第1章:风险度量基础——方差、标准差、协方差矩阵、VaR、CVaR的概念与计算
各位好,我是老张。今天咱们聊聊风险度量。
做组合优化,说白了就是跟风险打交道。你想想看,如果所有资产都稳赚不赔,那还优化个啥?直接全仓干就完了。但现实是,市场有波动,资产会跌,甚至可能归零。所以,我们得先搞清楚:风险到底是什么?怎么量化它?
我个人习惯把风险度量工具分成两类:传统统计量和尾部风险指标。前者告诉你“波动有多大”,后者告诉你“最坏情况有多糟”。这两类工具,咱们一个一个过。
1.1 方差与标准差:最朴素的波动度量
方差,是所有风险度量的起点。它的逻辑很简单:收益偏离平均水平的程度。
数学上,对于一组收益率 \( r_1, r_2, ..., r_n \),样本方差的计算公式是:
σ² = (1/(n-1)) * Σ (r_i - r̄)²
其中 \( r̄ \) 是平均收益率。标准差就是方差的平方根:\( σ = \sqrt{σ²} \)。
我在项目中遇到过一件事:有个同事拿方差直接比较两个资产的风险,结果发现一个资产方差很大,但它是高频交易策略,日内波动大但收盘基本稳定。另一个资产方差小,但偶尔会暴跌。你看,方差只告诉你“平均波动”,它不区分向上波动和向下波动。所以,方差适合作为初步筛选,但别迷信它。
1.2 协方差矩阵:资产之间的“关系网”
单个资产的风险好算,但组合的风险呢?这就得靠协方差矩阵了。
协方差衡量两个资产收益率的同向变动程度。如果两个资产经常一起涨一起跌,协方差为正;如果一个涨一个跌,协方差为负。
假设我们有 \( m \) 个资产,协方差矩阵 \( \Sigma \) 是一个 \( m \times m \) 的对称矩阵:
Σ = [
[σ₁², σ₁₂, σ₁₃, ...],
[σ₂₁, σ₂², σ₂₃, ...],
...
]
其中对角线是各资产的方差,非对角线是两两之间的协方差。
组合的方差计算公式是:
σ²_p = w^T * Σ * w
其中 \( w \) 是权重向量。这个公式,是马科维茨均值-方差模型的基石。
嗯,这里要注意:协方差矩阵的估计质量,直接决定优化结果的好坏。我曾经用60天的滚动窗口估计协方差矩阵,结果优化出来的权重每天都在剧烈变化,根本没法实盘。后来改用指数加权移动平均(EWMA),才稳定下来。
1.3 VaR:风险价值——最坏情况下的“底线”
方差告诉你波动,但没告诉你“亏多少”。VaR(Value at Risk)就是回答这个问题的。
VaR的定义:在给定的置信水平(比如95%)和持有期(比如1天)下,最大可能损失。换句话说,100天里,只有5天的损失会超过这个值。
计算VaR有三种常见方法:
- 参数法(方差-协方差法):假设收益率服从正态分布,VaR = - (μ + z_α * σ)。其中z_α是标准正态分布的分位数(95%置信水平下,z=1.645)。
- 历史模拟法:直接用历史收益率排序,取第5%分位数的损失值。
- 蒙特卡洛模拟法:假设收益率服从某种分布,随机生成大量路径,取分位数。
我个人最常用的是历史模拟法。为什么?因为它不需要假设分布,简单粗暴。但缺点也很明显:历史不会简单重复。2008年金融危机之前,用历史模拟法算出来的VaR,根本预测不到雷曼兄弟倒闭那天的损失。
1.4 CVaR:条件风险价值——尾部风险的“放大镜”
CVaR(Conditional VaR),也叫Expected Shortfall(ES),就是为了弥补VaR的缺陷而生的。
CVaR的定义:在损失超过VaR的条件下,平均损失是多少。比如,95%的VaR是-10%,那么CVaR就是“所有损失超过-10%的那些天,平均损失是多少”。
数学上,CVaR = E[ L | L > VaR_α ],其中L是损失。
举个例子:假设你有100天的收益率数据,95%的VaR是第5大的损失(即-8%)。那么CVaR就是那5天损失的平均值,假设是-12%。这意味着:一旦触发尾部风险,平均要亏12%。
我在做量化对冲策略时,曾经用VaR做风控,结果遇到一次小概率的闪崩,VaR没预警,但CVaR早就亮了红灯。从那以后,我所有的组合优化模型,约束条件里必加CVaR。
scipy.optimize.linprog或者cvxpy都能轻松实现。我习惯把CVaR作为目标函数的一部分,而不是硬约束——这样优化出来的组合,尾部风险天然就小。
1.5 知识体系总览
下面这张图,是我自己梳理的风险度量工具关系图。你看一眼,就能明白它们之间的逻辑:
1.6 实战:用Python计算这些指标
光说不练假把式。下面这段代码,是我平时做风险分析的标准模板。你直接拿去用,改改数据路径就行。
import numpy as np
import pandas as pd
# 模拟收益率数据(5个资产,1000个交易日)
np.random.seed(42)
returns = np.random.randn(1000, 5) * 0.02 # 日收益率,标准差2%
# 1. 方差与标准差
var = np.var(returns, axis=0, ddof=1)
std = np.std(returns, axis=0, ddof=1)
print("方差:", var)
print("标准差:", std)
# 2. 协方差矩阵
cov_matrix = np.cov(returns, rowvar=False)
print("协方差矩阵:\n", cov_matrix)
# 3. VaR(历史模拟法,95%置信水平)
def historical_var(returns, alpha=0.95):
sorted_returns = np.sort(returns, axis=0)
index = int((1 - alpha) * len(sorted_returns))
return sorted_returns[index]
var_95 = historical_var(returns, alpha=0.95)
print("95% VaR(每个资产):", var_95)
# 4. CVaR(历史模拟法,95%置信水平)
def historical_cvar(returns, alpha=0.95):
sorted_returns = np.sort(returns, axis=0)
index = int((1 - alpha) * len(sorted_returns))
tail_losses = sorted_returns[:index]
return np.mean(tail_losses, axis=0)
cvar_95 = historical_cvar(returns, alpha=0.95)
print("95% CVaR(每个资产):", cvar_95)
1.7 我的选择建议
说了这么多,到底该用哪个?我的经验是:
- 日常监控:用标准差和VaR就够了。简单、直观、好解释。
- 组合优化:必须用CVaR。因为优化过程会放大尾部风险,只用VaR会得到“看似安全实则危险”的组合。
- 多资产配置:协方差矩阵是核心。但记得做收缩估计或因子模型,别直接用原始数据。
好了,这一章就到这里。风险度量是组合优化的地基,地基不稳,楼盖得再高也是危楼。下一章,咱们聊聊怎么把这些指标用到优化模型里。