跳到正文
阅读设置

阅读设置

导出或导入阅读记录
保留你的阅读记录

已读、收藏、阅读位置和阅读设置保存在当前浏览器地址下。换一个地址不会自动带过去。

迁移时先在原地址导出,再到新地址选择备份文件。操作只在浏览器本地完成,不上传服务器,也不会删除原地址的记录。

导入前会检查文件并请你确认。已读和收藏合并;遇到冲突时保留当前地址已有的位置、最近阅读和设置。

G41 · 系统学习

未来函数与数据泄漏:回测为何会提前知道答案

沿一条可得时间线追查成交、财报、成员和预处理错误,用隔离修复与故意扰动检查回测是否偷看未来。

尚未标记已读案例与模板 ↓

每一行公式都算对了,回测却总能在好消息前买入。沿着输入的公开时间往回查,才发现有些数值在决策那天还不存在。怎样查出这种“算术正确、信息越界”的结果?

未来函数不一定是代码里写了“读取明天”。它也可能藏在今日成员名单、后来修订的财报、全样本计算的平均值,甚至研究者反复打开测试成绩的动作里。我们先找到第一处越过时间线的连接,再逐项修复。

这次要解决的问题

  • 用可得时间和处理顺序定位成交、数据与研究过程的泄漏。
  • 分别纠正三类可复查错误,说明数字改变与尚未证明的部分。
  • 设计故意扰动与时间截断检查,保存一张泄漏审查记录。

所有输入,都得回答同一个时间问题

把G33的时间表延伸到一次完整决策:业务或交易发生,资料公开,自己取得,完成核验与预处理,形成信号,最后才尝试执行。每条输入都应能走到这条链上,而不是只带一个“日期”标签。

数据泄漏是预测或决策时本来不可用的信息,进入了模型构造或评价。scikit-learn官方文档将测试资料用于模型选择、预处理学习等列为常见来源。[1] 对投资研究,还要追问历史记录的版本和可执行时点。

以下三个查错任务为C4错误实验室的隔离练习。第一个复用C4-S1已定五日价格和账本规则,另列错误执行版本作比较;其余财报和数值材料为独立合成输入,不改变C2或C4-S1规格,不冒充真实公司数据。

要追查的记录错误连接修复首先要找到什么
收盘信号与成交看完整收盘后仍按同一收盘成交信号完成与实际最早执行时点
财报与成员把期间、今日版本或未来身份当作过去已知发布、取得、修订及成员有效时间
数据预处理与模型用后段数据学习过去的处理规则每次训练时点的可用范围与固定转换

这张表不是三种检查通过就能保证无泄漏。它帮助你把模糊怀疑缩成一个可以找到输入、输出和时间证据的问题。

错误一:收盘后才知道,却按那个收盘成交

C4-S1从1000美元现金开始,无持仓;收盘严格大于11才以20股为目标,否则目标0。下一列示交易日开盘执行非零调整,每个成交订单费用1美元,现金不足整笔拒绝,主例没有缺价或公司行动。

G39已给定D2收盘12、D3开盘13且收盘11、D4开盘10。正确路径是D2收盘产生买单,D3开盘买20股,支出260加1,剩739;D3收盘产生卖单,D4开盘收200再付1,现金938,后续无新成交。

现在只引入一项错误:收盘完成信号后,立即按同一个收盘价执行。于是D2按12买20股,剩759;D3按11卖出,收220付1,最后978。两版初始资金与每次费用相同,差40美元,累计收益从正确的负6.2%变成错误版负2.2%。

错误版没有神奇地减少风险,只是换了执行条件。在这份规格下,完整收盘价要等收盘后才可知,不能反过来保证自己已经参加了那次收盘交易。修复后成绩下降,是时间顺序恢复的结果,不是应该把错误改回去的理由。

也不能推广为任何收盘成交都必然错误。若另一策略依据此前已知信息,符合相应订单与交易机制,属于需要单独核验的规则;这里错误的是把本例完整收盘信号与同收盘保证成交相连。

错误二:财报的日期,写成了数据可得日期

再看独立合成资料,以下时刻统一采用同一明确时区。某季度截至3月31日,收入100;5月13日08:00首次公开,08:05研究程序取得,08:10完成核验。6月10日另有更正,把该季度收入改为90。

如果回测把100放在3月31日的决策输入里,就提前使用了尚未公开的季度结果。若今天下载的文件只留下90,又将90回填5月15日的旧判断,则是把后来修订也送回了过去。

