4、压力测试指标计算:VaR、CVaR、最大回撤与夏普比率在压力期表现

好,咱们进入正题。压力测试跑完了,数据堆了一堆,接下来干什么?算指标。说白了,你得用几个硬核数字来回答一个问题:这套做市策略在极端行情下,到底扛不扛得住?

我个人习惯,压力测试指标主要看四个:VaR、CVaR、最大回撤、夏普比率。它们各自盯着风险的不同侧面。今天咱们一个一个拆开讲,顺便聊聊我在实战中踩过的坑。

4.1 在险价值(VaR)—— 最坏情况下的“底线”

VaR 是什么?简单说就是:在给定的置信水平和持有期内,资产组合可能的最大损失。比如“95%置信度下,日 VaR 是 50 万”,意思就是只有 5% 的概率,一天亏损会超过 50 万。

计算 VaR 的方法有好几种。做市场景下,我推荐用历史模拟法。为什么?因为它不需要假设收益率服从正态分布。你想想看,压力期哪有什么正态分布?全是肥尾。

核心公式(历史模拟法):
将历史损益序列按升序排列,取第 (1-α)×N 个分位数对应的损益值。

代码实现也很直接:

import numpy as np

def calculate_var(returns, confidence_level=0.95):
    """
    计算 VaR(历史模拟法)
    :param returns: 收益率序列(numpy array)
    :param confidence_level: 置信水平,默认 95%
    :return: VaR 值(正数表示损失)
    """
    sorted_returns = np.sort(returns)
    index = int((1 - confidence_level) * len(sorted_returns))
    var = -sorted_returns[index]  # 取负值,方便理解
    return var

# 示例:假设压力期收益率数据
stress_returns = np.random.normal(-0.002, 0.03, 1000)  # 模拟数据
var_95 = calculate_var(stress_returns, 0.95)
print(f"95% VaR: {var_95:.4f}")
我的经验: 别只算 95% 的 VaR。压力测试场景下,我建议同时算 99% 和 99.5% 的 VaR。为什么?因为做市商最怕的就是那 0.5% 的极端行情。我在项目中遇到过,95% VaR 看起来还行,但 99.5% VaR 直接翻了三倍——这才是真正的风险敞口。

4.2 条件在险价值(CVaR)—— 亏起来到底有多疼?

VaR 有个致命缺陷:它只告诉你“最坏情况”的边界,但没告诉你一旦突破这个边界,损失会有多惨。这就是 CVaR 要解决的问题。

CVaR,也叫期望损失(Expected Shortfall),衡量的是超过 VaR 的那些损失的均值。说白了就是:当坏日子真的来了,平均每天亏多少?

核心公式:
CVaR = E[ Loss | Loss > VaR ]
即所有超过 VaR 的损失的算术平均值。
def calculate_cvar(returns, confidence_level=0.95):
    """
    计算 CVaR(条件在险价值)
    """
    sorted_returns = np.sort(returns)
    index = int((1 - confidence_level) * len(sorted_returns))
    # 取所有超过 VaR 的损失
    tail_losses = -sorted_returns[:index]
    cvar = np.mean(tail_losses)
    return cvar

cvar_95 = calculate_cvar(stress_returns, 0.95)
print(f"95% CVaR: {cvar_95:.4f}")

我习惯把 VaR 和 CVaR 放在一起看。如果两者差距很大,说明尾部风险很重。举个例子:VaR=50万,CVaR=120万,这意味着一旦触发 VaR,平均亏损会达到 120 万——这个信息对做市商的资金准备至关重要。

注意: 压力期数据量通常不大(可能只有几百个样本点)。计算 CVaR 时,尾部样本可能只有十几个甚至几个。这时候 CVaR 的统计稳定性会下降。我的做法是:用 Bootstrap 重采样,生成 1000 组样本,取 CVaR 的中位数作为最终值。

4.3 最大回撤(Max Drawdown)—— 你能承受多久的浮亏?

最大回撤,衡量的是从净值峰值到后续谷底的最大跌幅。做市商尤其关注这个指标,因为它直接关系到你的资金占用和风控线。

压力期最大回撤往往比正常时期大 3-5 倍。我记得有一次做 BTC 永续合约的做市策略,正常时期最大回撤只有 2%,但 3.12 暴跌那天,最大回撤直接飙到 18%。

