第1章:因子收益率计算——从暴露度到残差的完整拆解
大家好,我是老张。今天咱们聊聊多因子归因里最基础、也最容易被忽视的一环——因子收益率的计算。
说实话,我见过不少团队,模型跑得飞起,但一问到因子收益率怎么算的,支支吾吾说不清楚。嗯,这其实是个大坑。你想想看,归因分析要是地基没打牢,后面所有结论都可能跑偏。
1.1 因子暴露度:你的股票在因子上的“敏感系数”
先讲因子暴露度。说白了,就是某只股票在某个因子上的“得分”。比如市值因子,小盘股暴露度高,大盘股暴露度低。
我个人习惯用标准化后的Z-score来表示暴露度。为什么?因为不同因子的量纲不一样,市盈率是几十倍,换手率是百分之几,不标准化没法直接比较。
举个例子,假设我们有5只股票,计算它们在“动量因子”上的暴露度:
import pandas as pd
import numpy as np
# 原始数据:过去20日收益率
returns_20d = [0.05, -0.02, 0.12, -0.08, 0.03]
stock_names = ['A', 'B', 'C', 'D', 'E']
# 标准化为Z-score
mean_ret = np.mean(returns_20d)
std_ret = np.std(returns_20d)
exposure = [(r - mean_ret) / std_ret for r in returns_20d]
# 结果展示
for name, exp in zip(stock_names, exposure):
print(f"{name}: {exp:.3f}")
输出结果:
A: 0.218
B: -0.654
C: 1.309
D: -1.309
E: 0.436
你看,股票C的动量暴露度最高(1.309),说明它最近涨得最猛。股票D最低(-1.309),跌得最惨。
1.2 因子收益率:横截面回归的核心输出
因子收益率怎么算?最经典的方法是Fama-MacBeth两步法中的第一步——横截面回归。
具体来说,在每个时间点t,我们用所有股票的收益率对因子暴露度做回归:
R_i = α + β_1 * X_i1 + β_2 * X_i2 + ... + ε_i
其中,β就是因子收益率,代表该因子在当期带来的超额收益。
我建议用加权最小二乘法(WLS),权重用市值的平方根。为什么?因为小市值股票波动大,容易带偏回归结果。这是我踩过坑之后才学乖的。
import statsmodels.api as sm
# 假设我们有100只股票,3个因子
# returns: 100x1 的收益率向量
# exposures: 100x3 的暴露度矩阵(已标准化)
# weights: 100x1 的权重向量(市值平方根)
# 添加截距项
X = sm.add_constant(exposures)
# 加权最小二乘回归
model = sm.WLS(returns, X, weights=weights)
results = model.fit()
# 因子收益率就是回归系数
factor_returns = results.params[1:] # 去掉截距项
print("因子收益率:", factor_returns)
1.3 残差收益率:被因子“遗漏”的部分
残差收益率,就是实际收益率减去因子能解释的部分。公式很简单:
ε_i = R_i - (α + β_1 * X_i1 + β_2 * X_i2 + ...)
这个残差很重要。它代表了个股的特质收益——那些因子抓不住的东西。
我曾经遇到过一个案例:某只股票因子暴露度很低,但收益率很高。一开始以为是数据错了,后来发现是公司发布了超预期的业绩预告。这就是典型的残差收益——因子模型解释不了的部分。
# 计算残差收益率
predicted_returns = results.predict(X)
residuals = returns - predicted_returns
# 查看残差最大的几只股票
top_residual = pd.DataFrame({
'stock': stock_names,
'actual_return': returns,
'predicted_return': predicted_returns,
'residual': residuals
}).sort_values('residual', ascending=False)
print(top_residual.head())
1.4 三者关系:一张图说清楚
下面我用一张SVG图来展示因子暴露度、因子收益率和残差收益率之间的关系:
1.5 实战中的避坑指南
最后,分享几个我踩过的坑:
- 多重共线性: 因子之间相关性太高,回归系数会不稳定。我一般用VIF(方差膨胀因子)检测,超过5就剔除或合并因子。
- 异常值处理: 极端暴露度会严重扭曲回归结果。我习惯用MAD(中位数绝对偏差)方法做缩尾处理,比3σ更稳健。
- 时间序列自相关: 因子收益率在时间上可能有自相关。我建议用Newey-West标准误调整t统计量,否则显著性检验会偏大。
好了,因子收益率计算的核心内容就这些。记住:暴露度是输入,因子收益率是过程输出,残差是最终检验。三者缺一不可。