3. 风险度量基础:最大回撤、波动率、VaR、CVaR
在量化风控中,收益与风险是一体两面。仅关注收益而忽视风险,模型极易在极端行情下遭遇重大损失。本章系统讲解四个核心风险度量指标:最大回撤、波动率、VaR(在险价值)与CVaR(条件在险价值),并给出 Python 计算示例。
3.1 最大回撤(Maximum Drawdown, MDD)
最大回撤衡量策略从历史峰值回落到后续最低点的最大亏损幅度,是评估策略“抗跌能力”最直观的指标。
- 定义:在选定周期内,任一时点向后推,净值从最高点回落到最低点的最大跌幅。
- 公式:
MDD = max( (Peak - Trough) / Peak ) - 意义:反映策略可能承受的最大资金缩水比例,回撤越大,策略容错性越差。
应用提示:在告警阈值联动中,通常将最大回撤的 1.5 倍或 2 倍设为“强制平仓”或“暂停交易”的触发线。
3.2 波动率(Volatility)
波动率衡量资产收益率的不确定性或离散程度,是风险定价与保证金计算的基础。
- 定义:通常指收益率序列的标准差,年化后用于跨周期比较。
- 公式:
σ = sqrt( (1/(n-1)) * Σ(rᵢ - r̄)² ) - 年化:日波动率 × sqrt(252),周波动率 × sqrt(52)。
| 指标 | 计算周期 | 年化系数 | 典型阈值(年化) |
|---|---|---|---|
| 日波动率 | 每日收益率 | √252 | 15% ~ 30% |
| 周波动率 | 每周收益率 | √52 | 15% ~ 30% |
| 月波动率 | 每月收益率 | √12 | 15% ~ 30% |
3.3 VaR(在险价值)
VaR 回答“在给定置信水平下,未来一段时间内最大可能损失是多少”。
- 定义:在置信水平 α(如 95%、99%)下,持有期 T 内的最大预期损失。
- 参数法(正态分布):
VaR = μ - z_α · σ
其中 z_α 为标准正态分布分位数(95% → 1.645,99% → 2.326)。 - 历史模拟法:直接取历史收益率序列的 α 分位数。
- 蒙特卡洛法:模拟大量路径,取损失分布的分位数。
局限性:VaR 不关心超过分位点的极端损失有多大,即“尾部风险”被忽略。这直接引出了 CVaR。
3.4 CVaR(条件在险价值)
CVaR 又称期望损失(Expected Shortfall),衡量损失超过 VaR 阈值时的平均损失大小。
- 定义:在损失超过 VaR 的条件下,损失的期望值。
- 公式:
CVaR = E[ L | L > VaR ] - 优势:对尾部风险更敏感,满足次可加性(Subadditivity),是一致性风险度量。
联动场景:在告警阈值设计中,CVaR 更适合作为“紧急熔断”的触发指标,因为它直接量化了极端行情下的平均亏损。
3.5 四种风险度量对比
| 指标 | 关注点 | 尾部敏感性 | 计算复杂度 | 告警适用场景 |
|---|---|---|---|---|
| 最大回撤 | 历史最大亏损幅度 | 低(仅一个极值点) | 低 | 策略暂停、风控硬止损 |
| 波动率 | 收益率的离散程度 | 低(对称假设) | 低 | 保证金调整、杠杆限制 |
| VaR | 给定置信度下的最大损失 | 中(忽略尾部) | 中 | 日常风险限额、预警 |
| CVaR | 尾部损失的期望值 | 高(直接度量尾部) | 中高 | 紧急熔断、极端行情应对 |
3.6 Python 计算示例
以下代码演示如何基于收益率序列计算上述四个指标。假设已获取日收益率数据 returns(pandas Series 或 numpy array)。
import numpy as np
import pandas as pd
def compute_risk_metrics(returns, confidence=0.95):
"""
计算最大回撤、年化波动率、VaR、CVaR
:param returns: 日收益率序列 (Series or array)
:param confidence: VaR/CVaR 置信水平,默认 95%
:return: dict 包含四个指标
"""
# 1. 最大回撤
cum_returns = (1 + returns).cumprod()
running_max = cum_returns.cummax()
drawdown = (cum_returns - running_max) / running_max
max_drawdown = drawdown.min()
# 2. 年化波动率
daily_vol = returns.std()
annual_vol = daily_vol * np.sqrt(252)
# 3. VaR(历史模拟法)
var = np.percentile(returns, (1 - confidence) * 100)
# 4. CVaR(条件在险价值)
tail_losses = returns[returns <= var]
cvar = tail_losses.mean() if len(tail_losses) > 0 else var
return {
'max_drawdown': round(max_drawdown, 4),
'annual_volatility': round(annual_vol, 4),
'VaR_95': round(var, 4),
'CVaR_95': round(cvar, 4)
}
# 示例用法
# np.random.seed(42)
# sample_returns = np.random.normal(0.001, 0.02, 1000)
# metrics = compute_risk_metrics(sample_returns)
# print(metrics)
代码说明:
- 最大回撤通过累计净值的滚动最高点计算,结果通常为负值(亏损)。
- VaR 使用历史模拟法,直接取收益率分位数,简单直观。
- CVaR 取所有超过 VaR 的损失样本的平均值,对尾部更敏感。
- 实际生产环境中建议使用滑动窗口计算,并配合告警阈值联动。
- 最大回撤通过累计净值的滚动最高点计算,结果通常为负值(亏损)。
- VaR 使用历史模拟法,直接取收益率分位数,简单直观。
- CVaR 取所有超过 VaR 的损失样本的平均值,对尾部更敏感。
- 实际生产环境中建议使用滑动窗口计算,并配合告警阈值联动。
3.7 告警阈值联动参考
在《模型收益评估与告警阈值联动教程》中,上述指标可直接映射为告警规则:
- 最大回撤 > 20% → 触发“策略暂停”告警。
- 年化波动率 > 40% → 触发“杠杆限制”告警。
- VaR_95 亏损 > 5% → 触发“风险预警”通知。
- CVaR_95 亏损 > 8% → 触发“紧急熔断”操作。