年化20%量化笔记 · 第33篇
WHY 为什么"看起来有关系"经常害你亏钱
一个真实的教训
2022年,我在一个量化圈的技术交流群里,看到一个哥们分享了他的"重大发现":
"回测了10年数据,发现一个超强信号——当印度大豆期货的日涨幅超过2%时,第二天A股螺纹钢下跌的概率高达71%!p值小于0.01,样本量2000+,统计显著!"
群里一堆人觉得这是alpha,准备拿去写策略。
我当时问了三个问题:
1. 印度大豆和螺纹钢之间有什么经济学传导链条?
2. 71%的"下跌概率",实际上下跌了多少?是跌0.01%也算跌?
3. 如果你测了100个商品对的这种"领先-滞后关系",有多少个碰巧能达到这个统计水平?
三个问题一出来,那个哥们的兴奋劲立马就凉了。
答案很简单:这两个品种之间没有任何因果机制,71%的概率很可能只是数据中恰好存在的相关性,放到样本外大概率归零。
相关性和因果性——被混为一谈的两个东西
这是统计学里最基础也最被低估的概念之一。
相关性(Correlation):两个变量同时变化,A涨的时候B也涨(或B跌)。数学上用相关系数衡量,范围-1到+1。
因果性(Causation):A的变化直接导致了B的变化。A是因,B是果,有明确的传导机制。
核心原则:相关性≠因果性。两个变量相关,不代表一个导致了另一个。它们可能都受第三个变量影响,也可能纯粹是巧合。
听起来简单,但在量化交易的实际操作中,这个坑无处不在——因为你不是在"看两个变量",你是在几百个因子、几千组数据点里找规律。找到的任何"相关性",都有极高的概率是假象。
交易中最常见的"相关≠因果"陷阱
我整理了这些年见过最典型的几类:
| 陷阱类型 | 典型表现 | 真相 | | --- | --- | --- | | 伪相关 | "当某国央行增持黄金时,美股下跌" | 两者都受美元指数和避险情绪驱动,互不为因果 | | 反向因果 | "交易量大的股票收益更高" | 不是大交易量导致高收益,而是高收益预期吸引了大交易量 | | 共同原因 | "冰淇淋销量和溺水人数正相关" | 共同原因是夏天——不是冰淇淋导致溺水 | | 时间巧合 | "每次超级碗在某个电视台转播,股市就涨" | 纯属巧合(Super Bowl Indicator,经典伪相关案例) | | 幸存者偏差导致的相关 | "回测中动量因子在过去10年有效" | 你只看到了过去10年的数据,动量因子在2000-2009年连续亏损 |
每一类陷阱的共同特征:统计上"看起来都对",但缺乏因果机制,放到样本外就失效。
为什么这个问题特别危险
因为人类大脑天生就是"因果机器"——看到一个模式,就自动编一个故事来解释它。
"美联储加息导致新兴市场资金外流"——这个有因果链条,是合理的。
"当X指标金叉时,Y品种上涨"——这个呢?你能说出因果机制吗?
如果你说不清楚"为什么",只有统计数字在撑着,那这个信号大概率是噪声。
量化交易最贵的学费,不是交在错误的策略上,而是交在"统计上对但因果上错"的策略上。 因为前者你亏几次就发现了,后者你可能跑了一年模拟盘才发现——那时候真金白银已经进去了。
HOW 如何区分真因果和伪相关——一套可操作的判断框架
方法一:因果链条检验——"能不能说出故事"
这是最朴素也最有效的第一步筛选:
对于你发现的每一个"信号→结果"关系,用一句话写清楚因果传导链条。如果写不出来,或者链条超过3个环节,大概率是伪相关。
举个例子:
有效因果链:
• 信号:美联储降息 → 结果:新兴市场货币升值 → 传导:利率差缩小→资金回流新兴市场→本币需求增加→汇率升值。3个环节,每一环都有经济学支撑。✅
伪相关:
• 信号:某商品期货的库存上升 → 结果:另一国股指上涨。传导:???写不出来。❌
实操建议:
在你的因子库或信号列表里,对每个信号做一个"因果链写作测试"——强制自己用不超过100个字解释"为什么这个信号能预测那个结果"。写不出来的,直接降优先级或淘汰。
方法二:反事实验证——"如果A不发生,B还会发生吗?"
这是因果推断的核心思维实验:
假设信号没有发生,结果还会按同样的规律出现吗?如果答案是"会",那你的信号就不是因果因素,只是一个伴随现象。
案例:你发现"当北向资金单日净流入超过100亿时,第二天沪深300上涨的概率是65%"。
反事实验证:
• 如果某一天北向资金净流入恰好是0,沪深300第二天上涨的概率是多少?
• 如果北向资金净流出50亿,沪深300第二天上涨的概率又是多少?
如果这些情况下上涨概率也是60-65%,那北向资金流入根本不是原因——它只是和某个真正的原因(比如全球risk-on情绪)同时出现了而已。
实操方式:
// python
import pandas as pd
import numpy as np
# 假设你有信号和结果的数据
# signal: 1=信号触发, 0=信号未触发
# outcome: 1=结果发生, 0=结果未发生
# 条件概率P(结果|信号)
p_outcome_given_signal = df[df['signal']==1]['outcome'].mean()
# 反事实概率P(结果|无信号)
p_outcome_no_signal = df[df['signal']==0]['outcome'].mean()
# 因果效应 = 条件概率 - 反事实概率
causal_effect = p_outcome_given_signal - p_outcome_no_signal
print(f"信号触发时结果概率: {p_outcome_given_signal:.2%}")
print(f"信号未触发时结果概率: {p_outcome_no_signal:.2%}")
print(f"因果效应: {causal_effect:.2%}")
# 如果因果效应接近0,信号大概率是伪相关
核心判断标准:如果因果效应(条件概率差值)小于5个百分点,这个信号的"预测力"可能只是统计噪声。
方法三:格兰杰因果检验——统计层面的因果方向判断
格兰杰因果检验(Granger Causality Test)是计量经济学中判断因果方向的经典方法:
如果X的过去值能显著提高对Y的预测精度(在控制了Y自身过去值之后),则称"X格兰杰导致Y"。
注意:格兰杰因果≠真正的因果。它只说明X的时间序列包含对Y有用的信息,但不能排除第三方变量的干扰。不过它比简单的相关性分析强——至少能判断时间先后方向。
// python
from statsmodels.tsa.stattools import grangercausalitytests
# 检验X是否格兰杰导致Y
# data的两列:第一列是Y,第二列是X
data = df[['outcome', 'signal']].dropna()
# 最多检验5阶滞后
results = grangercausalitytests(data, maxlag=5, verbose=True)
# 查看各阶滞后的F检验p值
for lag in range(1, 6):
f_stat = results[lag][0]['ssr_ftest'][0]
p_value = results[lag][0]['ssr_ftest'][1]
print(f"滞后{lag}期: F={f_stat:.4f}, p={p_value:.4f}")
if p_value < 0.05:
print(f" → 滞后{lag}期时,X格兰杰导致Y")
注意事项:
• 格兰杰因果只说明"时间上有预测关系",不保证真实因果
• 两个变量可能都受第三个变量驱动(混淆变量),格兰杰检验无法处理
• 必须配合方法一(因果链条检验)一起使用
方法四:工具变量法(IV)——用"外部冲击"分离因果
当你怀疑信号X和结果Y之间有伪相关问题(可能存在混淆变量),但又不想放弃这个信号时,可以试试工具变量法。
核心思路:
1. 找到一个"工具变量"Z,满足两个条件:
◦ Z影响X(相关性条件)
◦ Z只能通过X影响Y,不能通过其他路径影响Y(排他性条件)
2. 用Z对X的"外生冲击"部分来估计X对Y的因果效应
量化交易中的例子:
假设你发现"分析师覆盖数量多的股票,未来收益更高"。但这个相关性可能是假的——大公司被覆盖多,同时大公司基本面更好。
工具变量可以是"分析师所在券商的研报产能波动"——这个变量影响某只股票是否被覆盖(分析师忙不过来时少覆盖),但不直接影响股票的后续收益(排他性近似成立)。
// python
import statsmodels.api as sm
from statsmodels.sandbox.regression.gmm import IV2SLS
# 第一阶段:用工具变量Z预测内生变量X
# 第二阶段:用X的预测值预测Y
from linearmodels.iv import IV2SLS
# 模型:Y = β0 + β1*X + ε
# 工具变量:Z
mod = IV2SLS(df['Y'], sm.add_constant(df['X']),
instruments=sm.add_constant(df['Z']))
res = mod.fit()
print(res.summary)
实操门槛较高,适合有一定计量经济学基础的交易者。初学者先用前三个方法即可。
我的实操框架:四步因果检验流程
实际工作中,我评估一个新信号时会按以下顺序检验:
第一步:因果链写作测试(30秒)
├── 能否用100字以内说清楚"为什么这个信号能预测结果"?
├── 因果链条是否超过3个环节?
└── 通过 → 进入第二步 | 不通过 → 降级为"待验证"
第二步:反事实概率对比(5分钟)
├── 计算P(结果|信号触发)和P(结果|信号未触发)
├── 因果效应(差值)是否 > 5个百分点?
└── 通过 → 进入第三步 | 不通过 → 标记为"弱信号"
第三步:时间方向检验(10分钟)
├── 做格兰杰因果检验,确认时间先后方向
├── p值是否显著?方向是否符合预期?
└── 通过 → 进入第四步 | 不通过 → 标记为"方向存疑"
第四步:样本外 + 跨市场验证
├── 在样本外数据上,信号的预测力是否依然存在?
├── 在另一个市场/品种/时间窗口上,是否可复现?
└── 通过 → 可进入策略开发 | 不通过 → 大概率伪相关,放弃
核心原则:如果一个信号过不了前三步,就不值得花时间做第四步。大部分伪相关在前两步就会被淘汰。
WHAT 你带走的三个认知和一份筛选工具
1. "统计显著"只是入场券,因果可解释才是通行证
p<0.05不代表策略有效,相关系数0.7不代表有因果关系。在几百个因子、几千组数据点里,你一定能找到大量"统计上显著"的伪相关。真正值得下注的信号,必须同时满足"统计显著"和"因果可解释"两个条件。
2. 人类大脑是因果偏见的放大器
你会不自觉地为任何相关性编一个因果故事。"可能是因为……""也许是因为……"——这些不是因果推理,这是合理化偏见。必须用结构化的检验流程来对抗这种本能。
3. 伪相关的代价是真实的
一个伪相关信号上线实盘,不会立刻暴露——它可能在前几个月表现正常(因为市场偶然配合),然后在你加大仓位后突然失效。到那时候,亏损已经造成了。在策略开发阶段多花1小时做因果检验,比在实盘阶段亏10万学费要划算得多。
- ☐ 立即:从你当前的信号/因子库中,随机抽取3个信号,做"因果链写作测试"——用100字以内写清楚每个信号的因果传导机制。写不出来的,标记为"待验证"
- ☐ 本周:对标记为"待验证"的信号,计算条件概率P(结果|信号)和反事实概率P(结果|无信号),看因果效应是否>5个百分点。低于5%的信号,降优先级
- ☐ 本月:在因子筛选流程中嵌入"四步因果检验"——每个新信号必须通过因果链测试+反事实验证+格兰杰检验+样本外验证,才能进入策略开发环节
- ☐ 长期习惯:为每个上线的信号维护一份"因果档案"——记录因果链条、检验结果、可能的混淆变量,定期复盘信号的因果逻辑是否依然成立
一句话总结
市场里最贵的三个字不是"我亏了",而是"我以为"。相关性告诉你两件事同时发生,因果性告诉你为什么。没有"为什么"的信号,只是你还没发现的巧合。
年化20%量化笔记 · 第33篇 · 维克
下一篇:线性回归入门:用一条线预测未来