3. 前视偏差:不小心用了未来数据,回测结果虚高
做因子投资的人,十有八九都栽过这个坑。
前视偏差,说白了就是你在回测时,不小心用了「未来才知道」的数据。结果呢?回测曲线漂亮得像假的一样,一上实盘就崩。我见过太多人拿着这种回测结果来找我,一脸兴奋地说「我发现了圣杯」。嗯,每次我都要泼一盆冷水。
3.1 什么是前视偏差?
简单说,就是你的策略在回测时「偷看」了未来的信息。
举个例子。你想用「过去20天的收益率」来预测明天涨跌。这没问题。但如果你不小心用了「未来20天的收益率」——那问题就大了。回测时看起来百发百中,实盘时却一塌糊涂。
为什么会这样?因为未来数据在回测那一刻,本来就不该存在。
核心定义:前视偏差(Look-Ahead Bias)是指回测模型中使用了在决策时点尚未可知的信息,导致回测结果被系统性高估。
3.2 常见的三种前视偏差
我个人习惯把前视偏差分成三类。你对照看看,中过几枪?
| 类型 | 描述 | 典型例子 |
|---|---|---|
| 数据对齐偏差 | 使用了未来时间点的数据 | 用T+1的收盘价计算T日的因子 |
| 信息泄露偏差 | 使用了未来才公开的信息 | 用财报发布后的数据回测发布前的交易 |
| 幸存者偏差 | 只保留了存活至今的标的 | 回测时只选当前还在交易的股票 |
我在项目中遇到过最离谱的一次——有人用「当天收盘价」计算「开盘买入信号」。你想想看,收盘价在开盘之后才出来,这信号怎么可能在开盘时用?回测年化50%,实盘直接亏到怀疑人生。
3.3 一个典型的代码错误
来看一段我经常在面试题里放的代码。你找找看,问题出在哪?
import pandas as pd
import numpy as np
# 错误示例:前视偏差
def compute_factor_with_bias(df):
# 计算过去5日收益率
df['ret_5d'] = df['close'].pct_change(5)
# 问题在这里!shift(-1)用了未来数据
df['signal'] = np.where(df['ret_5d'].shift(-1) > 0, 1, -1)
# 计算收益
df['strategy_ret'] = df['signal'] * df['ret_5d']
return df['strategy_ret'].cumsum()
看出来了吗?shift(-1) 把未来的收益率搬到了今天。回测时信号和收益完美对齐,但实盘时你根本不知道明天的收益率是多少。
避坑指南:我曾经在做一个高频因子时,就因为少写了一个shift(1),导致回测夏普比从0.8飙到2.3。当时我还纳闷「这因子怎么这么强」……后来排查了三天才发现是shift方向搞反了。记住:回测时永远假设你只能用到「截止到当前时刻」的数据。
3.4 如何避免前视偏差?
说实话,完全避免前视偏差很难。但有几个方法可以大幅降低风险。
- 严格的时间戳对齐:确保因子计算时只用到T-1及之前的数据
- 使用shift操作:在pandas中,用
shift(1)把数据往后推一期 - 分步回测:先计算因子值,再生成信号,最后计算收益——每一步都检查时间戳
- 交叉验证:用不同时间段的数据反复验证,看结果是否稳定
我个人习惯的做法是:写一个「时间对齐检查函数」。每次回测前跑一遍,自动标记出那些「未来数据」的列。省心很多。
def check_look_ahead_bias(df, date_col='date', factor_cols=None):
"""
检查数据中是否存在前视偏差
"""
if factor_cols is None:
factor_cols = [c for c in df.columns if c != date_col]
for col in factor_cols:
# 检查是否有未来的数据点出现在当前时间之前
future_data = df[df[date_col] > df[col].notna().shift(-1)]
if len(future_data) > 0:
print(f"警告:{col} 可能存在前视偏差")
print("检查完成")
3.5 前视偏差的「隐形杀手」
有些前视偏差藏得很深。比如:
- 财报数据的时间戳:财报发布日期和财报覆盖期间是两回事。用Q1财报数据回测Q1的交易,这就是前视偏差
- 指数成分股调整:用调整后的成分股列表回测调整前的交易,也是坑
- 复权数据:后复权数据包含了未来的分红和拆股信息,用不好就会引入偏差
嗯,这里要注意。很多量化平台提供的「干净数据」其实已经帮你处理了一部分。但你不能完全依赖它。我建议你每次拿到新数据,先做一次「时间对齐测试」——用已知的事件去验证数据的时间戳是否合理。
3.6 一张图看懂前视偏差
下面这张图,是我自己总结的前视偏差检查流程。每次做因子回测前,我都会过一遍。
3.7 最后的忠告
前视偏差这东西,说难不难,说简单也不简单。它不像数学公式那样有标准解法,更多是靠经验和细心。
我做了这么多年因子投资,最大的体会就是:回测结果越漂亮,越要怀疑。年化50%、夏普3.0、最大回撤5%——这种曲线我见过太多次了,十有八九是前视偏差在作祟。
你想想看,如果真有这么完美的策略,为什么市场上没人用?
实用技巧:每次写完回测代码,先跑一个「随机信号」的对照实验。如果随机信号都能赚钱,那你的策略大概率有前视偏差。这招我用了很多年,屡试不爽。
好了,关于前视偏差就聊这么多。记住:回测是工具,不是真相。保持怀疑,保持谨慎,这才是量化投资的正确姿势。