回测即使用了正确公式,也可能在回答一个不可能的问题。当测试使用了模拟决策时点尚不可用的信息,就出现了前视偏差。有时错误很明显,例如不小心在K线结束前使用收盘价;有时则藏在发布时间、数据修订、数据集标签、参数调整,或研究者看过待评估时期后所作的选择中。
问题不一定是信息本身错误。信息可能准确,却使用了错误的时间概念。一项经济数据、企业标签或基准成分,只有在其内容和可用时间都已知后,才可以参与决策。因此,实际问题不只是“值是多少”,还包括“流程何时能够知道它”。
回测中的数据何时才可用?
一条记录可能包括事实所对应的日期,也包括该事实发布或可取得的日期。例如,某项统计描述周一结束的时期,却在周四才发布。若回测把它直接归到周一而不模拟发布时间,流程就可能被允许在真正知晓之前采取行动。
数据修订也会造成问题。宏观数据、指数、企业基本面和基准成分可能在之后被修正。如果历史重建悄悄用今天的最终版本替代当时可得版本,测试就可能看到当时参与者没有的信息。在可行时,同时保留发布日期和修订历史。
追踪每个输入到决策时点
对于每个影响分类或输出的字段,询问它代表什么、何时创建、何时可得,以及通过哪些变换进入模型。日频摘要可能掩盖事件发生时刻与确认时刻的差异。聚合流程可能按周期起始时间给K线标记时间,尽管收盘值要到周期结束后才知道。
QuantConnect 关于自定义数据的文档建议对可用时间建模,以避免引入未来信息。普遍的教训是把数据时间与决策时间分开,并测试整个数据流程不会过早暴露数值。即便来源不同,时点数据原则仍然适用。
- 事件时间:事件何时发生,或数据描述哪个时期?
- 发布时间:首次何时得知,有什么证据?
- 修订时间:之后是否更改,当时可用的是哪个版本?
- 数据变换:窗口、聚合或标签怎样改变可用时间?
- 决策时间:模拟流程在确切决策时点知道什么?
避免标签和特征构造中的泄漏
泄漏可能在设计标签时进入,而不只是数据时间戳错误。例如,某个标签由之后的价格路径决定。它作为待预测结果可能合理,但不应在同一时点作为输入。训练、验证和模拟推理中,都应一致执行预测变量与结果变量的边界。
重叠窗口也很重要。如果标签使用的未来观察与验证窗口重合,即使按时间划分样本,两个区间仍可能共享结果信息。按日期切分会有帮助,但不总是足够。标签窗口、隔离期和任何清除区间都应与研究的预测期限相匹配。
模型选择本身也可能偷看未来
即使数据流程本身具备因果顺序,研究过程仍可能泄漏未来。如果研究者在完整历史数据上尝试许多组合,选出表现最好的一组,再把同一时期当作测试,结果已经利用了来自该时期的信息。选择过程成了前视渠道。
信息泄漏不只经由列发生。研究者查看几百张图、看到结果后更改阈值,或只保留在评估期内“存活”的配置,同样是在获取未来信息。记录实验历史,区分开发材料与保留样本。QuantConnect 的参数优化文档也提醒研究者注意参数搜索中的过拟合与前视偏差。
保留样本不是永久解决方案,反复查看它就会把它变成开发过程的一部分。记录有多少研究决策依赖每个时期,说明方法何时被修改,并在条件允许时用尚未参与选择的时期评估冻结后的规格。
让决策与当时可用信息对齐
对每个模拟决策,建立一份当时已知输入的快照。简单的测试可以隐藏决策时间点之后的所有观察,并仅用剩余信息重新计算特征。如果加入未来数据后,过去分类发生变化,就需要调查是否存在泄漏,或可用时间约定缺乏记录。
执行顺序也很重要。使用当前K线收盘价的条件,要等收盘后才可用。如果测试模拟在同一收盘价执行,就必须说明流程如何同时获得信息并按这个约定成交。历史图表会显示最终结果,却不能单独证明该结果在假定时刻已经可用。
设计针对时间边界的测试
不要只依赖汇总收益来发现泄漏。应为延迟发布、已修订数据、缺失值、窗口预热、交易时段切换,以及训练/验证边界附近的决策编写单元测试。使用小型示例,在其中数据的正确可用时间明确,并确认流程在此前将其隐藏。
- 查找发布时间晚于其描述时期的数据,确认它在发布前不会出现。
- 比较当时可用版本与之后的修订版本。
- 确认标签不会意外重新成为特征。
- 检查训练与验证之间的窗口重叠。
- 隐藏之后的所有观察,重新计算过去的分类。
- 记录所报告结果被选出之前测试过多少个变体。
清楚说明边界和约定
透明的历史评估会记录决策时间戳、数据来源与可用约定、变换窗口、样本切分、模型选择历史、下单时点和未解决的限制。可以加入一个例子,展示数据值如何从来源一路进入决策。如果复核者无法知道当时哪些内容已知,过早呈现表现摘要就没有意义。
参考资料与延伸阅读
- 自定义数据关键概念:避免前视偏差QuantConnect 文档
- 优化参数:过拟合与前视偏差QuantConnect 文档



