3. 风险平价模型:让每份风险都“公平”分担

各位同学,咱们今天聊一个在量化圈里特别火的话题——风险平价模型。

说实话,我刚入行那会儿,大家做资产配置还停留在“60%股票+40%债券”这种老套路。后来我参与了一个FOF项目,发现这种配置方式有个致命问题:股票一跌,整个组合就崩了。为什么?因为股票的风险占了组合总风险的90%以上。你想想看,债券虽然配了40%,但它的波动率只有股票的1/3左右,风险贡献微乎其微。

所以,风险平价模型的核心思想很简单:让每种资产对组合总风险的贡献相等。说白了,就是“谁的风险大,谁就少配点;谁的风险小,谁就多配点”。

3.1 风险平价理论介绍

风险平价(Risk Parity)这个概念,最早是由桥水基金的Ray Dalio推广的。他搞了个“全天候策略”,核心就是风险平价。

我个人的理解是:传统的资产配置是在“分配资金”,而风险平价是在“分配风险”。这两者有什么区别?我给你举个例子:

传统配置 vs 风险平价

  • 传统60/40组合:股票60%,债券40%。但股票的风险贡献可能占到95%。
  • 风险平价组合:调整权重,让股票和债券的风险贡献各占50%。结果可能是股票20%,债券80%。

嗯,这里要注意:风险平价不是简单的“等权重”,而是“等风险贡献”。每种资产对组合总风险的边际贡献要相等。

我在项目中遇到过一位客户,他坚持认为“债券配80%太保守了”。我给他看了回测数据:2008年金融危机时,60/40组合跌了30%,而风险平价组合只跌了10%左右。他看完就沉默了。

3.2 等风险贡献计算

好,理论讲完了,咱们来点硬核的。等风险贡献(Equal Risk Contribution, ERC)怎么算?

首先,你得知道组合的总风险怎么衡量。通常我们用波动率(标准差)来表示。假设有n个资产,组合的波动率公式是:

σ_p = sqrt(w^T * Σ * w)

其中w是权重向量,Σ是协方差矩阵。

那么,第i个资产的风险贡献(Risk Contribution)定义为:

RC_i = w_i * (Σ * w)_i / σ_p

等风险贡献的条件就是:RC_1 = RC_2 = ... = RC_n

说白了,就是每个资产对组合风险的“贡献值”要一样大。

我的小技巧: 实际计算时,我们通常用数值优化方法,比如牛顿法或者梯度下降。别想着手算,那太折磨人了。

3.3 Python实现风险平价调仓

好了,终于到代码环节了。我习惯用Python的scipy.optimize来做这个优化。下面是我在实际项目中用过的代码框架:

import numpy as np
import pandas as pd
from scipy.optimize import minimize

def risk_parity_weights(cov_matrix):
    """
    计算风险平价权重
    cov_matrix: 协方差矩阵
    """
    n = cov_matrix.shape[0]
    
    # 目标函数:让各资产的风险贡献相等
    def risk_contribution(weights):
        portfolio_vol = np.sqrt(weights @ cov_matrix @ weights)
        rc = weights * (cov_matrix @ weights) / portfolio_vol
        return rc
    
    def objective(weights):
        rc = risk_contribution(weights)
        # 让所有RC的方差最小
        return np.var(rc)
    
    # 约束条件:权重和为1,且都大于0
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    bounds = tuple((0, 1) for _ in range(n))
    
    # 初始权重:等权重
    init_weights = np.array([1/n] * n)
    
    result = minimize(objective, init_weights, 
                      method='SLSQP',
                      bounds=bounds,
                      constraints=constraints)
    
    return result.x

# 示例:3个资产
cov = np.array([
    [0.04, 0.01, 0.005],
    [0.01, 0.09, 0.02],
    [0.005, 0.02, 0.16]
])

weights = risk_parity_weights(cov)
print("风险平价权重:", weights)
print("风险贡献:", risk_contribution(weights))

我曾经踩过的坑: 协方差矩阵的估计非常敏感。如果你用过去60天的滚动窗口,遇到市场突变时,权重会剧烈跳动。我建议至少用252个交易日(一年)的数据,并且加上一些正则化处理。

实际调仓时,我一般会这样做:

  1. 每月初:获取最新协方差矩阵(用过去1年数据)
  2. 计算目标权重:用上面的风险平价函数
  3. 考虑交易成本:如果调仓幅度小于0.5%,我就跳过这次调仓
  4. 执行调仓:用限价单慢慢吃,别一下子砸盘

你想想看,如果每个月都大调特调,交易成本会吃掉你的收益。我个人的经验是:风险平价组合的换手率通常比传统组合低30%-50%,因为它的权重变化相对平滑。

3.4 风险平价的核心逻辑图

下面这张图是我自己画的,帮你理解风险平价的核心流程:

风险平价模型核心逻辑 资产历史收益率数据 步骤1:估计协方差矩阵(Σ) 步骤2:数值优化 → 求解等风险贡献权重 输出:风险平价权重

这张图展示了从数据输入到权重输出的完整流程。核心就两步:估计协方差 → 数值优化。别小看这两步,每一步都有很多细节。

我的建议: 刚开始做风险平价时,先用3-5个资产练手。别一上来就搞几十个资产,那优化会非常慢,而且容易陷入局部最优。

最后说一句:风险平价不是万能的。它在低利率环境下表现很好,但如果所有资产都同时暴跌(比如2020年3月),它也会亏钱。不过,相比传统组合,它的“抗摔打能力”确实强很多。

好了,这一章就到这里。代码部分你可以直接拿去用,但记得根据你的实际数据调整参数。


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