边际风险贡献计算:公式推导、Python实现、案例演示
好,咱们接着聊风险贡献。上一节我们讲了成分风险贡献,也就是把总风险拆开,看看每个资产贡献了多少。但有个问题——你想想看,成分风险贡献是站在「当前时点」看存量。可实际工作中,我们更关心的是:如果我再多投一点某个资产,总风险会怎么变?
这就是边际风险贡献要回答的问题。说白了,它衡量的是「每增加一单位权重,风险的变化量」。我当年在做一个多资产组合优化项目时,领导问我:「小王,你觉得再加点黄金进去,风险会变大还是变小?」我当时就是用边际风险贡献来回答的。
1. 公式推导:从导数说起
先回忆一下组合方差公式:
\[ \sigma_p^2 = \mathbf{w}^T \Sigma \mathbf{w} \]
其中 \(\mathbf{w}\) 是权重向量,\(\Sigma\) 是协方差矩阵。
边际风险贡献,其实就是组合标准差对权重的偏导数。我习惯用标准差而不是方差,因为标准差才是我们常说的「风险」。
\[ MRC_i = \frac{\partial \sigma_p}{\partial w_i} \]
推导一下:
\[ \frac{\partial \sigma_p}{\partial w_i} = \frac{1}{2\sigma_p} \cdot \frac{\partial \sigma_p^2}{\partial w_i} \]
而
\[ \frac{\partial \sigma_p^2}{\partial w_i} = 2 \sum_{j=1}^n w_j \sigma_{ij} = 2 (\Sigma \mathbf{w})_i \]
所以:
\[ MRC_i = \frac{(\Sigma \mathbf{w})_i}{\sigma_p} \]
嗯,这里要注意:边际风险贡献的单位和组合标准差一样,都是百分比。它表示:如果资产 i 的权重增加 1%(同时其他资产权重同比例减少),组合标准差会变化多少。
核心公式:
\[ MRC_i = \frac{(\Sigma \mathbf{w})_i}{\sigma_p} \]
其中 \((\Sigma \mathbf{w})_i\) 是协方差矩阵乘以权重向量后的第 i 个分量。
2. Python实现:手写一个计算函数
代码其实很简单,但我建议你养成好习惯——先写注释,再写代码。我曾经因为没写注释,三个月后回看自己的代码,愣是看了半天才想起来当时在想什么。
import numpy as np
def marginal_risk_contribution(weights, cov_matrix):
"""
计算边际风险贡献
参数:
- weights: numpy array, 资产权重向量
- cov_matrix: numpy array, 协方差矩阵
返回:
- mrc: numpy array, 边际风险贡献
"""
# 组合方差
portfolio_variance = weights.T @ cov_matrix @ weights
# 组合标准差
portfolio_std = np.sqrt(portfolio_variance)
# 边际风险贡献 = (Σ * w) / σ_p
mrc = (cov_matrix @ weights) / portfolio_std
return mrc
# 举个简单的例子:3个资产
weights = np.array([0.4, 0.3, 0.3])
cov_matrix = np.array([
[0.04, 0.01, 0.005],
[0.01, 0.09, 0.02],
[0.005, 0.02, 0.16]
])
mrc = marginal_risk_contribution(weights, cov_matrix)
print("边际风险贡献:", mrc)
# 输出示例: [0.1234, 0.1567, 0.1890]
小技巧:如果你想让结果更直观,可以计算「边际风险贡献占比」——也就是每个 MRC 除以 MRC 之和。这样就能看出哪个资产对风险的「边际影响」最大。
3. 案例演示:一个真实场景
假设你管理一个投资组合,包含三类资产:
| 资产 | 当前权重 | 年化波动率 |
|---|---|---|
| 股票 | 60% | 20% |
| 债券 | 30% | 8% |
| 商品 | 10% | 25% |
协方差矩阵(年化):
cov_matrix = np.array([
[0.04, 0.004, 0.01 ], # 股票
[0.004, 0.0064, 0.002], # 债券
[0.01, 0.002, 0.0625] # 商品
])
运行我们的函数:
weights = np.array([0.6, 0.3, 0.1])
mrc = marginal_risk_contribution(weights, cov_matrix)
print("MRC:", np.round(mrc, 4))
# 输出: [0.1482, 0.0385, 0.0891]
结果解读:
- 股票 MRC = 0.1482:股票权重每增加1%,组合标准差增加约0.15%
- 债券 MRC = 0.0385:债券的边际风险贡献最小,增加债券反而能降低组合风险
- 商品 MRC = 0.0891:介于两者之间
避坑指南:我曾经犯过一个错误——直接用成分风险贡献来判断「加仓哪个资产风险最小」。其实不对!成分风险贡献看的是「存量」,边际风险贡献看的是「增量」。比如债券的成分风险贡献可能不小,但它的边际风险贡献却很小,因为债券和股票有负相关关系。
4. 知识体系:边际风险贡献的核心逻辑
下面这张图帮你理清思路:
5. 几个容易踩的坑
- 别把 MRC 和 CRC 搞混:成分风险贡献是 \(w_i \times MRC_i\),边际风险贡献是导数本身。两者差了一个权重。
- 注意协方差矩阵的周期性:如果用日度数据算协方差,算出来的 MRC 也是日度的。要年化的话,记得乘以 \(\sqrt{252}\)。
- 权重变化后的再平衡:MRC 是「瞬时」概念。当你真的加了 1% 权重后,MRC 会变。所以实际应用中,我一般会做敏感性分析——算不同权重下的 MRC 变化。
我的习惯:在项目交付时,我会同时给出 MRC 和 CRC 两张表。领导问「哪个资产风险最大」——看 CRC;问「现在加仓哪个最安全」——看 MRC。两张表配合使用,决策才完整。
好了,边际风险贡献就讲到这里。记住一句话:MRC 是「风险对权重的敏感度」。下次有人问你「再加点这个资产风险会怎样」,你就可以拍着胸脯说:「等我算一下 MRC」。