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 因子贡献度计算步骤

  1. 因子暴露估计: 使用时间序列回归(OLS)估计组合对各因子的 \(\beta\) 系数。
  2. 因子协方差矩阵: 计算因子收益率序列的协方差矩阵 \(\Sigma_F\)。
  3. 系统风险矩阵: 系统风险 = \(\beta^T \Sigma_F \beta\),其中 \(\beta\) 为因子暴露向量。
  4. 因子绝对贡献: 第 \(k\) 个因子的绝对贡献 = \(\beta_k \cdot (\Sigma_F \beta)_k\)。
  5. 因子相对贡献: 第 \(k\) 个因子的相对贡献 = 绝对贡献 / 总风险。
注意: 因子贡献度之和等于系统风险占比,不等于100%。剩余部分为特质风险贡献。若因子间存在强相关性,交叉项贡献可能为负,导致单个因子贡献度超过100%或为负值,需结合经济含义解释。

4.5 因子风险归因流程图

因子模型风险归因流程图 因子模型风险归因流程 组合收益率数据 因子收益率数据 时间序列回归 (OLS) 因子暴露 β 因子协方差矩阵 Σ_F 因子贡献度 = β·(Σ_F·β) 关键输出 • 因子绝对贡献 • 因子相对贡献 • 特质风险占比

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风格因子模型作为补充,提升风险归因的精细化程度。