单因子检验:IC 与 IR
直觉
造出一个因子后,怎么知道它「真的」能预测未来收益?信息系数(IC)就是答案:每个时段,算「因子打分」和「下期收益」的横截面相关。IC 持续为正、且稳定,才说明因子有效。信息比率(IR)把「平均 IC」和「IC 的波动」放一起,是衡量因子稳定有效的核心指标。
定义
每个时段 ,对全部股票计算因子 与下期收益 的(秩)相关:
汇总为:
「人话」解释:IC 和 IR 各看什么?
- IC:单期能预测多准。IC=0.02~0.05 在真实市场里就已经算不错的因子了(不是 0.5 那种);
- IR(IC 的信息比率):预测力稳不稳。平均 IC 高但波动也大 → IR 低 → 不可靠;
- 业内常用**秩相关(Rank IC / Spearman)**而非 Pearson,因为它对极端值不敏感、更稳健;
- IR 经验门槛约 0.5 算可用,>1 算优秀。
可运行案例:质量因子与动量因子的 IC/IR
按月计算 Rank IC 序列:质量(来自元数据,恒定)与动量(6 月,滞后一期防前视),看哪个更稳定有效。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
prices = pd.read_csv('/data/sp500_universe_daily.csv', parse_dates=['date']).set_index('date')
meta = pd.read_csv('/data/sp500_metadata.csv').set_index('ticker').loc[prices.columns]
quality = meta['quality']
monthly = prices.resample('ME').last()
mret = monthly.pct_change() # 下期(月)收益
# 动量: 过去6月收益, shift(1) 防前视(只用 t-1 及之前的信息预测 t)
mom = np.log(monthly / monthly.shift(6)).shift(1)
def rank_ic(ret_row, fac):
return ret_row.rank().corr(fac.rank()) # 横截面秩相关
ic_q = mret.apply(lambda r: rank_ic(r, quality), axis=1).dropna()
ic_m = mret.apply(lambda r: rank_ic(r, mom.loc[r.name]) if r.name in mom.index else np.nan, axis=1).dropna()
def report(ic, name):
print(f"{name}: 平均IC={ic.mean():+.4f} IR={ic.mean()/ic.std(ddof=0):+.3f} "
f"IC正率={ (ic>0).mean():.0%} 样本={len(ic)}")
report(ic_q, "质量因子")
report(ic_m, "动量因子")
pd.DataFrame({'质量': ic_q, '动量': ic_m}).cumsum().plot(figsize=(8, 3.6))
plt.axhline(0, color='gray', lw=0.8)
plt.title("累计 Rank IC(斜率=平均预测力,越陡越直=越稳)")
plt.ylabel("累计 IC"); plt.tight_layout(); plt.show()
小结
- IC = 单期「因子分 vs 下期收益」的横截面相关,常取秩相关;
- IR = 平均 IC / IC 标准差,衡量预测力的稳定性;
- 评估因子要看 IC 的均值、IR、正率三者,而非单期数值。
下一节把因子变成可交易的分层组合,直观看「高分组是不是真比低分组赚」。
小测验
1. 因子 IC 衡量的是?
2. IR(信息比)= 平均IC / ?,它衡量?
3. 为什么常用 rank IC(秩相关)?