风险价值 (Value at Risk, VaR) 衡量在给定置信水平和持有期下,投资组合可能遭受的最大损失。
条件风险价值 (Conditional VaR, CVaR / Expected Shortfall) 是当损失超过 VaR 阈值时的条件期望损失,更能反映尾部风险。
其中 为组合损失, 为置信水平(通常为 95% 或 99%)。
假设收益服从正态分布或学生 t 分布:
其中 为标准正态分位数。对于 t 分布,用 代替。
优点: 简洁快速,可解析求解 缺点: 正态假设严重低估尾部风险;t 分布的自由度选择有主观性
直接对历史收益排序,取第 百分位:
import numpy as np
from scipy import stats
def historical_var(returns, confidence=0.95):
"""历史模拟 VaR"""
return -np.percentile(returns, (1 - confidence) * 100)
def historical_cvar(returns, confidence=0.95):
"""历史模拟 CVaR (Expected Shortfall)"""
var = historical_var(returns, confidence)
tail_losses = returns[returns <= -var]
if len(tail_losses) == 0:
return var
return -tail_losses.mean()
# 加权历史模拟:给近期数据更高权重
def weighted_historical_var(returns, half_life=30, confidence=0.95):
"""EWMA 加权历史 VaR"""
n = len(returns)
weights = np.exp(-np.log(2) * np.arange(n) / half_life)
weights = weights / weights.sum()
sorted_idx = np.argsort(returns)
cumulative_weights = np.cumsum(weights[sorted_idx])
var_index = np.searchsorted(cumulative_weights, 1 - confidence)
return -returns[sorted_idx[var_index]]
优点: 无需分布假设,保留历史尾部特征 缺点: 依赖样本长度;极端事件可能在历史中不存在
从假设的联合分布中大量抽样:
def monte_carlo_var_cov(S0, mu, cov_matrix, T, N=100000, confidence=0.95):
"""多资产 Monte Carlo VaR(使用协方差矩阵)"""
np.random.seed(42)
# Cholesky 分解生成相关随机变量
L = np.linalg.cholesky(cov_matrix)
z = np.random.randn(N, len(S0))
# 生成相关收益率
corr_returns = z @ L.T
# 对数正态价格模拟
drift = (mu - 0.5 * np.diag(cov_matrix)) * T
vol = np.sqrt(np.diag(cov_matrix) * T)
log_returns = drift + vol * corr_returns
terminal_prices = S0 * np.exp(log_returns)
# 组合损失
weights = np.ones(len(S0)) / len(S0)
portfolio_returns = np.mean((terminal_prices - S0) / S0, axis=1)
var = -np.percentile(portfolio_returns, (1-confidence)*100)
# CVaR: 超过 VaR 的平均损失
tail = portfolio_returns[portfolio_returns <= -var]
cvar = -tail.mean() if len(tail) > 0 else var
return {'VaR': var, 'CVaR': cvar}
# 使用 GARCH 生成条件模拟
def garch_simulated_var(r, delta=1, N_sim=10000):
"""GARCH(1,1) 模拟 VaR"""
from arch import arch_model
# 拟合 GARCH(1,1)
model = arch_model(r, vol='Garch', p=1, q=1)
result = model.fit(disp='off')
# 模拟未来路径
sim = result.simulate(N_sim, delta=delta)
var_simulations = -sim.returns.values
return {
'VaR_95': np.percentile(var_simulations, 5),
'VaR_99': np.percentile(var_simulations, 1),
'CVaR_95': var_simulations[var_simulations <= np.percentile(var_simulations, 5)].mean(),
}
优点: 可处理复杂组合、非线性衍生品和非正态分布 缺点: 计算成本高;模型假设的敏感性(“garbage in, garbage out”)
Artzner et al. (1999) 提出风险度量应满足四个性质:
关键结论: VaR 不满足次可加性(不能保证分散化有益),而 CVaR / Expected Shortfall 满足所有四个性质,是一致风险度量。
Rockafellar & Uryasev (2002) 证明了 CVaR 可以通过凸优化求解:
其中 即为 。这个表达式使得 CVaR 优化可以转化为线性规划问题,非常适合大规模投资组合优化。
| 类型 | 说明 | 最低频率 |
|---|---|---|
| 收益序列 | 日频/分钟级历史收益率 | 日频(200+ 条) |
| 协方差矩阵 | 多资产需要相关性结构 | 日频 |
| 持仓权重 | 各标的在组合中的占比 | 实时更新 |
| 波动率模型 | GARCH 参数(如使用) | 日频 |
| 版本 | 描述 | 适用场景 |
|---|---|---|
| Historical VaR | 纯历史模拟,无参数假设 | 数据充足的成熟市场 |
| EWMA VaR | RiskMetrics 指数加权 | 快速响应波动率变化 |
| GARCH-VaR | GARCH 模型预测下日 σ,再算 VaR | 波动率聚类显著的市场 |
| Monte Carlo CVaR | 模拟全分布精确估计尾部期望 | 复杂组合/衍生品 |
| EWMA GARCH-VaR | RiskMetrics + GARCH 混合估计 | 高精度需求 |
| Regime-aware CVaR | 按 Bull/Bear/Range 分别估计,切换模型 | 跨周期稳健风控 |