压力测试与情景分析
直觉
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()
小结
- 情景分析:代入极端但合理的资产冲击,算确定的组合损失,不依赖概率;
- 蒙特卡洛压力:把分布的均值/相关性往坏处推,用 Cholesky 生成相关样本,重算尾部;
- VaR 管常态尾部,压力测试管「黑天鹅」——两者缺一不可。