横截面稳定性:测试你的因子是否在不同市场都有效
只在一个市场或行业有效的因子不是真正的 alpha。横截面稳定性测试你的因子的预测力是否在资产、行业和时间段之间都保持一致。
你的因子在美国股票上有很好的 IC = 0.05。但它是真的 alpha——还是只是一个行业赌注、市值赌注,或特定回测期间的伪影?
横截面稳定性测试回答这个问题:因子的预测力是在所有资产的完整横截面上保持,还是集中在某个子集?
为什么稳定性很重要
只在某个行业有效的因子不是通用 alpha。它可能是:
- 伪装成 alpha 的行业轮动策略
- 市值效应(大盘股 vs. 小盘股)
- 地区效应(仅美国等)
- 时间段伪影(2018-2022 年有效但之前无效)
真正的 alpha 是 在横截面上稳健的。 如果你的因子对所有股票都有效,而不只是科技股,你的因子更可能是真的。
测试横截面稳定性的方法
方法 1:按行业计算 IC
按行业分别计算 IC:
import pandas as pd
import numpy as np
from scipy import stats
def ic_by_sector(factor_values, returns, sector_mapping):
"""
按行业分别计算 IC。
"""
results = {}
for sector in sector_mapping.unique():
assets = sector_mapping[sector_mapping == sector].index
fv = factor_values[assets]
ret = returns[assets]
ic_list = []
dates = fv.index
for date in dates[:-1]:
if date not in ret.index:
continue
next_date = ret.index[ret.index.get_loc(date) + 1]
fv_row = fv.loc[date].dropna()
ret_row = ret.loc[next_date].dropna()
common = fv_row.index.intersection(ret_row.index)
if len(common) > 10:
ic, _ = stats.spearmanr(fv_row[common], ret_row[common])
ic_list.append(ic)
results[sector] = {
'mean_ic': np.mean(ic_list),
'positive_pct': np.mean([ic > 0 for ic in ic_list]),
'n_obs': len(ic_list)
}
return pd.DataFrame(results).T
稳定的因子在所有行业有相似的 IC(within sampling variance)。集中在科技的因子在科技有高 IC,其他都接近零。
方法 2:按市值五分位计算 IC
按市值将资产分为五分位,分别计算每个五分位的 IC:
def ic_by_size(factor_values, returns, market_caps, n_quintiles=5):
"""
测试因子 IC 是否随市值变化。
"""
results = {}
dates = factor_values.index
for q in range(1, n_quintiles + 1):
threshold_low = market_caps.quantile((q-1) / n_quintiles)
threshold_high = market_caps.quantile(q / n_quintiles)
assets = market_caps[(market_caps >= threshold_low) &
(market_caps < threshold_high)].index
if len(assets) > 10:
ic_list = []
for date in dates[:-1]:
if date not in returns.index:
continue
next_date = returns.index[returns.index.get_loc(date) + 1]
fv = factor_values.loc[date, assets].dropna()
ret = returns.loc[next_date, assets].dropna()
common = fv.index.intersection(ret.index)
if len(common) > 10:
ic, _ = stats.spearmanr(fv[common], ret[common])
ic_list.append(ic)
results[f'Q{q}'] = {
'mean_ic': np.mean(ic_list),
'positive_pct': np.mean([ic > 0 for ic in ic_list]),
'n_assets': len(assets)
}
return pd.DataFrame(results).T
如果你的因子只在小盘股有效,它是以市值效应的伪装。
方法 3:按地区计算 IC
对于全球策略,测试 IC 在各地区是否一致:
def ic_by_region(factor_values, returns, region_mapping):
"""
测试因子 IC 在各地理区域的一致性。
"""
results = {}
dates = factor_values.index
for region in region_mapping.unique():
assets = region_mapping[region_mapping == region].index
if len(assets) > 20:
ic_list = []
for date in dates[:-1]:
if date not in returns.index:
continue
next_date = returns.index[returns.index.get_loc(date) + 1]
fv = factor_values.loc[date, assets].mean(axis=1)
ret = returns.loc[next_date, assets].mean(axis=1)
common = fv.dropna().index.intersection(ret.dropna().index)
if len(common) > 10:
ic, _ = stats.spearmanr(fv[common], ret[common])
ic_list.append(ic)
results[region] = {
'mean_ic': np.mean(ic_list),
'positive_pct': np.mean([ic > 0 for ic in ic_list])
}
return pd.DataFrame(results).T
方法 4:滚动 IC 稳定性
测试 IC 是否随时间稳定,还是集中在特定时期:
def rolling_ic_stability(factor_values, returns, window=252):
"""
计算滚动 IC 并测试稳定性。
"""
ic_series = compute_rolling_ic(factor_values, returns, window=window)
rolling_ic = ic_series.rolling(window).mean()
rolling_ic_std = ic_series.rolling(window).std()
positive_pct = (rolling_ic > 0).mean()
ic_decay = (rolling_ic.iloc[-window:] < rolling_ic.iloc[:window].mean()).mean()
return {
'rolling_ic': rolling_ic,
'rolling_ic_std': rolling_ic_std,
'positive_pct': positive_pct,
'ic_decay': ic_decay,
'mean_ic': ic_series.mean(),
'std_ic': ic_series.std()
}
关键阈值
| 指标 | 好 | 可疑 |
|---|---|---|
| 行业 IC 标准差 | < 0.02 | > 0.05 |
| 市值 IC 标准差 | < 0.03 | > 0.05 |
| IC 正比例 | > 75% | < 60% |
| 各五分位最小 IC | > 0.01 | < 0 或接近 0 |
常见错误
行业集中伪装成 alpha。 如果你的因子在科技 IC = 0.08,其他都接近零,你没有 alpha——你有一个科技行业观点。要么接受它,要么明确管理行业敞口。
时间段稳定性。 在 2015-2019 年有效但 2020-2024 年无效的因子可能是结构性变化(竞争、市场结构)或只是运气不好。延长样本外测试是确认的唯一方法。
忽略 IC 抽样方差。 即使是真 alpha,不同行业之间的 IC 差异也可能很大,仅仅由于抽样误差。如果行业 A 的 IC 比行业 B 高 0.01,这可能只是噪声。用 t-stat 判断差异是否显著。
在知识体系中的位置
横截面稳定性是任何因子部署前的关键稳健性检查。具有不稳定横截面表现的因子应被怀疑对待——它可能是数据挖掘伪影。因子组合应选择跨横截面稳定的因子。
参考文献
- Ang, Asset Management, 第 9 章. Oxford University Press, 2014. ISBN: 978-0-19-995932-3.
- López de Prado, Advances in Financial Machine Learning, 第 3 章. Wiley, 2018. ISBN: 978-1-119-48208-6.
- Green, Hand, Zhang, “The Characteristics That Provide Independent Information,” Review of Financial Studies, 2013.