4. 因子模型风险归因:基于CAPM、Fama-French多因子模型的风险分解、因子贡献度计算
4.1 因子模型风险归因的核心逻辑
因子模型将组合收益与风险分解为系统性(因子)与特质性(残差)两部分。风险归因的目标是量化每个因子对组合总风险的贡献度,从而识别风险来源、优化因子暴露。
核心公式: 组合超额收益 \( R_p - R_f = \sum_{k=1}^{K} \beta_{p,k} \cdot F_k + \varepsilon_p \),其中 \(\beta_{p,k}\) 为组合对因子 \(k\) 的暴露,\(F_k\) 为因子收益率,\(\varepsilon_p\) 为特质收益。
风险归因的两种主流视角:
- 边际贡献(Marginal Contribution): 衡量因子暴露微小变动对组合风险的影响,用于调仓决策。
- 绝对贡献(Absolute Contribution): 衡量每个因子在组合总风险中占有的份额,用于风险报告。
4.2 CAPM单因子风险分解
CAPM假设市场因子是唯一系统性风险来源。组合风险可分解为:
| 风险成分 | 计算公式 | 含义 |
|---|---|---|
| 市场风险 | \(\beta_p^2 \cdot \sigma_m^2\) | 由市场波动引起的组合风险 |
| 特质风险 | \(\sigma_{\varepsilon}^2\) | 组合特有、可分散的风险 |
| 总风险 | \(\sigma_p^2 = \beta_p^2 \sigma_m^2 + \sigma_{\varepsilon}^2\) | 组合收益的总方差 |
实战要点: 在CAPM框架下,市场因子贡献度 = \(\beta_p^2 \sigma_m^2 / \sigma_p^2\)。若该值低于80%,说明组合存在显著的非市场风险暴露,需引入多因子模型。
4.3 Fama-French多因子模型风险分解
以三因子模型(市场、规模SMB、价值HML)为例,组合风险方差分解为:
组合风险方差 = β_m²·σ²_m + β_smb²·σ²_smb + β_hml²·σ²_hml
+ 2·β_m·β_smb·Cov(m, smb)
+ 2·β_m·β_hml·Cov(m, hml)
+ 2·β_smb·β_hml·Cov(smb, hml)
+ σ²_ε
其中交叉项(协方差项)反映了因子之间的相关性对组合风险的影响,不可忽略。
4.4 因子贡献度计算步骤
- 因子暴露估计: 使用时间序列回归(OLS)估计组合对各因子的 \(\beta\) 系数。
- 因子协方差矩阵: 计算因子收益率序列的协方差矩阵 \(\Sigma_F\)。
- 系统风险矩阵: 系统风险 = \(\beta^T \Sigma_F \beta\),其中 \(\beta\) 为因子暴露向量。
- 因子绝对贡献: 第 \(k\) 个因子的绝对贡献 = \(\beta_k \cdot (\Sigma_F \beta)_k\)。
- 因子相对贡献: 第 \(k\) 个因子的相对贡献 = 绝对贡献 / 总风险。
注意: 因子贡献度之和等于系统风险占比,不等于100%。剩余部分为特质风险贡献。若因子间存在强相关性,交叉项贡献可能为负,导致单个因子贡献度超过100%或为负值,需结合经济含义解释。
4.5 因子风险归因流程图
4.6 多因子风险归因案例
假设某组合使用Fama-French五因子模型(市场、规模、价值、盈利、投资),回归得到以下暴露与因子协方差:
| 因子 | 暴露 β | 因子方差 | 绝对贡献 | 相对贡献 |
|---|---|---|---|---|
| 市场 (MKT) | 1.05 | 0.0250 | 0.0276 | 55.2% |
| 规模 (SMB) | 0.32 | 0.0080 | 0.0026 | 5.2% |
| 价值 (HML) | 0.18 | 0.0060 | 0.0011 | 2.2% |
| 盈利 (RMW) | -0.10 | 0.0040 | 0.0004 | 0.8% |
| 投资 (CMA) | 0.05 | 0.0030 | 0.0002 | 0.4% |
| 交叉项合计 | — | — | 0.0081 | 16.2% |
| 系统风险合计 | — | — | 0.0400 | 80.0% |
| 特质风险 | — | — | 0.0100 | 20.0% |
| 总风险 | — | — | 0.0500 | 100% |
案例解读: 市场因子贡献55.2%风险,是最大风险源;交叉项合计贡献16.2%,说明因子间相关性不可忽视;特质风险20%,组合分散化程度中等。若需降低风险,应优先减少市场暴露或对冲市场风险。
4.7 因子风险归因的Python实现
import numpy as np
import pandas as pd
import statsmodels.api as sm
def factor_risk_decomposition(returns, factor_returns):
"""
因子风险归因函数
Parameters:
returns: 组合收益率 Series
factor_returns: 因子收益率 DataFrame
Returns:
factor_contrib: 因子贡献度 DataFrame
"""
# 1. 时间序列回归估计因子暴露
X = sm.add_constant(factor_returns)
model = sm.OLS(returns, X).fit()
betas = model.params[1:] # 剔除截距项
# 2. 因子协方差矩阵
cov_factors = factor_returns.cov()
# 3. 系统风险矩阵
beta_vec = betas.values
systematic_risk = beta_vec @ cov_factors @ beta_vec
# 4. 因子绝对贡献
factor_abs_contrib = beta_vec * (cov_factors @ beta_vec)
# 5. 因子相对贡献
total_risk = returns.var()
factor_rel_contrib = factor_abs_contrib / total_risk
# 6. 特质风险
idiosyncratic_risk = total_risk - systematic_risk
# 结果汇总
result = pd.DataFrame({
'暴露': betas,
'绝对贡献': factor_abs_contrib,
'相对贡献': factor_rel_contrib
})
result.loc['特质风险'] = [np.nan, idiosyncratic_risk, idiosyncratic_risk/total_risk]
result.loc['总风险'] = [np.nan, total_risk, 1.0]
return result
4.8 因子风险归因的常见陷阱
- 因子多重共线性: 高度相关的因子会导致暴露估计不稳定,贡献度解释困难。建议使用正交化因子或降维处理。
- 时变暴露: 因子暴露随时间变化,滚动窗口回归比全样本回归更准确。建议使用60个月滚动窗口。
- 特质风险低估: 若因子遗漏重要风险源,特质风险会被高估。应通过因子有效性检验确保模型完备性。
- 交叉项解释: 负的交叉项贡献不代表因子无风险,而是因子间对冲降低了组合风险。
最佳实践: 在月度报告中,同时展示因子绝对贡献与相对贡献的时序变化,结合Drift监控(第5章)判断因子暴露是否需要调整。建议使用Barra风格因子模型作为补充,提升风险归因的精细化程度。