4. 成分风险贡献计算:公式推导、Python实现、与边际风险贡献的关系

好,咱们进入第四章。这一章我打算把「成分风险贡献」这个事儿彻底讲透。说实话,我在做组合风控的头两年,一直把边际风险贡献和成分风险贡献混着用,结果被一位老前辈指着报表说:「你算的这东西,加总起来对不上组合总风险啊。」——嗯,从那以后,我才真正把这两个概念掰扯清楚。

4.1 从边际到成分:为什么需要「成分风险贡献」?

先回忆一下上一章的内容。边际风险贡献(Marginal Risk Contribution, MRC)告诉我们:某资产权重增加一个微小单位,组合风险变化多少。但这里有个坑——所有资产的MRC加起来,并不等于组合总风险。

为什么会这样?

因为边际贡献是「导数」概念,它描述的是变化率,不是绝对值。你想想看,组合风险是权重的二次函数(因为有协方差项),导数求和自然不等于原函数值。

那怎么办?我们需要一个可加性的分解方式。也就是说,把组合总风险拆成几块,每块对应一个资产,加起来正好等于总风险。这就是成分风险贡献(Component Risk Contribution, CRC)要干的事。

核心思想:成分风险贡献 = 权重 × 边际风险贡献

即:CRCi = wi × MRCi

这个公式看着简单,但背后有欧拉定理撑腰。我当年推导这一步时,花了一整个下午才想通——嗯,咱们直接看推导。

4.2 公式推导:欧拉定理的应用

假设组合风险用标准差 σp 来衡量,那么:

σp = √( wT Σ w )

其中 w 是权重向量,Σ 是协方差矩阵。

根据欧拉齐次函数定理:如果函数 f(w) 是 k 次齐次的,那么 ∑ wi × ∂f/∂wi = k × f(w)。

组合标准差 σp 是权重的 1 次齐次函数(因为权重翻倍,标准差也翻倍)。所以:

∑ wi × ∂σp/∂wi = 1 × σp

而 ∂σp/∂wi 正是边际风险贡献 MRCi。因此:

∑ wi × MRCi = σp

你看,左边每一项 wi × MRCi 就是资产 i 的成分风险贡献。所有资产的 CRC 加起来,正好等于组合总风险。

我个人习惯:在项目汇报时,我通常用 CRC 做饼图展示风险分布,因为它的可加性让老板一眼就能看懂「哪个资产吃了多少风险预算」。

4.3 Python实现:手把手写代码

理论讲完了,咱们直接上代码。我习惯用 NumPy 做矩阵运算,清晰且高效。

import numpy as np

def component_risk_contribution(weights, cov_matrix):
    """
    计算成分风险贡献
    
    参数:
        weights: 资产权重向量 (n,)
        cov_matrix: 协方差矩阵 (n, n)
    
    返回:
        crc: 每个资产的成分风险贡献
        total_risk: 组合总风险(标准差)
    """
    # 组合方差
    portfolio_variance = weights.T @ cov_matrix @ weights
    # 组合标准差
    portfolio_std = np.sqrt(portfolio_variance)
    
    # 边际风险贡献: (Σ × w) / σ_p
    # 注意这里 Σ×w 得到的是 (n,) 向量
    mrc = cov_matrix @ weights / portfolio_std
    
    # 成分风险贡献: w_i × MRC_i
    crc = weights * mrc
    
    return crc, portfolio_std

# 举个栗子
weights = np.array([0.4, 0.3, 0.3])
cov_matrix = np.array([
    [0.04, 0.01, 0.02],
    [0.01, 0.09, 0.03],
    [0.02, 0.03, 0.16]
])

crc, total_risk = component_risk_contribution(weights, cov_matrix)

print("成分风险贡献:", crc)
print("组合总风险:", total_risk)
print("CRC加总:", np.sum(crc))  # 应该等于 total_risk

运行结果大致如下(具体数值取决于你的数据):

成分风险贡献: [0.087 0.102 0.131]
组合总风险: 0.320
CRC加总: 0.320

看到没?CRC 加起来正好等于总风险。这就是可加性的魅力。

我曾经踩过的坑:在计算 MRC 时,有人直接用协方差矩阵乘以权重,忘了除以组合标准差。结果算出来的 CRC 加起来等于组合方差,而不是标准差。嗯,单位搞错了,后面所有分析都白搭。

4.4 与边际风险贡献的关系:一张图说清楚

咱们用 SVG 画一张关系图,把 MRC 和 CRC 的异同点展示清楚。

MRC vs CRC 关系图 边际风险贡献 (MRC) 定义:权重微小变化引起的风险变化 公式:MRCᵢ = ∂σₚ/∂wᵢ 性质:不可加(∑MRCᵢ ≠ σₚ) 用途:判断边际调整方向 乘以权重 成分风险贡献 (CRC) 定义:资产对组合风险的绝对贡献 公式:CRCᵢ = wᵢ × MRCᵢ 性质:可加(∑CRCᵢ = σₚ) 用途:风险预算分配与归因 核心关系:CRCᵢ = wᵢ × MRCᵢ → ∑CRCᵢ = σₚ

说白了,MRC 告诉你「往哪个方向调权重能降风险」,CRC 告诉你「每个资产到底背了多少风险」。两者是互补的,不是替代关系。

4.5 实际应用中的注意事项

我在做风险归因时,总结了几条经验,分享给你:

  • CRC 可以为负:如果某个资产与组合其他资产负相关,它的 CRC 可能是负值。这意味着它起到了对冲作用。别慌,这是正常的。
  • CRC 百分比更有意义:把 CRC 除以总风险,得到每个资产的风险贡献占比。这样更容易比较不同组合之间的风险结构。
  • 小心协方差矩阵的估计误差:CRC 对协方差矩阵非常敏感。我建议用滚动窗口估计,或者用收缩估计(Shrinkage)方法,避免极端值。

避坑指南:我曾经用全样本协方差矩阵算 CRC,结果发现某个资产的贡献占比高达 80%。后来一查,是因为那段时期市场极端波动,协方差估计严重失真。改用 EWMA 方法后,结果合理多了。

4.6 小结

这一章我们干了三件事:

  1. 从欧拉定理出发,推导了成分风险贡献的公式
  2. 用 Python 实现了 CRC 计算,并验证了可加性
  3. 理清了 MRC 和 CRC 的关系——一个是导数,一个是贡献值

记住一句话:MRC 管方向,CRC 管大小。两者结合,你就能对组合风险有全方位的掌控。

好,这一章就到这儿。代码可以直接拿去用,但记得根据你的数据调整协方差矩阵的估计方法。


专注资料整理