风险预算模型原理:等风险贡献(ERC)模型、风险预算的数学推导、风险贡献的计算方法
各位同学,今天我们来啃一块硬骨头——风险预算模型。说实话,我刚入行那会儿,觉得这东西就是数学公式堆砌,离实战很远。直到有一次,我管理的组合在极端行情下差点爆仓,才真正意识到:不懂风险预算,你就是在蒙眼开车。
嗯,咱们今天不讲虚的。直接上干货。
一、等风险贡献(ERC)模型:最朴素的公平
先问大家一个问题:如果你有100块钱,要买股票和债券,怎么分配?
传统做法是“等权重”——各50块。但你想过没有?股票的波动率可能是债券的5倍。等权重分配,其实是在让股票承担绝大部分风险。
ERC模型的核心思想很简单:让每个资产对组合总风险的贡献相等。说白了,就是“风险面前,人人平等”。
ERC的核心逻辑:
- 不是资金等权重,而是风险贡献等权重
- 高波动资产自动获得更低的资金权重
- 低波动资产自动获得更高的资金权重
我在项目中遇到过这样一个案例:一个股债60/40组合,表面看很稳健。但用ERC一算,股票的风险贡献占了92%,债券只有8%。这哪是平衡?这分明是押注股市。后来我们按ERC重新调仓,股票仓位降到35%,债券升到65%,组合的夏普比率从0.8提升到了1.3。
你想想看,同样的资金,只是换了个分配逻辑,效果天差地别。
二、风险预算的数学推导:从直觉到公式
好,直觉有了,咱们上数学。别怕,我会用最白话的方式讲。
首先,定义几个东西:
- 组合总风险:用方差表示,σ²(p) = w' Σ w
- 第i个资产的边际风险贡献:MRC_i = ∂σ(p)/∂w_i
- 第i个资产的总风险贡献:RC_i = w_i × MRC_i
这里有个关键点:所有资产的风险贡献之和,正好等于组合总风险。这不是巧合,是数学上的必然。
为什么?我给大家推导一下:
组合方差 σ²(p) = w₁²σ₁² + w₂²σ₂² + 2w₁w₂σ₁₂
对w₁求偏导:∂σ²(p)/∂w₁ = 2w₁σ₁² + 2w₂σ₁₂
边际风险贡献 MRC₁ = (1/2σ(p)) × ∂σ²(p)/∂w₁
= (w₁σ₁² + w₂σ₁₂) / σ(p)
总风险贡献 RC₁ = w₁ × MRC₁
= w₁(w₁σ₁² + w₂σ₁₂) / σ(p)
你看,RC₁ + RC₂ 算出来,正好等于 σ(p)。这就是风险预算的数学基础。
个人习惯:我每次做风险预算,都会先算一遍这个等式。如果两边不相等,说明代码写错了。曾经有一次,我调了一整天bug,最后发现是协方差矩阵没做正定化处理。嗯,血的教训。
三、风险贡献的计算方法:手把手教你算
理论讲完了,咱们来点实际的。怎么算?
我一般分三步走:
- 计算协方差矩阵:用历史数据,窗口期我习惯用252天(一年交易日)
- 计算边际风险贡献:用矩阵运算,一步到位
- 计算总风险贡献:权重乘以边际贡献
给你看一段Python代码,这是我项目里一直在用的:
import numpy as np
def calculate_risk_contribution(weights, cov_matrix):
"""
计算每个资产的风险贡献
weights: 资产权重向量
cov_matrix: 协方差矩阵
"""
# 组合方差
portfolio_variance = weights.T @ cov_matrix @ weights
# 组合标准差
portfolio_std = np.sqrt(portfolio_variance)
# 边际风险贡献
marginal_contrib = (cov_matrix @ weights) / portfolio_std
# 总风险贡献
risk_contrib = weights * marginal_contrib
# 风险贡献占比
risk_contrib_pct = risk_contrib / portfolio_std
return risk_contrib, risk_contrib_pct
# 举个栗子: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]
])
rc, rc_pct = calculate_risk_contribution(weights, cov_matrix)
print("风险贡献:", rc)
print("风险贡献占比:", rc_pct)
注意:这段代码假设协方差矩阵已经计算好了。实际项目中,协方差矩阵的估计是个大坑。我曾经用60天滚动窗口,结果遇到市场突变,矩阵直接奇异了。后来我改用指数加权移动平均(EWMA),效果好了很多。
四、ERC模型的求解:数值方法
ERC模型的求解,说白了就是找一组权重,让所有资产的风险贡献相等。数学上可以写成:
目标: RC_i = RC_j,对所有i, j成立
这通常没有解析解,得用数值方法。我常用的方法是:
- 梯度下降法:简单粗暴,但要注意学习率
- 牛顿法:收敛快,但需要二阶导数
- scipy.optimize:懒人首选,直接调库
我个人习惯用scipy,因为稳定。给你看个例子:
from scipy.optimize import minimize
def erc_objective(weights, cov_matrix):
"""ERC的目标函数:让所有风险贡献相等"""
n = len(weights)
rc, _ = calculate_risk_contribution(weights, cov_matrix)
# 目标:每个风险贡献与平均值的差的平方和最小
target = np.mean(rc)
return np.sum((rc - target)**2)
# 约束:权重和为1,且都大于0
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
bounds = [(0, 1) for _ in range(3)]
# 初始权重:等权重
init_weights = np.array([1/3, 1/3, 1/3])
result = minimize(erc_objective, init_weights,
args=(cov_matrix,),
method='SLSQP',
bounds=bounds,
constraints=constraints)
print("ERC最优权重:", result.x)
实战经验:ERC模型有个隐含假设——资产间的相关性是稳定的。但现实世界,相关性会变。2018年我做过一个回测,股债相关性在危机时从0.2跳到了0.6,ERC组合瞬间失效。后来我加了相关性预警机制,一旦相关性突破阈值,就强制再平衡。
五、风险预算的SVG框架图
为了让你更直观地理解整个体系,我画了张图:
这张图把整个知识体系串起来了。你从ERC模型出发,理解数学推导,掌握计算方法,最后回到动态调仓。每一步都有坑,每一步也都有解法。
我的建议:刚开始学风险预算,别急着上复杂模型。先用两个资产练手,把ERC的直觉建立起来。等你能手算两个资产的ERC权重了,再扩展到多资产。我当年就是这么过来的,稳扎稳打,比一上来就搞10个资产强得多。
好了,这一章的内容就到这里。记住:风险预算不是数学游戏,它是你组合管理的安全带。下一章我们会讲如何把风险预算落地到动态调仓策略中,到时候我会分享一个我踩过的坑——关于再平衡频率的选择,保证让你少走弯路。
公众号:蓝海资料掘金营,微信deep3321