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 知识体系总览

下面这张图,帮你把整个因子暴露分析的逻辑串起来:

因子暴露分析知识体系 输入数据 策略收益率 + 因子收益率 多元线性回归 OLS估计 + 显著性检验 输出结果 暴露度系数 + t值 + p值 市值因子 SMB 小盘 vs 大盘 动量因子 MOM 趋势 vs 反转 价值因子 HML 高PB vs 低PB 波动率因子 VOL 低波 vs 高波 应用场景 策略归因 | 风险控制 | 风格漂移检测 | 组合优化

4.6 避坑指南

最后,分享几个我踩过的坑:

  • 数据频率要一致:策略用日频,因子也得用日频。别混着用周频和日频,结果会乱套。
  • 小心幸存者偏差:因子数据里如果只包含当前还在交易的股票,那结果会偏乐观。我建议用全历史数据,包括已经退市的。
  • 滚动窗口分析:因子暴露度不是一成不变的。我习惯用36个月的滚动窗口,每个月重新算一次暴露度。这样能看出策略风格有没有漂移。
  • 别过度解读:暴露度高不代表因果关系。可能只是巧合。多跑几个时间段验证一下。

好了,因子暴露分析就聊到这儿。你回去把自己的策略跑一遍,看看暴露在哪些因子上。心里有数了,后面迭代才有方向。


专注资料整理