修复不能只做“全部滞后一天”。应按实际公开、取得与处理时间连接:3月底这项结果不可用;在5月13日08:10以后,才满足本例自己的处理条件;5月15日版本仍是当时可得的100,不是6月才知道的90。何时成交,还要再接对应市场日历与策略规则。

EDGAR说明带“/A”的表单为修订文件,但修订的内容和可得时间仍需单独检查。[2] 并非任何今日数据库都能返回所有旧版本;若历史版本无法取得,就记录限制,不用当前正确数值假扮当时已知值。

同样的连接错误会出现在成员数据。若一只证券在7月宣布、8月才加入指定指数,不能因今天它是成员,就允许1月的原指数成员策略选择它。修复应回到当时的资格、公布与生效记录,保持与G34的股票池定义一致。

这一步可能改变信号和持仓,也可能在某段样本里没有改变收益。没有变化不证明数据连接正确,有变化也不证明新策略有价值;先检验时间关系,再评价经济结果。

错误三:模型没看收益,预处理却看了测试段

有人说:“我没有把未来收益放进输入,只是先把全部数据统一处理一下。”可处理参数本身也可能带回未来信息,尤其是用全样本均值、标准差、缺失填充值或筛选结果。

用一份独立合成特征表看得更清楚。训练时已经可得的两个数为2、4,后来的测试段为100、102。若只用训练段学习均值,得到3,数值4减均值后为1;若用四个数一起学,均值52,过去的4便变成负48。

假设模型判断“处理后严格为正”时触发条件,过去同一个4就从满足变成不满足。未来值没有直接出现在那一行,却通过平均值改变了它。这是计算过程泄漏,不是数据单位统一的无害步骤。

修复是先按研究时间划分资料,只从当时允许的训练资料学习处理参数,再固定这套参数转换相应后段输入。官方文档明确区分学习预处理与应用相同转换,也指出特征筛选等步骤同样可能泄漏。[1]

本题是演示均值居中,不是建议采用这种投资信号。原始特征的含义、样本选择和模型训练仍需自己的依据;把训练段单独处理正确,只是修好了一条连接。

填补缺失也可以沿同样方式检查。若M5的特征为空,工具拿M6才公布的值补回M5,即使用的只是“最近一项”,方向仍是从未来回到过去。沿用更早已知值则未必穿越时间,却还需说明它是否过时、规则是否允许。一个叫“填补”的按钮,可能对应这两种完全不同的研究条件。

标签的结果,可能还活在未来几天

如果要预测未来若干交易日收益,标签就是之后结果。建模时可以用已经结束的历史标签,但训练截止时尚未实现的标签,不能因为它写在较早那一行,就被算成已知。

例如,用D5作一条训练输入,其标签覆盖D5之后至D10的收益;模型却在D5收盘就训练完,并从D6开始测试。标签要到D10才完整知道,这次训练已经借用了后面的结果。仅按输入行日期把表切成两段,没有修好它。

需要检查每条标签所覆盖的区间和最晚可得时间,排除跨越当前训练边界而尚未知的标签,或重新设计训练与测试安排。重叠结果也可能共享信息,影响独立证据的解释。

scikit-learn的TimeSeriesSplit提供按时间顺序划分与设置间隔的工具接口。[3] 但一个固定的间隔数不会自动理解财报延迟、标签期限、交易日历或多资产时间。是否足够,要根据本题真实数据链核查,而不是只看到函数名就宣布无泄漏。

测试结果,也能从人的眼睛回到模型

假设原来答应只用开发段选窗口,最后用测试段评价。研究者跑完测试,看到效果不好,改窗口再试;循环多次,最终只交最好一版。即使程序每次没有直接读取未来标签,测试表现也已经参与选择。

修复应如实记录测试段已被使用、全部尝试和改变理由,重新安排评价,不把它继续称为完全未接触的检验。某段历史被作者反复分析过,也不能靠重新命名“留出”而变回未知未来。

这里先定位泄漏路径,多次尝试和结果挑选将在G42展开。一次规则冻结后的真正前瞻记录,与作者知道后续的历史教学留出,需要分开报告。

故意动一动未来,看过去是否跟着变

可以把这三类错误变成具体检查。先保存截止某决策日的原始输入、处理参数和输出,再把之后尚不可得的资料临时移走或改动,检查此前输出是否改变。改变的应是测试副本,不覆盖原始材料。

