2、风险度量基础:波动率、协方差矩阵、边际风险贡献(MRC)、风险贡献(RC)的定义与计算

各位同学,咱们今天聊点实在的。做风险预算,你首先得知道风险长什么样,怎么量它。说白了,就是得有一把尺子。

这把尺子,就是波动率、协方差矩阵,还有边际风险贡献和风险贡献。这四个概念,是风险预算的基石。我在做组合优化的时候,经常发现很多人只盯着波动率看,忽略了协方差结构,结果组合一遇到市场异动就崩了。嗯,咱们今天就把这几个概念彻底捋清楚。

2.1 波动率:风险的“体温计”

波动率,大家都很熟悉。它衡量的是资产收益率的离散程度。我个人习惯用年化波动率,因为这样不同时间频率的数据可以放在一起比较。

计算方式很简单:

# 假设我们有一组日收益率数据
import numpy as np

returns = np.array([0.01, -0.02, 0.015, -0.005, 0.008])
# 日波动率
daily_vol = np.std(returns, ddof=1)
# 年化波动率(假设252个交易日)
annual_vol = daily_vol * np.sqrt(252)

print(f"日波动率: {daily_vol:.4f}")
print(f"年化波动率: {annual_vol:.4f}")

这里有个坑,我必须要提醒你。用 np.std 时,默认是除以 N 的,但样本标准差应该除以 N-1。我曾经因为这个细节,在回测报告里算错了夏普比率,被风控部门追着问了一下午。所以,ddof=1 这个参数,一定要记住。

避坑指南: 我曾经在计算多资产组合波动率时,直接用日波动率乘以 sqrt(252) 来年化。但如果你用的是周数据或月数据,乘的因子是不一样的。周数据是 sqrt(52),月数据是 sqrt(12)。别搞混了。

2.2 协方差矩阵:资产之间的“关系网”

波动率只告诉你单个资产的风险。但组合的风险,还取决于资产之间的联动关系。协方差矩阵,就是描述这种关系的。

你想想看,如果两个资产总是同涨同跌,那组合的风险并不会因为分散化而降低多少。但如果它们走势相反,那组合的波动就会被平滑掉。

协方差矩阵的计算:

# 假设有三只股票的日收益率数据
import pandas as pd

data = {
    '股票A': [0.01, -0.02, 0.015, -0.005, 0.008],
    '股票B': [0.005, -0.01, 0.02, -0.01, 0.012],
    '股票C': [-0.005, 0.01, -0.01, 0.005, -0.008]
}
df = pd.DataFrame(data)

# 计算协方差矩阵
cov_matrix = df.cov()
print(cov_matrix)

输出结果大概长这样:

股票A 股票B 股票C
股票A 0.00015 0.00010 -0.00008
股票B 0.00010 0.00018 -0.00006
股票C -0.00008 -0.00006 0.00012

对角线是方差,也就是波动率的平方。非对角线是协方差。你看,股票A和股票C的协方差是负数,说明它们有对冲效果。

我的经验: 在实际项目中,我建议用指数加权移动平均(EWMA)来计算协方差矩阵,而不是简单的历史平均。因为市场环境在变,近期的数据比远期的数据更有参考价值。我常用的衰减因子是0.94,这是RiskMetrics的标准做法。

2.3 边际风险贡献(MRC):每个资产对组合风险的“增量影响”

好了,现在我们有了组合的波动率(通过协方差矩阵和权重计算),但问题来了:组合的总风险,到底是谁贡献的?

边际风险贡献,就是回答这个问题的。它衡量的是:如果我把某个资产的权重增加一点点,组合的总风险会变化多少。

数学上,MRC 是组合风险对权重的偏导数:

# 计算边际风险贡献
import numpy as np

# 假设权重向量
weights = np.array([0.4, 0.3, 0.3])
# 协方差矩阵
cov_matrix = np.array([
    [0.00015, 0.00010, -0.00008],
    [0.00010, 0.00018, -0.00006],
    [-0.00008, -0.00006, 0.00012]
])

# 组合方差
portfolio_variance = weights.T @ cov_matrix @ weights
# 组合波动率
portfolio_vol = np.sqrt(portfolio_variance)

# 边际风险贡献
mrc = (cov_matrix @ weights) / portfolio_vol
print(f"边际风险贡献: {mrc}")

输出的 MRC 值,可以理解为:每增加1%的权重,组合波动率会变化多少。正值表示增加风险,负值表示降低风险。

为什么会这样?因为 MRC 考虑了资产自身的波动,也考虑了它与其他资产的相关性。如果一个资产与其他资产负相关,它的 MRC 可能是负的——增加它的权重,反而能降低组合风险。

2.4 风险贡献(RC):每个资产对组合风险的“实际贡献”

MRC 是边际概念,而风险贡献(RC)是总量概念。它告诉你:在组合的总风险中,每个资产到底占了多少份额。

计算很简单:RC = 权重 × MRC

# 计算风险贡献
rc = weights * mrc
# 风险贡献之和应该等于组合波动率
total_rc = np.sum(rc)

print(f"风险贡献: {rc}")
print(f"风险贡献之和: {total_rc:.6f}")
print(f"组合波动率: {portfolio_vol:.6f}")

你会发现,所有资产的风险贡献加起来,正好等于组合的波动率。这是一个非常重要的性质,叫做“风险分解的可加性”。

核心要点: 风险预算的本质,就是让每个资产的风险贡献(RC)等于我们预设的目标。比如,你想让股票和债券各承担50%的风险,那就调整权重,直到它们的 RC 相等。

2.5 知识体系总览

为了让你更直观地理解这几个概念之间的关系,我画了一张图:

风险度量基础:知识体系 波动率 单个资产的风险 协方差矩阵 资产间的联动关系 组合波动率 总风险度量 权重 权重 边际风险贡献 增量影响 风险贡献 实际贡献份额 偏导数 × 权重 可加性 核心逻辑:波动率 → 组合波动率 → MRC → RC → 风险预算

这张图把整个逻辑串起来了。从单个资产的波动率,到资产间的协方差矩阵,再到组合波动率,然后通过偏导数得到 MRC,最后乘以权重得到 RC。风险预算,就是在这个链条的末端做文章。

一个小技巧: 在实际做风险预算时,我通常不会直接计算 MRC 和 RC 的解析解,而是用数值方法。比如,把某个资产的权重微调 0.1%,然后重新计算组合波动率,看变化了多少。这样虽然慢一点,但不容易出错,尤其是在协方差矩阵接近奇异的时候。

好了,这一节的内容就到这里。波动率、协方差矩阵、MRC、RC,这四个概念是风险预算的“四件套”。下一节,我们会用这些工具,真正开始做风险预算的分配。嗯,到时候你会看到,这些数学公式到底是怎么变成真金白银的。

专注资料整理