4、风险贡献计算:边际风险贡献、绝对风险贡献、相对风险贡献、风险预算分配逻辑
好,咱们进入风险预算模型最核心的环节——风险贡献计算。
说实话,很多做量化的朋友把风险预算挂在嘴边,但真让他算一笔账,往往就卡在「贡献」这两个字上。我当年刚入行时也踩过这个坑,以为风险贡献就是权重乘以波动率,结果被风控总监叫去办公室聊了半小时人生。
今天咱们把这块彻底掰开揉碎。你想想看,风险预算的本质是什么?就是把总风险这个蛋糕,切成几块分给不同资产。但怎么切?切多大?这就得靠边际、绝对、相对这三把刀。
4.1 边际风险贡献(Marginal Risk Contribution)
边际风险贡献,说白了就是:某资产权重增加一个微小单位,组合总风险会变化多少。
数学上,它是组合风险对权重的偏导数。假设组合方差为 σ²p = wᵀΣw,那么第 i 个资产的边际风险贡献就是:
MRC_i = ∂σp / ∂w_i = (Σw)_i / σp
嗯,这里要注意,MRC 是个有方向的东西。正值意味着增加权重会推高风险,负值则相反。我在项目中遇到过一种情况:某债券和股票高度负相关,它的 MRC 居然是负的。当时团队里有人想加杠杆,我说等等,你加仓反而会降低组合波动——这就是边际风险贡献告诉我们的反直觉事实。
核心要点:边际风险贡献衡量的是「最后一单位」的影响,不是平均影响。
4.2 绝对风险贡献(Absolute Risk Contribution)
绝对风险贡献,也叫成分风险贡献(Component Risk Contribution)。它回答的问题是:每个资产对组合总风险贡献了多少绝对值。
计算公式很简单:
ARC_i = w_i × MRC_i = w_i × (Σw)_i / σp
注意,所有资产的 ARC 加起来,正好等于组合总风险 σp。这是一个完美的分解性质。我习惯用这个性质来校验模型——如果加总不等于总风险,那一定是代码写错了。
举个例子,假设组合只有两个资产:
| 资产 | 权重 | 波动率 | 相关系数 | MRC | ARC |
|---|---|---|---|---|---|
| 股票 | 60% | 20% | 0.3 | 0.18 | 0.108 |
| 债券 | 40% | 8% | 0.07 | 0.028 | |
| 组合总风险 | 0.136 | ||||
你看,股票贡献了 0.108 的风险,债券贡献了 0.028,加起来正好 0.136。这就是绝对风险贡献的妙处——每一分风险都有主。
4.3 相对风险贡献(Relative Risk Contribution)
相对风险贡献,其实就是把绝对风险贡献归一化,看看每个资产承担了总风险的百分之多少。
RRC_i = ARC_i / σp
这个指标在风险预算中特别有用。因为很多时候我们关心的不是具体数值,而是比例。比如风控委员会开会,你说「股票贡献了 79.4% 的风险」,比说「股票贡献了 0.108」要直观得多。
我曾经帮一家保险资管做风险归因,他们要求每个资产类别的相对风险贡献不能超过 30%。结果发现某只高收益债的 RRC 飙到了 45%,一查才知道,这只债的久期被低估了,实际风险敞口比名义上大得多。这就是相对风险贡献的实战价值——帮你快速定位风险集中度。
避坑指南:相对风险贡献对协方差矩阵的估计误差非常敏感。我曾经因为用 60 天滚动窗口估计协方差,导致 RRC 在每个月末剧烈跳动,后来改用 EWMA 模型才稳定下来。
4.4 风险预算分配逻辑
好了,前面三把刀都磨好了,现在咱们来切蛋糕。
风险预算分配的核心逻辑是:让每个资产的相对风险贡献等于预设的风险预算比例。
数学上,我们要解这样一个方程组:
RRC_i = b_i, 对于所有 i
其中 b_i 是预设的风险预算,且 ∑b_i = 1。
这个方程组没有解析解,得用数值方法迭代求解。我常用的方法是牛顿法或者序列二次规划。下面给个简单的 Python 实现思路:
import numpy as np
from scipy.optimize import minimize
def risk_budget_objective(weights, cov, budgets):
# 计算组合风险
port_vol = np.sqrt(weights @ cov @ weights)
# 计算边际风险贡献
mrc = cov @ weights / port_vol
# 计算绝对风险贡献
arc = weights * mrc
# 计算相对风险贡献
rrc = arc / port_vol
# 目标:让 RRC 接近预算
return np.sum((rrc - budgets) ** 2)
# 初始权重设为等权
w0 = np.ones(n) / n
# 约束:权重和为1,且非负
cons = ({'type': 'eq', 'fun': lambda w: np.sum(w) - 1})
bounds = [(0, 1) for _ in range(n)]
result = minimize(risk_budget_objective, w0,
args=(cov, budgets),
constraints=cons,
bounds=bounds,
method='SLSQP')
optimal_weights = result.x
嗯,这里要注意几个细节:
- 初始权重很重要:我习惯用等风险贡献(ERC)的权重作为起点,收敛更快
- 约束条件要谨慎:如果允许做空,边界要设为 (-∞, ∞),但风险预算模型通常不允许
- 收敛判据:我一般设 RRC 与预算的误差小于 1e-6 就算收敛
实战技巧:如果遇到不收敛的情况,先检查协方差矩阵是否正定。我曾经因为数据缺失导致协方差矩阵奇异,优化器直接报错。后来用 shrinkage 方法做了正则化,问题就解决了。
4.5 知识体系总览
为了让你更直观地理解整个风险贡献的计算逻辑,我画了张图:
这张图把整个流程串起来了:从权重和协方差出发,先算总风险,再拆成三个层次的贡献,最后落到预算分配上。你写代码的时候,就按这个流程一步步来,不会乱。
最后说一句,风险预算模型不是万能药。它假设协方差矩阵是稳定的,但市场会变。我每季度会重新估计一次协方差,并做压力测试——如果某个资产的相关性突然变了,预算还扛得住吗?这才是真正的风险管理。
本章小结:边际风险贡献告诉你「方向」,绝对风险贡献告诉你「大小」,相对风险贡献告诉你「比例」。三者结合,才能精准地把风险预算分配到每个资产上。
公众号:蓝海资料掘金营,微信deep3321