压力测试与情景分析
:::info 学习目标 你将能设计历史、假设与反向压力情景,处理相关性和流动性恶化,并把损失映射到可执行风险限额。 :::
直觉
VaR/CVaR 描述的是「常态分布的尾部」,但真正让机构破产的,是常态之外的极端事件——2008、2020、2022 这类相关性突然趋同、所有资产一起跌的危机。压力测试故意跳出历史分布,直接问:「如果 2008 重演,我会亏多少?」「如果股债同跌、商品暴涨,组合扛得住吗?」它分两类:情景分析(代入一组极端但合理的资产冲击,算确定损失)和蒙特卡洛压力(把分布的均值/相关性往坏处推,重算尾部风险)。
情景损失与压力分布
情景分析:给定一组资产冲击 ,组合损失直接为:
蒙特卡洛压力:用历史数据估均值 与协方差 ,做 Cholesky 分解 生成相关随机样本 ;压力版本把均值压低()或抬高相关性,重算 CVaR。
「人话」解释:为什么要「跳出历史分布」?
VaR 用的是「过去发生过的最坏 5%」。可危机的特征恰恰是「过去没怎么发生、但一旦发生就致命」——平时股债负相关(债券能对冲股票),危机时相关性翻正(股债齐跌),对冲瞬间失效。 情景分析就是「人为设定一个噩梦剧本」(比如股 −34%、债 −2%、商品 −25%),直接算组合在这个剧本下亏多少,不依赖概率分布;蒙特卡洛压力则是「把分布往坏处拧」(均值下移、波动放大、相关性趋同),看尾部风险膨胀到什么程度。两者互补:一个定方向,一个定概率尾部。
可运行案例:情景损失 + 蒙特卡洛压力
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('/data/multi_asset_daily.csv', parse_dates=['date']).set_index('date')
assets = list(df.columns); w = np.array([0.25]*4)
rets = df.pct_change().dropna()
# 1) 情景分析: 代入极端资产冲击, 算确定损失
scenarios = {
'Risk-off(2020式)': {'equity': -0.34, 'bond': +0.03, 'commodity': -0.25, 'reit': -0.20},
'通胀冲击(2022式)': {'equity': -0.12, 'bond': -0.10, 'commodity': +0.20, 'reit': -0.08},
'股债齐跌(相关性翻正)': {'equity': -0.15, 'bond': -0.06, 'commodity': +0.05, 'reit': -0.10},
}
print("情景损失(组合):")
for name, sh in scenarios.items():
loss = -sum(w[i]*sh[assets[i]] for i in range(4))
print(f" {name:18}: {loss:+.2%}")
# 2) 蒙特卡洛压力: 拟合均值/协方差, Cholesky 生成相关样本
mu = rets.mean().values; cov = rets.cov().values
Lc = np.linalg.cholesky(cov)
rng = np.random.default_rng(0); N = 100000
def sim(mean_vec):
z = rng.standard_normal((N, 4))
return (z @ Lc.T + mean_vec) @ w
base = sim(mu)
stressed = sim(mu - 2*np.sqrt(np.diag(cov))) # 各资产均值压低 2σ
def vc(x, a=0.05):
q = np.quantile(x, a); return -q, -x[x <= q].mean()
b_var, b_cvar = vc(base); s_var, s_cvar = vc(stressed)
print(f"\n基准 1日 VaR95={b_var:.2%} CVaR95={b_cvar:.2%}")
print(f"压力 1日 VaR95={s_var:.2%} CVaR95={s_cvar:.2%} ← 均值下移, 尾部膨胀")
plt.figure(figsize=(9, 3.4))
plt.hist(base, bins=80, alpha=0.5, label='基准', color='steelblue')
plt.hist(stressed, bins=80, alpha=0.5, label='压力(均值-2σ)', color='crimson')
plt.axvline(-b_cvar, color='navy', ls='--', lw=1.4); plt.axvline(-s_cvar, color='darkred', ls='--', lw=1.4)
plt.title('组合日收益: 基准 vs 压力分布'); plt.xlabel('日收益'); plt.legend(fontsize=9)
plt.tight_layout(); plt.show()
情景治理
压力测试不是把均值随意减两倍标准差。每个情景应写明叙事、冲击期限、资产映射、相关性、波动、流动性和二阶效应,并由独立人员挑战。线性权重只适合小变动;期权、杠杆和保证金会产生非线性与强制去杠杆。还应做反向压力:从不可承受损失倒推需要什么市场组合。
实践与延伸
- 设计一个流动性减半且价差翻倍的情景,把退出成本加入损失。
- 求令组合亏损 20% 的最小冲击组合,形成反向压力测试。
延伸阅读:Basel stress testing principles;CCAR 情景设计公开方法。
小结
- 情景分析:代入极端但合理的资产冲击,算确定的组合损失,不依赖概率;
- 蒙特卡洛压力:把分布的均值/相关性往坏处推,用 Cholesky 生成相关样本,重算尾部;
- VaR 管常态尾部,压力测试管「黑天鹅」——两者缺一不可。
章末自测
1. 关于本章主题,哪项说法更准确?