3. 因子归因入门:因子模型基础、CAPM模型归因、Fama-French三因子模型归因
聊到策略归因,绕不开的一个话题就是因子模型。说白了,我们做量化投资,赚的钱到底是从哪来的?是运气好,还是真的靠本事?因子归因就是用来回答这个问题的。
我个人习惯把因子模型比作「拆解收益的显微镜」。你想想看,一个策略的收益,其实可以拆解成两部分:一部分是市场整体涨跌带来的(Beta收益),另一部分是超越市场的部分(Alpha收益)。因子模型就是帮我们做这个拆解的工具。
3.1 因子模型基础:为什么需要它?
先问个问题:你辛辛苦苦开发了一个策略,回测年化收益30%。这时候老板问你:「这收益是来自你选股厉害,还是因为最近大盘涨得好?」
嗯,这就是因子归因要解决的核心问题。
因子模型的基本思想很简单:资产的收益可以被一系列共同因子所解释。这些因子可能是市场因子、规模因子、价值因子等等。每个资产对这些因子有不同的暴露度(也就是因子载荷),因子的收益率乘以暴露度,就构成了资产的预期收益。
核心公式:
R_i = α_i + β_i1 * F_1 + β_i2 * F_2 + ... + ε_i
其中:R_i 是资产i的收益率,F_j 是因子j的收益率,β_ij 是资产i对因子j的暴露度,α_i 是超额收益,ε_i 是残差项。
我在项目中遇到过不少新手,一上来就搞几十个因子,觉得因子越多越牛。结果呢?过拟合得一塌糊涂,实盘直接翻车。我的建议是:从最简单的模型开始,逐步增加复杂度。
3.2 CAPM模型归因:最经典的起点
CAPM(资本资产定价模型)是因子模型的鼻祖。它只有一个因子——市场因子。说白了,就是认为股票的收益只跟市场整体涨跌有关。
CAPM的公式长这样:
R_i - R_f = β_i * (R_m - R_f) + α_i
其中R_f是无风险利率,R_m是市场收益率。β_i衡量的是股票对市场的敏感度。
举个例子:假设无风险利率是3%,市场涨了10%,某股票的β是1.2。那么按照CAPM,这只股票的预期超额收益应该是1.2 * (10% - 3%) = 8.4%。如果实际收益是12%,那α就是12% - 3% - 8.4% = 0.6%。
实战小技巧:
做CAPM归因时,我建议用滚动窗口估计β值。比如用过去60个交易日的数据,每天滚动计算。这样能捕捉到β的时变性。我曾经吃过亏,用固定β做归因,结果市场风格切换时,归因结果完全失真。
CAPM的局限性也很明显:它假设只有一个因子能解释收益。现实中,还有很多其他因素在影响股票收益。比如小盘股往往比大盘股收益更高,价值股往往比成长股表现更好。这些CAPM都解释不了。
3.3 Fama-French三因子模型:更精细的归因
1993年,Fama和French在CAPM的基础上,加入了两个新因子:规模因子(SMB)和价值因子(HML)。这就是大名鼎鼎的三因子模型。
三因子模型的公式:
R_i - R_f = α_i + β_mkt * (R_m - R_f) + β_smb * SMB + β_hml * HML + ε_i
三个因子的含义:
- 市场因子(MKT):跟CAPM一样,代表市场整体风险溢价
- 规模因子(SMB):小盘股收益减去大盘股收益,代表规模效应
- 价值因子(HML):高账面市值比股票收益减去低账面市值比股票收益,代表价值效应
我个人觉得,三因子模型最大的贡献是帮我们识别策略的「风格暴露」。比如你的策略如果在小盘股上暴露很高,那收益很大一部分可能来自规模因子,而不是你的选股能力。
避坑指南:
我曾经帮一个朋友做策略归因,他的策略回测收益很高,但用三因子模型一拆,发现α几乎为零。说白了,他的策略就是在做多小盘价值股,赚的全是因子暴露的钱。一旦风格切换,策略就会大幅回撤。所以,做归因不是为了好看,而是为了理解风险来源。
3.4 实战:用Python做三因子归因
下面我给出一个简单的Python实现,用最小二乘法做三因子归因。数据用的是A股市场的模拟数据。
import pandas as pd
import numpy as np
import statsmodels.api as sm
# 模拟数据:策略收益、市场收益、SMB、HML
np.random.seed(42)
dates = pd.date_range('2023-01-01', periods=252, freq='D')
data = pd.DataFrame({
'strategy_ret': np.random.randn(252) * 0.02 + 0.001,
'mkt_ret': np.random.randn(252) * 0.015 + 0.0008,
'smb': np.random.randn(252) * 0.01,
'hml': np.random.randn(252) * 0.01
}, index=dates)
# 计算超额收益(假设无风险利率为0.03/252)
rf = 0.03 / 252
data['strategy_excess'] = data['strategy_ret'] - rf
data['mkt_excess'] = data['mkt_ret'] - rf
# 回归分析
X = data[['mkt_excess', 'smb', 'hml']]
X = sm.add_constant(X)
y = data['strategy_excess']
model = sm.OLS(y, X).fit()
print(model.summary())
# 输出因子暴露和Alpha
print(f"Alpha (年化): {model.params['const'] * 252 * 100:.2f}%")
print(f"市场因子暴露: {model.params['mkt_excess']:.2f}")
print(f"SMB暴露: {model.params['smb']:.2f}")
print(f"HML暴露: {model.params['hml']:.2f}")
运行这段代码,你会得到每个因子的系数(暴露度)和α值。如果α显著为正,说明你的策略确实有超额收益能力。如果α不显著,那就要反思一下了。
3.5 归因结果解读:别被数字骗了
拿到归因结果后,怎么解读?我总结了几个要点:
| 指标 | 含义 | 实战解读 |
|---|---|---|
| α(Alpha) | 超额收益,不能被因子解释的部分 | α显著为正 → 有选股/择时能力;α不显著 → 收益来自因子暴露 |
| β_mkt | 对市场风险的暴露 | β > 1 → 高波动策略;β < 1 → 防御型策略 |
| β_smb | 对规模因子的暴露 | 正值 → 偏向小盘股;负值 → 偏向大盘股 |
| β_hml | 对价值因子的暴露 | 正值 → 偏向价值股;负值 → 偏向成长股 |
| R² | 模型拟合优度 | R²越高 → 策略收益越能被因子解释;R²低 → 可能有独特alpha来源 |
重要提醒:
归因分析不是一次性的工作。我建议每个月做一次滚动归因,观察因子暴露的稳定性。如果某个因子的暴露度忽高忽低,说明策略的风格不稳定,这本身就是一个风险信号。
3.6 本章小结
因子归因入门,说白了就是学会用CAPM和三因子模型来拆解策略收益。记住三个核心点:
- 因子模型是工具,帮我们理解收益来源和风险暴露
- 从简单开始,先跑CAPM,再逐步加因子
- 关注α的显著性,这才是策略真正的价值所在
嗯,这一章的内容就到这里。因子归因是量化策略分析的基础,掌握了它,你就能更清楚地知道自己的策略到底在赚什么钱。