def calculate_max_drawdown(equity_curve):
    """
    计算最大回撤
    :param equity_curve: 净值曲线(numpy array)
    :return: 最大回撤(百分比,正数)
    """
    peak = np.maximum.accumulate(equity_curve)
    drawdown = (peak - equity_curve) / peak
    max_dd = np.max(drawdown)
    return max_dd

# 模拟净值曲线
np.random.seed(42)
equity = 100 * np.exp(np.cumsum(np.random.normal(0.0005, 0.02, 500)))
max_dd = calculate_max_drawdown(equity)
print(f"最大回撤: {max_dd:.2%}")
避坑指南: 我曾经犯过一个错误——只看整体最大回撤,忽略了回撤的持续时间。后来发现,有些策略虽然最大回撤只有 10%,但回撤持续了 3 个月,这对做市商来说是致命的(资金被套牢,无法开新仓)。所以我现在会同时计算两个指标:最大回撤深度 + 回撤恢复天数。

4.4 夏普比率在压力期的“失真”问题

夏普比率 = (策略收益率 - 无风险利率) / 收益率标准差。正常时期,这个指标很好用。但压力期,它可能会骗人。

为什么会这样?因为夏普比率假设收益率是正态分布,且风险用标准差衡量就够了。但压力期有两个问题:

  • 肥尾效应: 极端损失出现的概率远高于正态分布假设。夏普比率会低估尾部风险。
  • 波动率聚集: 压力期波动率会突然飙升,导致分母变大,夏普比率反而可能下降,掩盖了策略的真实风险调整后收益。

我个人的做法是:压力期不要只看夏普比率,而是看调整后的夏普比率,或者用 Sortino 比率替代(只考虑下行波动率)。

def calculate_sortino_ratio(returns, risk_free_rate=0.02):
    """
    计算 Sortino 比率(只考虑下行风险)
    """
    excess_returns = returns - risk_free_rate / 252  # 日化
    downside_returns = returns[returns < 0]
    downside_std = np.std(downside_returns)
    sortino = np.mean(excess_returns) / downside_std * np.sqrt(252)  # 年化
    return sortino

sortino = calculate_sortino_ratio(stress_returns)
print(f"压力期 Sortino 比率: {sortino:.2f}")
核心观点: 压力期夏普比率低于 0.5 的做市策略,基本可以判定为不合格。但要注意,如果夏普比率是负的,但 Sortino 比率是正的,说明策略的亏损主要来自正常波动,而不是尾部风险——这反而是一个积极信号。

4.5 四个指标的综合解读框架

光算单个指标没用,你得把它们串起来看。我总结了一个四象限判断法:

指标组合 解读 应对建议
VaR 低 + CVaR 低 + 回撤小 策略在压力期表现稳健 可以适当放大仓位
VaR 低 + CVaR 高 + 回撤大 尾部风险集中,平时没事,一有事就是大事 必须加尾部对冲(如深度虚值期权)
VaR 高 + CVaR 高 + 回撤大 策略不适合当前市场环境 立即降低仓位,重新评估参数
VaR 高 + CVaR 低 + 回撤小 少见,说明损失分布很均匀,没有极端值 检查数据是否有误,或者策略是否过度拟合

嗯,这里要注意:压力测试的指标不是算一次就完事了。我建议每季度重新跑一次压力测试,更新参数。因为市场结构在变,去年的压力场景,今年可能就不适用了。

4.6 本章知识体系总览

下面这张图,是我自己画的一个知识结构图,帮你把四个指标的关系理清楚:

压力测试指标计算知识体系 压力测试指标 VaR(在险价值) 最大可能损失边界 CVaR(条件在险价值) 尾部损失均值 最大回撤 净值峰值到谷底跌幅 夏普比率 风险调整收益 历史模拟法 参数法 / 蒙特卡洛 尾部样本均值 Bootstrap 重采样 累计峰值法 回撤恢复天数 Sortino 比率 下行波动率调整 四象限综合判断框架 VaR + CVaR + 最大回撤 + 夏普比率 联合解读 压力期指标 ≠ 正常期指标,需单独计算并对比 建议每季度更新一次压力测试参数

最后说一句:指标只是工具,不是目的。真正重要的是,通过这些指标你能做出什么决策。是加仓、减仓、还是加对冲?这才是压力测试的价值所在。


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