因子初探:单因子分析基础
各位同学,今天我们来聊聊量化选股中最基础、也最关键的一步——单因子分析。说白了,就是看看我们选出来的这个因子,到底有没有预测能力。
我记得刚入行那会儿,总觉得因子越多越好,恨不得把能想到的指标全塞进模型里。结果呢?过拟合得一塌糊涂,实盘跑起来惨不忍睹。后来才明白,单因子分析才是基本功,就像练武要先扎马步一样。
什么是单因子分析?
单因子分析,就是单独考察一个因子对股票未来收益的预测能力。比如我们想用「市盈率」这个因子选股,那就得先看看:市盈率低的股票,未来是不是真的涨得更好?
这里有几个核心问题需要回答:
- 因子和未来收益之间有没有稳定的关系?
- 这种关系是线性的还是非线性的?
- 因子的预测能力在不同市场环境下是否一致?
嗯,带着这些问题,我们一步步来看。
IC分析:因子与收益的相关性
IC,全称是Information Coefficient,信息系数。它衡量的是因子值与未来收益之间的相关性。常用的有两种:
- Pearson IC:线性相关系数,假设因子和收益是线性关系
- Spearman Rank IC:秩相关系数,只关心排序关系,更稳健
我个人习惯用Rank IC,为什么?因为股票收益往往不是正态分布,极端值很多。Pearson IC容易被几个异常值带偏,而Rank IC只看排名,稳健得多。
IC的计算公式:
# 计算Rank IC的Python示例
import pandas as pd
from scipy.stats import spearmanr
def calc_rank_ic(factor_values, forward_returns):
"""
计算Rank IC
factor_values: 因子值序列
forward_returns: 未来N日收益序列
"""
ic, p_value = spearmanr(factor_values, forward_returns)
return ic, p_value
# 月度IC计算示例
monthly_ic = []
for month in range(12):
ic, _ = calc_rank_ic(
factor_data[month],
return_data[month]
)
monthly_ic.append(ic)
print(f"平均IC: {np.mean(monthly_ic):.4f}")
print(f"IC标准差: {np.std(monthly_ic):.4f}")
IR分析:IC的稳定性更重要
光看IC还不够。你想想看,一个因子IC平均0.05,但有时候0.2有时候-0.1,你敢用吗?
这就引出了IR——Information Ratio,信息比率。它衡量的是IC的稳定性:
IR = mean(IC) / std(IC)
IR越高,说明因子的预测能力越稳定。我在项目中遇到过这样的情况:一个因子IC均值0.08,看起来不错,但IR只有0.3,结果实盘时表现时好时坏,根本没法用。反而是另一个IC均值0.04但IR达到0.8的因子,长期表现非常稳健。
实战经验:IR大于0.5算及格,大于1.0算优秀。如果IR小于0.3,建议直接放弃这个因子。
因子分组回测
IC/IR是从统计角度判断,但做投资的人更关心:如果我用这个因子选股,到底能赚多少钱?
因子分组回测就是干这个的。具体做法:
- 每个月把所有股票按因子值从小到大排序
- 分成10组(Decile)或5组(Quintile)
- 计算每组未来N日的平均收益
- 观察多空组合(第10组 - 第1组)的收益
分组回测代码框架:
def factor_group_backtest(factor_df, return_df, groups=10):
"""
因子分组回测
factor_df: 因子值矩阵,行为时间,列为股票
return_df: 未来收益矩阵
"""
results = {}
for date in factor_df.index:
# 获取当期因子值
factors = factor_df.loc[date].dropna()
# 分组
labels = pd.qcut(factors, groups, labels=False)
# 计算每组收益
group_returns = return_df.loc[date][factors.index]
for g in range(groups):
mask = labels == g
if g not in results:
results[g] = []
results[g].append(group_returns[mask].mean())
# 计算累计收益
cum_returns = {}
for g in results:
cum_returns[g] = (1 + pd.Series(results[g])).cumprod()
return cum_returns
因子有效性初步判断
做完以上分析,我们怎么判断一个因子是否有效?我总结了一个「三看」原则:
| 维度 | 指标 | 合格标准 |
|---|---|---|
| 一看IC | 均值IC | 绝对值 > 0.02 |
| 二看IR | 信息比率 | > 0.5 |
| 三看分组 | 多空收益 | 显著为正,且单调递增 |
我曾经踩过的坑:只看IC均值,忽略了IC的符号稳定性。有个因子IC均值0.03,但正负交替,分组回测的多空收益曲线像心电图一样上下乱窜。后来我加了一个条件:IC为正的月份占比要超过60%。
还有一个容易被忽视的点——因子的换手率。有些因子虽然IC很高,但每个月都要大幅调仓,交易成本一扣,收益就没了。我建议在初步判断时,也看看因子的半衰期和换手率。
本章知识体系
下面这张图总结了单因子分析的核心逻辑:
嗯,以上就是单因子分析的基础内容。记住,因子分析不是一次性工作,而是需要持续迭代的过程。今天讲的这些方法,是后续所有优化工作的基石。
我的建议:刚开始做因子研究时,先拿5-10个经典因子练手,把IC/IR计算、分组回测这些流程跑通。别急着上复杂模型,基础打牢了,后面才能走远。
公众号:蓝海资料掘金营,微信deep3321