风险预算模型原理:从等风险贡献到优化求解

风险预算模型,说白了就是解决一个核心问题:你的钱该怎么分配到不同资产上,才能让每个资产承担的风险差不多

我刚开始做量化的时候,总觉得风险预算是个高大上的概念。后来踩过几次坑才明白,它本质上就是个「公平分蛋糕」的逻辑——只不过这个蛋糕是风险,不是收益。

等风险贡献模型:最朴素的公平

先说说最简单的版本——等风险贡献模型。它的思想很直接:每个资产对组合总风险的贡献度相等

举个例子,你有股票和债券两个资产。如果股票波动大,债券波动小,那等风险贡献模型会要求:

  • 股票少配一点(因为波动大)
  • 债券多配一点(因为波动小)
  • 最终让两者对组合风险的「贡献值」一样

数学上怎么表达?假设组合有 n 个资产,权重向量为 w,协方差矩阵为 Σ。组合方差是 w^T Σ w。第 i 个资产的边际风险贡献(MRC)是:

MRC_i = (Σ w)_i / sqrt(w^T Σ w)

然后第 i 个资产的总风险贡献(TRC)就是权重乘以边际风险贡献:

TRC_i = w_i * MRC_i

等风险贡献模型要求:TRC_1 = TRC_2 = ... = TRC_n

核心要点:等风险贡献不是等权重,也不是等波动率。它追求的是风险层面的公平,而不是资金层面的公平。

我记得有一次给客户做方案,客户说「我要等风险贡献」。结果我算出来股票只配了15%,债券配了85%。客户当场就炸了:「你让我把85%的钱放债券?」我解释了半天,他才明白——因为当时股票波动是债券的5倍,等风险贡献自然要大幅低配股票。

风险预算优化目标函数:从等贡献到自定义

等风险贡献虽然简单,但实际中我们往往需要更灵活的控制。比如:

  • 我想让股票承担40%的风险,债券承担60%的风险
  • 或者我想让某个行业不超过总风险的20%

这时候就需要引入风险预算优化。它的目标函数是:

minimize  Σ (TRC_i / total_risk - b_i)^2

其中 b_i 是预设的风险预算比例,满足 Σ b_i = 1。

说白了,就是让每个资产的实际风险贡献比例,尽可能接近你设定的目标比例。

个人经验:我建议目标预算 b_i 不要设得太极端。比如你设股票风险预算90%、债券10%,那优化结果往往不稳定。因为股票稍微波动一下,实际风险贡献就会大幅偏离目标。

约束条件设定:别让模型放飞自我

光有目标函数还不够,你得给模型加「缰绳」。常见的约束条件有:

  1. 权重约束:每个资产的权重在 [0, 1] 之间,且总和为 1
  2. 杠杆约束:不允许做空(权重 ≥ 0)
  3. 行业集中度约束:单个行业不超过总权重的 30%
  4. 流动性约束:某些资产的最低配置比例

我曾经犯过一个错误:只设了权重约束,没设行业约束。结果模型把30%的资金全配到了某只科技股上,因为它的波动率刚好符合预算目标。但一旦科技股暴跌,整个组合就崩了。嗯,从那以后我再也不敢忽略行业约束了。

避坑指南:约束条件不是越多越好。约束太多会导致模型无解,或者解出来的权重完全不合理。我一般建议:核心约束不超过5个,其他用软约束(惩罚项)处理。

模型求解方法:数值优化与解析解

风险预算模型的求解,主要有两条路:

方法一:数值优化(通用但慢)

直接用优化器求解上面的目标函数。Python 里可以用 scipy.optimize:

import numpy as np
from scipy.optimize import minimize

def risk_budget_objective(weights, cov, budgets):
    port_var = weights @ cov @ weights
    port_vol = np.sqrt(port_var)
    trc = weights * (cov @ weights) / port_vol
    trc_ratio = trc / port_vol
    return np.sum((trc_ratio - budgets) ** 2)

# 约束:权重和为1,且非负
constraints = ({'type': 'eq', 'fun': lambda w: np.sum(w) - 1})
bounds = [(0, 1) for _ in range(n_assets)]

result = minimize(risk_budget_objective, x0, 
                  args=(cov, budgets),
                  constraints=constraints,
                  bounds=bounds,
                  method='SLSQP')

方法二:解析解(快但有限制)

对于等风险贡献这种特殊情况,存在解析解。当协方差矩阵是对角阵(资产间不相关)时,权重与波动率成反比:

w_i = (1/σ_i) / Σ (1/σ_j)

但现实中资产间都有相关性,所以解析解基本用不上。我一般直接用数值优化,虽然慢点,但更可靠。

我的习惯:先用等权重初始化,然后用 SLSQP 方法求解。如果遇到收敛问题,换用 trust-constr 方法。实在不行,就检查一下协方差矩阵是不是奇异矩阵——我遇到过好几次因为数据缺失导致协方差矩阵不可逆的情况。

知识体系总览

下面这张图总结了风险预算模型的核心逻辑:

风险预算模型核心逻辑 输入数据 协方差矩阵 Σ 目标设定 风险预算比例 b_i 约束条件 权重/行业/杠杆 优化求解 min Σ (TRC_i / total_risk - b_i)² 方法:SLSQP / trust-constr 输出结果 最优权重 w* + 实际风险贡献 TRC 验证:TRC_i / total_risk ≈ b_i

从这张图可以看出,风险预算模型本质上是一个输入-优化-输出-验证的闭环。我个人习惯在输出结果后,一定做一步验证——看看实际的风险贡献比例是否真的接近目标。如果偏差超过5%,我会重新检查协方差矩阵或者约束条件。

小技巧:验证时别只看数值,画个柱状图对比目标预算和实际贡献,一眼就能看出问题。我每次做报告都会附上这张图,客户看了也放心。

好了,风险预算模型的核心原理就这些。等风险贡献是基础,自定义预算更灵活,约束条件不能少,求解方法选数值优化最稳妥。下一章我们会聊怎么用 Python 实现完整的风险预算优化流程,包括数据获取、协方差估计、优化求解和结果可视化。


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