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 知识体系总览

为了让你更直观地理解整个风险贡献的计算逻辑,我画了张图:

风险贡献计算与预算分配逻辑 组合权重 w 协方差矩阵 Σ 组合总风险 σp = √(wᵀΣw) 边际风险贡献 MRC = (Σw)_i / σp 绝对风险贡献 ARC = w_i × MRC_i 相对风险贡献 RRC = ARC_i / σp 风险预算分配:RRC = b_i

这张图把整个流程串起来了:从权重和协方差出发,先算总风险,再拆成三个层次的贡献,最后落到预算分配上。你写代码的时候,就按这个流程一步步来,不会乱。

最后说一句,风险预算模型不是万能药。它假设协方差矩阵是稳定的,但市场会变。我每季度会重新估计一次协方差,并做压力测试——如果某个资产的相关性突然变了,预算还扛得住吗?这才是真正的风险管理。

本章小结:边际风险贡献告诉你「方向」,绝对风险贡献告诉你「大小」,相对风险贡献告诉你「比例」。三者结合,才能精准地把风险预算分配到每个资产上。


公众号:蓝海资料掘金营,微信deep3321