在合成财报例中,把6月10日修订90改为另一个数,不应改变按当时版本重建的5月15日输入100。若旧信号随之变化,就找到了一条需要追踪的未来连接。

在特征例中,把测试段100、102改成别的值,训练段均值仍应为3,过去4的处理结果仍为1。若它跟着变,先查是否把处理参数在全样本上重新学习,而不是把变化归为模型“更全面”。

交易检查则要核对每笔成交使用的输入何时完成。也可做逐步截断:只提供当时已知资料,是否还能复现相同信号与订单?最终权益会随之后的真实价格变动,这本身不是泄漏;检查对象是过去决策,而非要求未来收益永远不变。

扰动通过只能增加对所查路径的信心。没有被改动的字段、未覆盖的分支、错误时间戳或隐蔽选择,仍可能漏查。全局把所有字段机械移后一天,也可能既没解决慢披露,又错误移动本来即时可得的价格。

先查错,再说明修复改变了什么

解释题:错误版C4最后978,为什么不是比938更好的有效策略证据?应用题:某工具说“财报已经统一推迟一个交易日,所以没有前视”,你会先查哪两项时间?先写答案再核对。

第一题中,978来自违反原规格的同收盘成交。它可以作为独立错误对照,不能冒充原规则的合法结果。第二题应核财报首次公开与实际取得、处理完成;相对报告期末只推后一天,仍可能早了数周。

换一个预处理输入

另一份独立合成记录,训练段为10、14,后段测试为30、34。助手先用四项总均值22处理,得到训练中的14为负8,然后声称训练与测试已经按行分开。请写出仅用训练段的正确均值、14的转换结果,并提出一次能复查的扰动检查。

训练均值是12,14应转成2。先分段再只从训练段学习参数,不能用表格已经分开掩盖前面全样本处理。将后段30、34改为其他值,训练均值12与过去输出2应保持不变;若改变,继续沿参数来源追查。

最后再说明哪些未验证:本题没有回测真实成员、交易与收益,也没有证明这种特征有预测价值。修复输入时间,与证明投资能力是不同任务。

保存你的泄漏审查记录

挑一条信号,逐项列出价格、财报、成员、公司行动、预处理参数和标签各自的观察范围、公开与取得时间、版本、处理完成时间、允许使用位置。再将订单与成交接上去,标明证据或缺口。

至少保留三项可复查错误、修复前后输入与输出、变更原因及影响范围。先一次只改一个错误,再做组合检查;费用、样本和规则也若同时变化,要另列说明,不能把全部收益差归给一次修复。

自检时问:另一位读者能否重现第一处时间越界?故意改变未来资料时,过去对应输出是否稳定?无法核实的历史版本或成员资料,要限制结论;不要把AI给出的“检查通过”当作独立证据。

小结:查的不是日期标签,而是信息怎么走

先沿同一条可得时间线,把信号、数据版本、处理参数和标签连到决策,再连到执行。过去的输入行不保证里面只有过去信息,当前正确的数据也不等于当时能知道的版本。

修复后数字变差可以是查错成功,数字不变却不保证无错。用隔离修复、时间截断和未来扰动留下可复核记录,再诚实说明未查范围,才有条件讨论这段研究还剩多少可信证据。

参考资料

  1. scikit-learn:Common Pitfalls—Data Leakage。训练/测试分离、预处理与特征筛选的学习范围;文中数值为独立合成输入。
  2. Investor.gov:Using EDGAR to Research Investments。公开申报及修订标识;不保证任何数据源提供全部历史版本。
  3. scikit-learn:TimeSeriesSplit。时间顺序与间隔功能,只作为方法边界说明,不要求读者写程序,不将默认参数当完整金融防泄漏方案。

资料核查日期2026-10-29。本文由AI辅助编写与检查,C4-S1正确/错误路径及补充例子均为教学合成资料,未宣称真实研究已经排除所有泄漏。

本篇配套材料

C4 · 6 份材料
浏览全部案例与模板 →
来源、版本与审查说明

最后更新:2026-10-29

SHA256 2548fed0d412eaf1bc80aeed684f7c5388ecb8a460138e93dcab4a0c5cc3afa2

案例:C4

当前网页接入相应书稿;AI审查、双语复核及未完成项按内容发布检查登记。人工金融审校与目标读者试读未进行。

报告本篇问题或勘误
全书目录

记录只保存在当前浏览器。

本篇目录
搜索全书