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 告诉你「往哪个方向调权重能降风险」,CRC 告诉你「每个资产到底背了多少风险」。两者是互补的,不是替代关系。
4.5 实际应用中的注意事项
我在做风险归因时,总结了几条经验,分享给你:
- CRC 可以为负:如果某个资产与组合其他资产负相关,它的 CRC 可能是负值。这意味着它起到了对冲作用。别慌,这是正常的。
- CRC 百分比更有意义:把 CRC 除以总风险,得到每个资产的风险贡献占比。这样更容易比较不同组合之间的风险结构。
- 小心协方差矩阵的估计误差:CRC 对协方差矩阵非常敏感。我建议用滚动窗口估计,或者用收缩估计(Shrinkage)方法,避免极端值。
避坑指南:我曾经用全样本协方差矩阵算 CRC,结果发现某个资产的贡献占比高达 80%。后来一查,是因为那段时期市场极端波动,协方差估计严重失真。改用 EWMA 方法后,结果合理多了。
4.6 小结
这一章我们干了三件事:
- 从欧拉定理出发,推导了成分风险贡献的公式
- 用 Python 实现了 CRC 计算,并验证了可加性
- 理清了 MRC 和 CRC 的关系——一个是导数,一个是贡献值
记住一句话:MRC 管方向,CRC 管大小。两者结合,你就能对组合风险有全方位的掌控。
好,这一章就到这儿。代码可以直接拿去用,但记得根据你的数据调整协方差矩阵的估计方法。