4、因子IC分析:IC定义与计算、IC序列分析、IC衰减与换手率分析
因子IC分析,说白了就是回答一个问题:你这个因子到底有没有预测能力?
我刚开始做量化那会儿,经常遇到这种情况——回测曲线漂亮得不行,实盘一跑就崩。后来才发现,问题出在IC分析上。因子和未来收益之间的相关性,才是检验因子的试金石。
4.1 IC的定义与计算
IC(Information Coefficient,信息系数),衡量的是因子值与未来收益之间的相关性。简单说,就是看因子排名和收益排名是否一致。
IC有两种主流计算方式:
- Spearman秩相关系数:计算因子排名与收益排名的相关性。我个人更常用这个,因为它对极端值不敏感。
- Pearson相关系数:直接计算因子值与收益值的线性相关性。要求数据正态分布,实际中很少用。
代码实现其实很简单:
import pandas as pd
import numpy as np
from scipy.stats import spearmanr
def calc_ic(factor_series, return_series):
"""
计算截面IC值
factor_series: 因子值,index为股票代码
return_series: 未来收益,index为股票代码
"""
# 合并数据,去除缺失值
df = pd.DataFrame({'factor': factor_series, 'return': return_series}).dropna()
# 计算Spearman秩相关系数
ic, p_value = spearmanr(df['factor'], df['return'])
return ic, p_value
# 示例:计算某一天的IC
ic_value, p_val = calc_ic(factor_data['2023-01-05'], forward_return['2023-01-05'])
print(f"IC值: {ic_value:.4f}, p值: {p_val:.4f}")
💡 我的经验:IC值在±0.05以上才算有统计意义。±0.1以上算不错,±0.2以上就是非常优秀的因子了。当然,这取决于你的选股池大小和频率。
4.2 IC序列分析
单日的IC值说明不了什么问题。我们需要看IC序列——也就是一段时间内IC值的走势。
IC序列分析主要关注三个维度:
- IC均值:序列的平均值,反映因子整体的预测能力。正值表示因子与收益正相关。
- IC标准差:序列的波动程度,反映因子的稳定性。标准差越小越好。
- ICIR(IC信息比率):IC均值除以IC标准差。这个指标比单纯的IC均值更有参考价值。
我习惯用ICIR来筛选因子。为什么?因为一个因子可能均值很高,但波动也大,实盘时你根本拿不住。ICIR大于0.5的因子,我个人觉得才算合格。
def calc_ic_series(factor_df, return_df):
"""
计算IC时间序列
factor_df: 因子面板数据,index为日期,columns为股票
return_df: 收益面板数据,index为日期,columns为股票
"""
ic_series = pd.Series(index=factor_df.index, dtype=float)
for date in factor_df.index:
if date in return_df.index:
ic, _ = calc_ic(factor_df.loc[date], return_df.loc[date])
ic_series[date] = ic
# 计算统计指标
ic_mean = ic_series.mean()
ic_std = ic_series.std()
icir = ic_mean / ic_std if ic_std != 0 else 0
return ic_series, ic_mean, ic_std, icir
# 示例
ic_series, ic_mean, ic_std, icir = calc_ic_series(factor_panel, forward_return_panel)
print(f"IC均值: {ic_mean:.4f}")
print(f"IC标准差: {ic_std:.4f}")
print(f"ICIR: {icir:.4f}")
🔑 核心要点:IC序列分析不是看某一天的表现,而是看长期的一致性。一个优秀的因子,IC序列应该像心电图——有波动,但整体趋势稳定。
4.3 IC衰减与换手率分析
这里有个坑,我曾经踩过好几次。
IC衰减指的是因子预测能力随时间推移而下降的现象。你想想看,一个因子如果今天有效,明天也有效,但一周后就没用了——这种因子你敢用吗?
IC衰减分析通常这样做:
- 计算因子与未来1天、5天、10天、20天收益的IC值
- 观察IC值随预测期拉长而变化的趋势
- 衰减越慢的因子,信号质量越高
换手率分析则是另一个角度。一个因子如果每天都要换仓,交易成本会吃掉所有收益。我见过很多策略,回测年化30%,扣掉手续费只剩5%。
换手率的计算方式:
def calc_turnover(position_df):
"""
计算组合换手率
position_df: 持仓权重矩阵,index为日期,columns为股票
"""
# 计算每日调仓比例
diff = position_df.diff().abs().sum(axis=1)
turnover = diff / 2 # 双边换手率
avg_turnover = turnover.mean()
return turnover, avg_turnover
# 示例
turnover_series, avg_turn = calc_turnover(portfolio_weights)
print(f"日均换手率: {avg_turn:.2%}")
⚠️ 避坑指南:我曾经有一个因子,IC均值0.08,ICIR也有0.6,看起来很不错。但一算换手率,日均换手率高达40%!这意味着每2.5天就要换一遍仓。扣除千分之三的交易成本后,年化收益直接腰斩。所以,IC分析和换手率分析一定要结合起来看。
4.4 知识体系总览
下面这张图,是我做因子评价时脑子里始终绷着的一根弦:
嗯,这张图基本把IC分析的核心脉络理清了。从定义到计算,从序列分析到衰减和换手率,每一步都有它的意义。
最后说一句:因子评价不是一锤子买卖。我见过太多人,算出一个漂亮的IC值就兴奋得不行,结果实盘被打脸。记住,IC分析只是第一步,后面还有分层回测、分组收益分析、风险归因等等。每一步都扎实了,你的因子才真正经得起考验。
公众号:蓝海资料掘金营,微信 deep3321