IC是在某一个特定日期,对所有股票的横截面(Cross-section)计算出的相关系数。
这是衡量因子预测能力的常用指标,其时间序列常用于后续均值、标准差、信息比率计算分析。
这里尝试基于网络资料,探索信息系数IC时间序列的计算过程。
1 IC计算
信息系数(Information Coefficient,简称IC)
信息系数IC时间序列的计算,需要从空间和时间两个维度分开看。
IC时间序列是将IC计算,在时间轴上逐日滚动重复,把每天的IC值串起来形成的序列。
整体计算过程为:
在每一个交易日,拿出当天所有股票的最新因子值和对应的未来收益。
剔除空值和常量,算一个相关系数;
然后下一天,再来一遍,
把每天的相关系数按时间连成一根曲线。
这里分步讨论计算过程,细节如下
step1 面板数据
计算开始前,确保数据必须是面板数据(Panel Data)结构,即底层数据的结构。
因子值表(Factor Values):行为日期(t),列为股票代码(i)。单元格为当日因子暴露度。
远期收益表(Forward Returns):行为日期(t),列为股票代码(i)。单元格为对应日期买入后、持有N日的未来收益(如t+1日收盘价/t日收盘价 - 1)。
需要注意的是
远期收益必须与因子值在时间上严格错位,比如因子值用
t日信息,收益用t+1或t+5日数据,否则会造成未来数据泄漏(Look-ahead Bias)。
step2 对齐与清洗
对齐与清洗的主要工作为逐日横截面数据预处理。
对于时间轴上的每一个交易日t,执行以下子步骤:
1)取切片
从因子表中取出t日的行向量,从收益表中取出
t日的行向量。
2)时间对齐(索引对齐)
由于停牌、退市或数据缺失,两个向量中的股票未必完全相同。
此时取二者的交集(Intersection),仅保留当天既有因子值又有未来收益的股票。
3)缺失值剔除(Drop NA)
剔除因子值为NaN或收益值为NaN的股票。
4)常量检查(Variance Check)
计算经过以上筛选后剩余样本的因子值标准差和收益标准差。
如果某一方的标准差接近 0,如std < 1e-10,说明该日所有股票因子值几乎一样,或收益一样,此时相关系数无意义,直接跳过该日。
5)最小样本量过滤
经过上述筛选剔除后,
如果剩余股票数量少于阈值(如10只),此时统计量极不可靠,直接跳过该日数据。
经过这步,我们得到两个长度相等(设为 NN)的纯净数组:
step3 横截面相关系数
IC的核心数学计算即横截面相关系数,这里有多种计算方式可以选择。
1)pearson
pearson即皮尔逊线性相关,具体为计算两组数组的协方差除以标准差乘积
公式为:
它衡量的是因子值与收益之间的线性相关程度,极易受极端值(Outliers)影响。
2)spearman
pearson易受极端值影响,这里引入spearman即斯皮尔曼秩相关。
计算过程为
首先,将原始
和
分别转换为各自秩Rank,即排序后位置编号(若有并列值则取平均秩)
然后,代入上述皮尔逊公式计算秩之间的相关系数
公式示例如下
spearman衡量的是因子值与收益之间的单调关系(Monotonic Relationship)。
spearman不要求线性,且对极端值稳健,在量化选股中使用更广泛。
在实践计算一般返回多个值元组,比如(ic, p_value),横截面相关系数即为第一个ic。
step4 生成时间序列
生成时间序列即迭代滚动
将第三阶段的计算封装成一个函数,作用在第二阶段预处理后的数据上。
然后:
- 遍历日期索引(如 `2020-01-01` 到 `2025-12-31`)。
- 对每个交易日执行一次上述完整流程,得到一个浮点数
。
- 将日期
和对应的
存入列表。
当所有日期遍历完毕,得到了一个以日期为索引、数值为每日IC值的序列,即 IC 时间序列:
step5 时间序列的后续衍生分析
计算出序列后,通常用来做以下总结:
- 均值(Mean IC):衡量因子整体的预测能力(正负方向)。
- 标准差(Std IC):衡量因子预测能力的稳定性。
- ICIR(Information Ratio of IC):
,衡量因子性价比,通常要求大于 0.5 或 1.0。
- 胜率(Win Rate):IC > 0 的天数占总天数的比例。
- 自相关性(Autocorrelation):检验IC序列是否存在趋势(若自相关高,可能因子衰减较慢)。
2 示例代码
1)代码示例
示例代码实现了因子投资分析中常用的 信息系数(IC,Information Coefficient)时间序列 计算。
def compute_ic_series( factor_values: pd.DataFrame, forward_returns: pd.DataFrame, method: str = "pearson", min_samples: int = 10, ) -> pd.DataFrame: # 确保列名一致 common_stocks = factor_values.columns.intersection(forward_returns.columns) if len(common_stocks) == 0: raise ValueError("No common stocks between factor and returns") factor = factor_values[common_stocks] ret = forward_returns[common_stocks] # 只取共同日期 common_dates = factor.index.intersection(ret.index) factor = factor.loc[common_dates] ret = ret.loc[common_dates] ic_list = [] p_list = [] n_list = [] for date in common_dates: f = factor.loc[date].dropna() r = ret.loc[date].dropna() # 使用 index 交集,或者直接用 dropna 后再对齐 common = f.index.intersection(r.index) if len(common) < min_samples: continue f_vals = f.loc[common].values r_vals = r.loc[common].values if np.nanstd(f_vals) < 1e-12 or np.nanstd(r_vals) < 1e-12: continue if method == "pearson": ic, p = stats.pearsonr(f_vals, r_vals) elif method == "spearman": ic, p = stats.spearmanr(f_vals, r_vals) else: raise ValueError(...) ic_list.append(ic) p_list.append(p) n_list.append(len(common)) return pd.DataFrame({ "IC": ic_list, "p_value": p_list, "n": n_list }, index=common_dates[:len(ic_list)])2)代码说明
该代码整体实现了 IC 序列的基本计算逻辑,适合中小规模数据的快速验证。
其函数compute_ic_series接受两个 DataFrame
- factor_values:每日各股票的因子值,行索引为日期,列名为股票代码。
- forward_returns:对应的未来收益(例如次日收益、N日收益等),结构同上。
对每个交易日,计算所有股票因子值与未来收益之间的截面相关系数(可选 Pearson 或 Spearman),并返回按日期索引的 IC 序列pd.Series。将收集到的 IC 值和对应日期构造成pd.Series,索引为日期,名称为IC_{method}。
需要注意的是,这仅仅是验证测试代码,在生产环境或大规模回测,需进行性能、稳健性优化。
比如,通过引入参数化、异常处理和更强的数据对齐控制,使其更健壮、更通用,速度更快。
3 预处理要点
1)为什么要求交集
若某股票因子存在但未来停牌导致收益缺失,不剔除的话计算机会自动忽略或报错,强行填充 0 会引入巨大偏差,所以必须严格取共有股票。
2)跳过样本少于10的日期
统计学上,样本量过小导致相关系数的置信区间极宽。
甚至一对极端值就能把IC拉到 ±1,这回使得IC的分析毫无参考价值。
3)Spearman的平局处理
scipy.stats.spearmanr内部默认对平局(Ties)取平均秩,这在因子值大量相等(如很多股票为0)时依然能稳定计算。
4)align(join="inner")双重作用
它同时对行(日期)和列(股票)做了内连接。
这意味着如果某一天在因子表里有但在收益表里没有,该日会被直接丢弃;
同样,某只股票在其中一个表缺失,也会被剔除。
reference
---
quantrocket-llc/alphalens
GitHub - quantopian/alphalens: Performance analysis of predictive (alpha) stock factors · GitHub
单因子有效性分析-因子IC分析
https://zhuanlan.zhihu.com/p/593817951#1
IC测试与因子有效性检验实例
https://raw.githubusercontent.com/laozdao/dao-quant-research/refs/heads/main/articles/M06-factor-validation/M06-02-ic-test-factor-validation.md#1
如何在编写交易指标代码时避免未来函数(Look-ahead Bias)
https://www.patternsmart.com/cn/如何在编写交易指标代码时避免未来函数(look-ahead-bias)