阶段4数据清洗实战●●●●●

lookahead审计:给因子计算链做"时间安检"

我的掌握程度:
q-357精讲

先掌握这个答案

lookahead审计三件武器:①静态审计(人工过链):对链上每个中间变量问一句「这个值在t日收盘后可知吗?」——重点检查shift方向(防前视要shift(1)后用于t+1)、merge的右表时间戳类型(公告日≠报告日)、rolling是否包含当日当期;②组合对照:任何「因子值→未来收益」的配对,两者时间轴必须错开(因子t、收益t+1起);③截断重跑(终极):只用截至T日的数据重算全链,T日前的因子值必须与全量计算完全一致——任何不一致即泄漏点。三选一不可,三者互补。

先读结论,再核对下方使用边界;数字例题为教学情景,涉及实际行情与规则时请核对原始来源。

从理解到使用

本阶段实战方法 · 一条能复现的数据流水线

把接口返回的数据变成可用于因子研究的面板时,先处理时点、主键与单位。

  1. 建立数据字典:字段、单位、时区、交易日历、数据源、抓取时间、原始价与复权因子。
  2. 用(date, code)查重,区分停牌、未上市、窗口不足和真实缺失;不要用向后填充把未来值带回过去。
  3. 保存原始快照与清洗日志,固定随机种子和环境版本;接口字段变化时先核对官方文档。

使用边界

  • 报告期不等于公告可用日,盘后公告通常不能用于当天收盘前决策。
  • API输出名为“动态市盈率”时不能直接改名TTM;浏览器练习不支持任意原生库或行情抓取接口。
背景 · 从一个困惑说起
一个因子函数往往不是一步算完的:原始价→滚动收益→排名→再滚动平滑→再排名。链条越长,某一步悄悄用错时间轴的概率越大——而且错误不报错,只让回测虚高。人眼review百行链路必然遗漏,安检必须自动化。
由此产生的问题
如何系统性地审计一条因子计算链的每个环节?「截断重跑检验」为什么是终极手段?
核心概念
lookahead审计三件武器:①静态审计(人工过链):对链上每个中间变量问一句「这个值在t日收盘后可知吗?」——重点检查shift方向(防前视要shift(1)后用于t+1)、merge的右表时间戳类型(公告日≠报告日)、rolling是否包含当日当期;②组合对照:任何「因子值→未来收益」的配对,两者时间轴必须错开(因子t、收益t+1起);③截断重跑(终极):只用截至T日的数据重算全链,T日前的因子值必须与全量计算完全一致——任何不一致即泄漏点。三选一不可,三者互补。
为什么需要它
①链式污染:中间变量的前视会通过后续计算传播放大——单点检查抓不全,截断检验抓全部;②可自动化:截断检验可写成单元测试,每次改因子代码自动跑——把「防自欺」变成CI的一环(职业分水岭);③协作纪律:团队code review的第一检查项就是时间安检清单。
实际应用场景
落地模板(本题code):factor_chain(df)封装整条链;test_no_lookahead()做截断对照,assert最大差异<1e-12;接入pytest后每次提交自动验证。
与之前知识的联系
q-352给了横竖操作的分界,本题把它们放进安检门;q-393给用户级检查法(删尾部重跑),q-502(阶段6)将其升级为回测框架级测试。三题构成「前视防御三部曲」。
⚠ 常见误解
  • 我用的都是t日及以前的数据所以没问题:中间变量的对齐错位(索引拼接时错一天)是静默的——自以为≠审计过
  • 截断检验成本高:单因子几秒钟;相比泄漏上线后亏的真金,这是全世界最便宜的保险
  • 测试一次通过永远有效:改一行代码就可能引入新泄漏——把它做成随代码演进自动重跑的单元测试

🤖 AI导师

导师会先检查你的前置知识(shift纪律、横截面与时序操作、merge_asof),再用案例、公式和代码帮助理解。此功能需要先启用服务。