比如策略逻辑是「今天跌幅超过 3% 就买入」。 如果你的回测里用今天的收盘价判断、又用今天的收盘价成交, 那就等于在收盘那一刻同时知道结果和执行交易——现实中做不到。 真实世界里你只能在收盘之后下单,成交价最早是次日开盘。
| 类型 | 典型表现 |
|---|---|
| 同日收盘决策 + 同日成交 | 信号和成交都用了当天收盘价 |
| 用了事后修正的数据 | 财务数据用最新披露值回填历史(应该是当时能看到的版本) |
| 成分股用当前名单 | 拿今天的指数成分股回测十年前(幸存者偏差的一种) |
| 全样本标准化 | 用整段数据的均值/标准差做归一化,包含未来信息 |
| 参数在样本内调到最优 | 本质是拟合历史噪声(见「过拟合」一篇) |
某策略回测年化 80%、最大回撤 3%,曲线几乎是直线向上。 这种形态基本可以直接判定有问题:真实策略不可能长期只有 3% 的回撤, 因为市场本身的波动就远大于此。过于完美的曲线,本身就是未来函数的指纹。
shift()、rolling() 的方向,确认没有把未来的窗口带进来;最后一条最容易被忽略:一份「2024 年 12 月 31 日」的财报, 可能要到次年 4 月才披露。按日期对齐而不按披露日对齐,就是典型的未来函数。
过拟合可以通过样本外检验暴露:样本内好、样本外崩,一眼就能发现。 未来函数不一样——它在任何时间段都在作弊,所以样本内样本外一样漂亮, 所有「换个区间再测一次」的办法都查不出来。 唯一的办法是按真实时间线重放:只允许策略看到当时已经发生的数据。
最快的办法是加延迟测试:把信号和成交都往后推 1–2 天,如果收益断崖式下跌,说明原结果高度依赖即时信息。其次是检查成交价是否符合该市场的交易制度(如 A 股 T+1)。
未来函数是「用了不该知道的信息」,属于逻辑错误,通常能通过检查代码发现;过拟合是「把噪声当规律」,数据本身没问题,但结论不可外推。两者常常同时出现,但排查手段不同。
在日频策略里影响非常大,因为收盘价往往是最有信息量的那个价格。把它改成次日开盘,很多「高收益」策略的收益会直接腰斩甚至转负。