4、因子IC分析:IC(信息系数)定义、Rank IC、ICIR(信息比率)、IC序列可视化
因子IC分析,说白了就是回答一个问题:你这个因子到底有没有预测能力?
我刚开始做量化那会儿,挖了一堆因子,回测曲线漂亮得不行。结果实盘一跑,直接翻车。后来才明白——回测漂亮不代表因子有效,你得看IC。IC才是因子的“照妖镜”。
这一节,咱们就把IC、Rank IC、ICIR这几个概念彻底讲透。嗯,我还会分享一些实战中踩过的坑。
4.1 IC(信息系数)定义
IC,全称Information Coefficient,信息系数。它衡量的是因子值对下一期收益率的预测能力。
具体来说,IC就是因子值与未来收益之间的相关系数。常用的计算方式是Pearson相关系数。
核心公式:
IC = corr(因子值, 下一期收益率)
取值范围:[-1, 1]
- IC > 0:因子值与收益正相关,因子值越大,预期收益越高
- IC < 0:因子值与收益负相关,因子值越小,预期收益越高
- IC = 0:因子没有预测能力
举个例子。假设我们有一个“市盈率倒数”因子,计算每个股票在t时刻的因子值,然后看t+1时刻的收益率。如果因子值高的股票,下一期收益率也高,那IC就是正的。
我个人习惯,每天计算一次截面IC。这样能得到一个IC时间序列,方便后续分析。
实战小贴士:
IC计算时,记得剔除ST股、新股和涨跌停的股票。我在项目中遇到过,不剔除这些异常值,IC会变得很不稳定,甚至出现虚假信号。
4.2 Rank IC(秩相关系数)
Pearson IC有个问题——它对异常值特别敏感。你想想看,如果某只股票突然有个极端收益,整个相关系数就被带偏了。
这时候,Rank IC就派上用场了。
Rank IC计算的是因子值排名与收益排名之间的相关系数,也就是Spearman秩相关系数。
Rank IC公式:
Rank IC = corr(rank(因子值), rank(下一期收益率))
说白了,就是把数值变成排名,再算相关性。
这样做的好处很明显:
- 对异常值不敏感——极端值不会扭曲排名
- 更稳健——适合处理非正态分布的数据
- 更符合投资逻辑——我们做多空组合时,本质上是在做排名
我记得有一次,一个因子Pearson IC只有0.02,看起来没啥用。但Rank IC却有0.08,而且很稳定。后来仔细排查,发现是几只小市值股票的极端收益把Pearson IC拉低了。改用Rank IC后,这个因子反而成了我们组合里的主力。
注意:
Rank IC虽然稳健,但会丢失一些信息。比如因子值之间的差距大小,排名是看不出来的。所以,我一般两个都看,互相印证。
4.3 ICIR(信息比率)
IC告诉你因子有没有预测能力,但没告诉你这个能力稳不稳定。
有的因子,今天IC是0.2,明天变成-0.1,后天又变成0.3。这种因子你敢用吗?反正我不敢。
ICIR(Information Coefficient Information Ratio)就是用来衡量IC稳定性的指标。
ICIR公式:
ICIR = mean(IC序列) / std(IC序列)
也就是IC的均值除以标准差。
ICIR越高,说明因子的预测能力越稳定。一般经验:
- ICIR > 0.5:因子不错,可以考虑使用
- ICIR > 1.0:因子很好,值得重仓
- ICIR > 2.0:极品因子,别声张(笑)
我曾经遇到过一个因子,IC均值0.06,看起来还行。但ICIR只有0.3,说明波动很大。后来实盘果然不行,赚三天亏两天,根本拿不住。所以我现在看因子,ICIR比IC本身更重要。
计算周期:
ICIR的计算周期一般取60天或120天。太短了噪声大,太长了反应迟钝。我个人习惯用60天滚动计算,既能捕捉变化,又不会太敏感。
4.4 IC序列可视化
光看数字不够直观。把IC序列画出来,很多问题一眼就能看出来。
下面这张图,展示了IC分析的核心流程:
可视化IC序列时,我一般会画三张图:
- IC折线图——看IC随时间的变化趋势
- IC累积图——累积IC可以看出因子的长期表现
- IC分布直方图——看IC的分布是否集中在0附近
下面是一个简单的Python代码示例,用来计算和可视化IC:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 假设 factor_df 是因子值,return_df 是下一期收益率
# 都是 DataFrame,index=日期,columns=股票代码
def calc_ic(factor_df, return_df):
"""计算每日截面IC和Rank IC"""
dates = factor_df.index
ic_list = []
rank_ic_list = []
for date in dates:
f = factor_df.loc[date].dropna()
r = return_df.loc[date].dropna()
common = f.index.intersection(r.index)
if len(common) < 30: # 少于30只股票,跳过
continue
f = f[common]
r = r[common]
# Pearson IC
ic = f.corr(r)
# Rank IC
rank_ic = f.rank().corr(r.rank())
ic_list.append(ic)
rank_ic_list.append(rank_ic)
ic_series = pd.Series(ic_list, index=dates[:len(ic_list)])
rank_ic_series = pd.Series(rank_ic_list, index=dates[:len(rank_ic_list)])
return ic_series, rank_ic_series
# 计算IC
ic, rank_ic = calc_ic(factor_df, return_df)
# 计算ICIR
icir = ic.mean() / ic.std()
rank_icir = rank_ic.mean() / rank_ic.std()
print(f"IC均值: {ic.mean():.4f}, ICIR: {icir:.4f}")
print(f"Rank IC均值: {rank_ic.mean():.4f}, Rank ICIR: {rank_icir:.4f}")
# 可视化
fig, axes = plt.subplots(3, 1, figsize=(12, 10))
# 折线图
axes[0].plot(ic.index, ic.values, label='IC', alpha=0.7)
axes[0].plot(rank_ic.index, rank_ic.values, label='Rank IC', alpha=0.7)
axes[0].axhline(y=0, color='r', linestyle='--', alpha=0.3)
axes[0].legend()
axes[0].set_title('IC时间序列')
# 累积图
axes[1].plot(ic.index, ic.cumsum(), label='累积IC')
axes[1].plot(rank_ic.index, rank_ic.cumsum(), label='累积Rank IC')
axes[1].legend()
axes[1].set_title('累积IC')
# 直方图
axes[2].hist(ic.dropna(), bins=30, alpha=0.6, label='IC分布')
axes[2].axvline(x=0, color='r', linestyle='--', alpha=0.3)
axes[2].legend()
axes[2].set_title('IC分布直方图')
plt.tight_layout()
plt.show()
避坑指南:
我曾经犯过一个错误——直接用全部股票的因子值和收益率算IC。结果发现IC很高,但实盘就是不行。后来排查发现,是因为包含了次新股和ST股,它们的收益波动太大,把IC拉高了。
所以,计算IC前一定要做好数据清洗:剔除ST、*ST、新股(上市不满60天)、涨跌停股票。这个步骤不能省。
4.5 实战中的IC分析要点
最后,总结一下我在实战中积累的几个要点:
| 指标 | 含义 | 经验阈值 | 注意事项 |
|---|---|---|---|
| IC均值 | 因子平均预测能力 | 绝对值 > 0.02 | 正负号代表方向 |
| IC标准差 | IC的波动程度 | 越小越好 | 波动大说明不稳定 |
| ICIR | IC的稳定性 | > 0.5 可用,> 1.0 优秀 | 比IC均值更重要 |
| IC正值比例 | IC为正的天数占比 | > 55% | 避免方向频繁反转 |
| Rank IC | 排名的相关性 | 一般比Pearson IC高 | 更稳健,推荐使用 |
嗯,IC分析这块内容就这些。说白了,IC是因子研究的起点,不是终点。一个因子IC好,不代表它一定能赚钱,还要看换手率、容量、与其他因子的相关性等等。但IC不好,那这个因子基本可以放弃了。
我个人习惯,每挖一个新因子,第一件事就是算IC和ICIR。这两个指标不过关,后面的回测都不用做,省时间。
最后一个小技巧:
IC序列可以按市场状态分组分析。比如牛市、熊市、震荡市分别看IC。有的因子在牛市中IC很高,熊市中就翻车。这种因子你要小心,它可能只是“牛市因子”,不具备普适性。
公众号:蓝海资料掘金营,微信deep3321