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 尾部损失的期望值 高(直接度量尾部) 中高 紧急熔断、极端行情应对
风险度量四维关系图 最大回撤 历史最大亏损 波动率 收益离散程度 VaR 分位数损失 CVaR 尾部期望损失 度量维度 回撤:极端点 波动:整体离散 尾部风险递进 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 的损失样本的平均值,对尾部更敏感。
- 实际生产环境中建议使用滑动窗口计算,并配合告警阈值联动。

3.7 告警阈值联动参考

在《模型收益评估与告警阈值联动教程》中,上述指标可直接映射为告警规则:

  • 最大回撤 > 20% → 触发“策略暂停”告警。
  • 年化波动率 > 40% → 触发“杠杆限制”告警。
  • VaR_95 亏损 > 5% → 触发“风险预警”通知。
  • CVaR_95 亏损 > 8% → 触发“紧急熔断”操作。