4. 因子暴露分析:计算策略在常见因子上的暴露度
各位同学,咱们今天聊点实在的——因子暴露分析。
说白了,就是看看你的策略到底在赚什么钱。是跟着大盘涨跌?还是专门挑小盘股?或者是在赌波动率回归?我见过太多人,回测曲线漂亮得不行,一上实盘就崩。为什么?因为根本不知道自己策略的「底牌」是什么。
因子暴露分析,就是帮你翻底牌的工具。
4.1 什么是因子暴露?
先问个问题:你的策略收益率,能拆成几部分?
经典的思路是这样的:
策略收益 = 市场收益 + 因子收益 + 残差收益
市场收益就是大盘涨跌带来的。因子收益呢,是你主动暴露在某些风格上赚的钱。比如你一直买小市值股票,那市值因子就会贡献一部分收益。残差收益,才是你真正的alpha。
因子暴露,就是衡量你的策略跟某个因子「绑得有多紧」。暴露度越高,说明策略受这个因子影响越大。
核心公式:
因子暴露度 = Cov(R_strategy, R_factor) / Var(R_factor)
其实就是回归系数。把策略收益率对因子收益率做回归,斜率就是暴露度。
4.2 常见因子有哪些?
我个人习惯用这四个核心因子:市值、动量、价值、波动率。够用,且不容易过拟合。
| 因子名称 | 含义 | 构建方式(简版) |
|---|---|---|
| 市值因子 (SMB) | 小盘股 vs 大盘股 | 小市值组合收益 - 大市值组合收益 |
| 动量因子 (MOM) | 过去涨得好的 vs 涨得差的 | 过去12个月收益最高的股票 - 收益最低的 |
| 价值因子 (HML) | 高账面市值比 vs 低账面市值比 | 高PB/PE股票组合 - 低PB/PE股票组合 |
| 波动率因子 (VOL) | 低波动 vs 高波动 | 低波动率股票组合 - 高波动率股票组合 |
嗯,这里要注意:因子构建方式有很多变种。上面给的是最经典的Fama-French思路。你在实际项目中,可以根据数据情况调整。
4.3 计算步骤:手把手来一遍
咱们直接上代码。我用Python演示,数据用pandas处理。
第一步:准备数据
你需要两样东西:策略的每日收益率序列,以及各个因子的每日收益率序列。
import pandas as pd
import numpy as np
import statsmodels.api as sm
# 假设你已经有了这些数据
# strategy_returns: 策略每日收益率,Series
# factor_returns: 因子每日收益率,DataFrame,列名为 'SMB', 'MOM', 'HML', 'VOL'
# 看一眼数据长啥样
print(strategy_returns.head())
print(factor_returns.head())
第二步:做多元线性回归
把策略收益率作为因变量,四个因子收益率作为自变量。别忘了加截距项。
# 合并数据
data = pd.concat([strategy_returns, factor_returns], axis=1).dropna()
data.columns = ['strategy', 'SMB', 'MOM', 'HML', 'VOL']
# 自变量(加截距)
X = data[['SMB', 'MOM', 'HML', 'VOL']]
X = sm.add_constant(X) # 加截距项
# 因变量
y = data['strategy']
# 跑回归
model = sm.OLS(y, X).fit()
# 看结果
print(model.summary())
跑完之后,你会得到每个因子的系数。这个系数就是暴露度。
一个小技巧:我建议你同时看t值和p值。如果某个因子的p值大于0.05,说明暴露度不显著。说白了,就是你的策略跟这个因子关系不大。
第三步:解读结果
假设输出是这样的:
| 因子 | 暴露度 | t值 | p值 |
|---|---|---|---|
| const | 0.0005 | 1.23 | 0.22 |
| SMB | 0.35 | 5.67 | 0.00 |
| MOM | -0.12 | -2.01 | 0.04 |
| HML | 0.08 | 1.45 | 0.15 |
| VOL | -0.25 | -4.32 | 0.00 |
怎么读?
- SMB暴露度0.35:策略偏向小盘股。每1%的小盘股超额收益,策略能多赚0.35%。
- MOM暴露度-0.12:策略有反向动量特征。说白了,你在买跌得多的股票。
- HML暴露度0.08:价值因子暴露不显著(p值0.15)。说明策略跟价值风格关系不大。
- VOL暴露度-0.25:策略偏向低波动股票。每1%的低波动超额收益,策略能多赚0.25%。
我曾经踩过的坑:有一次我跑出来的R方高达0.9,高兴坏了。后来发现是因为因子之间高度相关(多重共线性)。你想想看,市值因子和波动率因子有时候相关性很高。建议算一下VIF(方差膨胀因子),如果某个因子VIF大于5,就要小心了。
4.4 可视化:一张图看懂暴露度
光看数字不够直观。我习惯画一个因子暴露度柱状图,带置信区间。
import matplotlib.pyplot as plt
# 提取系数和置信区间
coef = model.params[1:] # 去掉截距项
ci = model.conf_int().iloc[1:] # 95%置信区间
# 画图
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(coef.index, coef.values, yerr=abs(ci.values - coef.values.reshape(-1,1)).T,
capsize=5, color='steelblue', alpha=0.7)
ax.axhline(y=0, color='red', linestyle='--', linewidth=1)
ax.set_title('策略因子暴露度分析', fontsize=14)
ax.set_ylabel('暴露度')
ax.set_xlabel('因子')
plt.tight_layout()
plt.show()
这张图里,如果某个因子的置信区间跨过0线,说明暴露度不显著。一眼就能看出来。
4.5 知识体系总览
下面这张图,帮你把整个因子暴露分析的逻辑串起来:
4.6 避坑指南
最后,分享几个我踩过的坑:
- 数据频率要一致:策略用日频,因子也得用日频。别混着用周频和日频,结果会乱套。
- 小心幸存者偏差:因子数据里如果只包含当前还在交易的股票,那结果会偏乐观。我建议用全历史数据,包括已经退市的。
- 滚动窗口分析:因子暴露度不是一成不变的。我习惯用36个月的滚动窗口,每个月重新算一次暴露度。这样能看出策略风格有没有漂移。
- 别过度解读:暴露度高不代表因果关系。可能只是巧合。多跑几个时间段验证一下。
好了,因子暴露分析就聊到这儿。你回去把自己的策略跑一遍,看看暴露在哪些因子上。心里有数了,后面迭代才有方向。