开通会员
首页›量化投研›正文

你的量化回测可能偷偷看到了未来:QuantConnect 刚修复的 Look-ahead Bias 是什么?

你的量化回测可能偷偷看到了未来

宽
宽宽
9月19日3 阅读
你的回测可能偷偷看到了未来

你的量化回测可能偷偷看到了未来:QuantConnect 刚修复的 Look-ahead Bias 是什么?


一个量化策略,回测年化 30%,最大回撤只有 8%,Sharpe 超过 2。

看起来很漂亮。

但有一种错误,可以把一个原本普通、甚至亏钱的策略,直接变成“神策略”。

它叫前视偏差,英文是 Look-ahead Bias。

意思很简单:你的回测程序在做过去某一天的投资决策时,用到了当时还不可能知道的信息。

麻烦在于,这种问题不一定是你自己写出来的。

2026 年 9 月,QuantConnect 的开源量化引擎 LEAN 就修复了一个和前视偏差有关的问题,涉及 chained fundamental universe selection,也就是一层股票池筛选之后,再接一层基本面筛选。

修复说明提到,在某些情况下,LEAN 构造 Fundamental 数据时使用了当天的数据,导致当天的收盘信息提前进入了选股过程。

也就是说,回测程序知道了它本来不应该知道的东西。


前视偏差到底是什么?

先看一个简单的例子。

假设今天是 1 月 10 日早上。

你的策略规定,每天开盘前,从全市场挑出昨天表现最好的 20 只股票。

这个逻辑没问题。

因为 1 月 10 日早上,你已经知道 1 月 9 日完整的行情。

但如果程序在 1 月 10 日早上选股时,用到了 1 月 10 日当天的收盘价,问题就来了。

现实世界里,你不可能在早上 9 点知道下午收盘时的价格。

回测程序却知道。

这相当于拿着答案做题。

这就是前视偏差。


数据流示意图


QuantConnect 这次修了什么?


问题出现在 LEAN 的股票池筛选流程里。

QuantConnect 可以先建立一个 Universe,也就是候选股票池,然后再根据基本面数据继续筛选。

比如先选出一批股票,再根据市值、财务指标、成交量或者价格等条件进行第二轮过滤。

这次问题就发生在这种 chained universe selection 里。

LEAN 的修复说明提到,原来的代码在构造 Fundamental 数据时,使用了 selection time 本身,因此可能把当天的数据提前交给策略。后来修改为和其他 Fundamental API 一致的 Fundamental.ForDate 逻辑。

举个例子。

假设策略正在 4 月 2 日开盘前选股。

修复前,在特定情况下,程序可能已经拿到了 4 月 2 日收盘后的数据。

但现实里,4 月 2 日还没交易完。

修复后,4 月 2 日做筛选时,只能使用当时已经真正可获得的信息,比如前一个交易日的数据。

QuantConnect 还增加了回归测试,用来检查 chained universe 拿到的 Fundamental 数据是否对应上一交易日,并和算法当时已经收到的日线数据保持一致。

这里有一句话很重要:

数据有没有存在,不重要;关键是那个时间点的你能不能知道它。


为什么这种错误很危险?

因为程序通常不会报错。

它会正常运行。

回测曲线甚至可能好得出奇。

普通 Bug 往往很容易发现,程序崩了、数据为空、出现异常,你自然会去查。

前视偏差恰好相反。

它常常表现为胜率高得离谱,回撤低得离谱,参数怎么调都赚钱。

结果越好,人越容易相信。


财报数据是最典型的例子

假设一家公司的第一季度在 3 月 31 日结束。

后来公司公布了一份财报,营收增长 40%。

你设计了一个策略:

买入营收同比增长超过 30% 的公司。

如果数据库把这条数据简单记在 3 月 31 日,那么回测程序可能会认为,3 月 31 日这一天市场已经知道这家公司营收增长了 40%。

于是程序当天就买了进去。

但现实中,公司可能直到 4 月 28 日才发布财报。

程序等于提前快一个月知道了答案。

所以量化研究不能只问:

这条数据属于哪一天?

还要问:

市场从哪一天开始真正知道这条数据?

这两个日期经常不是同一天。


look ahead bias时间线示意图


前视偏差不只出现在价格数据里

很多人一听 Look-ahead Bias,会理解成“不小心用了明天的价格”。

实际上,常见的坑远不止这个。

财务数据

财报对应的会计期间结束时间,不等于财报公布时间。

指数成分股

如果你下载今天的标普 500 成分股,然后拿这份名单回测过去 20 年,相当于你提前知道了哪些公司最后还留在指数里。

已经退市、破产或者被剔除的公司,可能根本没进入你的历史样本。

这还会同时带来另一个问题:Survivorship Bias,也就是幸存者偏差。

股票池筛选

如果你用当天收盘后的成交量、涨跌幅、市值或者技术指标,去模拟当天开盘买入,也是在使用未来数据。

机器学习

机器学习里的数据泄漏尤其隐蔽。

比如你有 2010—2025 年的数据,先拿全部数据算平均值和标准差,再进行标准化。

之后才把 2010—2020 年设为训练集,2021—2025 年设为测试集。

表面上看,你做了样本外测试。

但在标准化那一步,2010 年的数据已经间接用到了 2025 年的信息。

这就是 Data Leakage。

说到底,也是同一类问题:未来的信息跑到了过去。


这次修复为什么值得说?

不是因为 QuantConnect 出了一个 Bug。

大型量化框架不断修 Bug,本来就是正常的。

但这个案例提醒了一件事:

用了成熟框架,不代表你的回测天然就是干净的。

LEAN 是成熟的开源算法交易引擎,支持研究、回测和实盘交易,也有完整的 Universe Selection、Fundamental Data 等机制。

这次的问题却出现在数据时间、Universe、Fundamental Filter 和 Selection Time 几个环节连起来之后。

单看某一块代码,可能都没问题。

一旦时间关系错了一天,回测结果就可能被污染。

这也是为什么专业量化研究里,“时间”往往比公式本身更重要。


正确回测Vs错误回测



怎么检查自己的策略有没有偷看未来?

看到一条很漂亮的回测曲线时,可以先问自己一句:

我今天做出的这个交易决定,用到的信息在今天真的已经公开了吗?

然后再往下查:

  • 财报用的是财报期末日期,还是实际发布日期?
  • 当天收盘数据有没有被拿去模拟当天开盘交易?
  • 股票池是不是用了今天才知道的指数成分股?
  • 历史退市股票有没有保留下来?
  • 机器学习的数据标准化、特征选择有没有提前接触测试集?
  • 回测平台里的时间戳,到底代表数据发生时间,还是数据真正可用的时间?

这些问题如果说不清楚,回测结果再漂亮,也得先打个问号。

最后说一句。

量化回测里,最容易被忽略的问题往往不是:

这个数据是真的吗?

而是:

在那个历史时刻,我真的知道这个数据吗?

价格可以是真的。

财报可以是真的。

指数成分股也可以是真的。

但只要把它们放到了错误的时间点,真实数据一样能制造出假的回测结果。

所以下次再看到一个年化 50%、Sharpe 3 的策略,先别急着研究它怎么赚钱。

先问一句:

它有没有偷偷看过未来?

资料来源:https://github.com/QuantConnect/Lean

# Len框架
//参与评论
?
还没有评论,来说第一句