halo 的技术博客

返回

引言#

2008年金融危机、2015年A股股灾、2020年疫情暴跌…每一次市场崩盘都在提醒量化交易者:风险管理比收益挖掘更重要

VaR(Value at Risk,风险价值)和CVaR(Conditional Value at Risk,条件风险价值)是量化风险管理的核心工具。本文将深入探讨它们的计算方法、实盘应用和局限性。

VaR:风险管理的基石#

什么是VaR?#

定义:在给定置信水平下,某一金融资产或组合在未来特定时间内的最大可能损失。

例子

  • “该组合在95%置信水平下,1日VaR为-5%”
  • 含义:有95%的把握,明天该组合的损失不会超过5%

VaR的三大计算方法#

1. 历史模拟法(Historical Simulation)#

原理:直接使用历史收益率数据,假设未来与过去分布相同。

计算步骤

  1. 收集过去N天(如250天)的收益率数据
  2. 按收益率从小到大排序
  3. 找到对应置信水平的分位数

代码示例

优点

  • 简单直观,无需假设分布
  • 能捕捉历史极端事件

缺点

  • 假设未来与过去相同(平稳性假设)
  • 对数据长度敏感(需要足够长的历史数据)
  • 无法预测历史未出现的风险

VaR计算方法对比

2. 参数法(方差-协方差法)#

原理:假设收益率服从特定分布(如正态分布),利用均值和方差计算VaR。

计算公式

VaR(α) = μ - z_α * σ * √(Δt)
plaintext

其中:

  • μ:平均收益率
  • σ:收益率标准差
  • z_α:标准正态分布的α分位数
  • Δt:持有期

代码示例

from scipy import stats

def parametric_var(returns, confidence=0.95, holding_period=1):
    """
    参数法计算VaR(假设正态分布)
    """
    mu = returns.mean()
    sigma = returns.std()
    z_score = stats.norm.ppf(1 - confidence)
    var = mu - z_score * sigma * np.sqrt(holding_period)
    return var

var_normal = parametric_var(returns, 0.95)
print(f"参数法95% VaR (正态分布): {var_normal:.2%}")
python

优点

  • 计算速度快
  • 易于理解和解释

缺点

  • 假设正态分布,忽略肥尾效应
  • 对均值和方差估计敏感

改进:使用t分布或偏t分布替代正态分布

from scipy.stats import t

def tdist_var(returns, confidence=0.95, df=5):
    """
    使用t分布计算VaR(捕捉肥尾)
    """
    mu = returns.mean()
    sigma = returns.std()
    t_score = t.ppf(1 - confidence, df)
    var = mu - t_score * sigma
    return var
python

3. 蒙特卡洛模拟法(Monte Carlo Simulation)#

原理:通过随机模拟大量可能的未来场景,计算VaR。

计算步骤

  1. 估计收益率的随机过程(如几何布朗运动)
  2. 模拟大量(如10,000次)未来路径
  3. 计算模拟收益率的分位数

代码示例

优点

  • 灵活,可以模拟复杂分布
  • 能处理非线性衍生品

缺点

  • 计算成本高
  • 依赖模型假设

蒙特卡洛模拟示意图

CVaR:更稳健的风险度量#

为什么需要CVaR?#

VaR有一个重大缺陷:不满足次可加性(Subadditivity),即两个组合并后的VaR可能大于各自VaR之和,这违背了分散化降低风险的直觉。

CVaR(期望损失):在损失超过VaR的条件下的平均损失,满足一致性风险度量公理。

CVaR的计算方法#

1. 历史模拟法计算CVaR#

def historical_cvar(returns, confidence=0.95):
    """
    历史模拟法计算CVaR
    """
    var = np.percentile(returns, (1 - confidence) * 100)
    cvar = returns[returns <= var].mean()
    return cvar

cvar_95 = historical_cvar(returns, 0.95)
print(f"95% CVaR: {cvar_95:.2%}")
python

2. 参数法计算CVaR(正态分布)#

对于正态分布,CVaR有解析解:

CVaR(α) = μ - σ * φ(z_α) / (1 - α)
plaintext

其中φ(·)是标准正态密度函数。

from scipy.stats import norm

def parametric_cvar_normal(returns, confidence=0.95):
    """
    参数法计算CVaR(假设正态分布)
    """
    mu = returns.mean()
    sigma = returns.std()
    z_score = norm.ppf(1 - confidence)
    phi_z = norm.pdf(z_score)
    cvar = mu - sigma * phi_z / (1 - confidence)
    return cvar
python

VaR vs CVaR:该用哪个?#

特性VaRCVaR
直观性✅ 易于理解❌ 较抽象
次可加性❌ 不满足✅ 满足
尾部风险❌ 忽略尾部✅ 捕捉尾部
计算复杂度✅ 简单❌ 较复杂
监管接受度✅ 广泛接受⚠️ 逐渐增加

建议

  • 对外报告:使用VaR(监管和投资者更熟悉)
  • 内部风控:使用CVaR(更稳健的风险度量)

VaR与CVaR对比

实盘应用:如何设置止损?#

1. 基于VaR的动态止损#

思路:根据当前市场波动率动态调整止损线。

计算方法

def dynamic_stop_loss(returns, confidence=0.95, multiplier=1.5):
    """
    基于VaR的动态止损
    multiplier: VaR倍数,用于设置更保守的止损线
    """
    rolling_var = returns.rolling(window=20).apply(
        lambda x: np.percentile(x, (1 - confidence) * 100)
    )
    stop_loss = rolling_var * multiplier
    return stop_loss

# 示例:如果20日95% VaR为-3%,设置1.5倍止损线为-4.5%
python

优点

  • 适应市场波动率变化
  • 高波动期间止损线更宽,避免被噪音止损

2. 组合层面的风险管理#

问题:单个资产的VaR之和 ≠ 组合VaR(因为相关性)

解决方法:计算组合VaR

3. 风险预算分配#

思路:将总风险(VaR或CVaR)分配给各个资产,进行风险平价配置。

压力测试:当VaR失效时#

为什么需要压力测试?#

VaR基于历史数据,无法预测历史未发生的极端事件,如:

  • 黑天鹅事件(2020年3月疫情暴跌)
  • 流动性枯竭(2015年A股熔断)
  • 相关性崩溃(危机时所有资产同向变动)

压力测试的场景设计#

1. 历史场景重演#

方法:将历史极端事件(如2008年金融危机)的收益率直接应用于当前组合。

def historical_stress_test(portfolio, crisis_returns):
    """
    历史场景压力测试
    crisis_returns: 危机期间的收益率(如2008年9月-2009年3月)
    """
    stress_loss = (portfolio['weight'] * crisis_returns).sum()
    return stress_loss

# 示例:2008年金融危机期间,某股票组合损失-40%
python

2. 假设场景(Hypothetical Scenarios)#

方法:设计可能的极端场景,如:

  • 利率突然上升200bp
  • 人民币贬值10%
  • 原油价格暴跌50%
def hypothetical_stress_test(portfolio, scenario_shocks):
    """
    假设场景压力测试
    scenario_shocks: 各资产的冲击幅度(字典)
    """
    stress_loss = 0
    for asset, weight in portfolio['weight'].items():
        shock = scenario_shocks.get(asset, 0)
        stress_loss += weight * shock
    return stress_loss

# 示例:利率上升200bp,债券组合损失-15%
scenario = {'10年期国债': -0.15, '股票': -0.20}
python

3. 蒙特卡洛极端场景#

方法:模拟收益率分布的左尾(如后1%),计算平均损失。

def monte_carlo_stress_test(returns, confidence=0.99, num_simulations=100000):
    """
    蒙特卡洛压力测试(聚焦尾部)
    """
    mu = returns.mean()
    sigma = returns.std()
    
    # 模拟极端场景(左尾)
    simulated_returns = np.random.normal(mu, sigma, num_simulations)
    tail_returns = simulated_returns[simulated_returns < np.percentile(simulated_returns, 1)]
    
    # 计算平均尾部损失
    expected_tail_loss = tail_returns.mean()
    return expected_tail_loss
python

压力测试流程图

实务中的陷阱与应对#

陷阱1:模型风险#

问题:错误的分布假设导致VaR低估风险。

案例:2008年金融危机前,许多银行使用正态分布计算VaR,低估了尾部风险。

应对

  • 使用历史模拟法(不依赖分布假设)
  • 用t分布替代正态分布(捕捉肥尾)
  • 结合CVaR和压力测试

陷阱2:数据窥探偏差#

问题:过度优化VaR模型参数,导致样本外表现差。

应对

  • 使用样本外测试
  • 简化模型(奥卡姆剃刀原则)
  • 定期重新估计参数(滚动窗口)

陷阱3:流动性风险#

问题:VaR假设可以按市价平仓,但危机时流动性枯竭。

案例:2007年量化崩盘(Quant Quake),许多量化基金同时平仓,导致流动性蒸发。

应对

  • 在VaR中加入流动性调整(Liquidity-adjusted VaR)
  • 限制单只股票仓位
  • 分散交易时间(避免集中平仓)

陷阱4:相关性崩溃#

问题:平静时期的相关性在危机时失效,分散化保护消失。

案例:2008年危机时,股票、债券、商品同时下跌,传统分散化失效。

应对

  • 使用动态相关性模型(如DCC-GARCH)
  • 加入尾部相关性度量
  • 持有真正的避险资产(如国债、黄金)

Python实战:完整的风险管理系统#

系统架构#

数据层:历史收益率数据
计算层:VaR/CVaR计算引擎
展示层:风险仪表盘(Dashboard)
告警层:风险超限告警
plaintext

完整代码示例#

风险管理系统界面

总结与建议#

关键要点#

  1. VaR是必要但不充分的:VaR给出了风险概览,但忽略尾部风险,需要结合CVaR和压力测试。

  2. 没有万能的计算方法:历史法简单但依赖历史,参数法快速但假设强,蒙特卡洛灵活但计算贵。建议组合使用

  3. 风险管理是动态过程:市场结构变化,风险模型需要定期更新和验证。

  4. 警惕模型风险:所有VaR模型都是对现实的简化,黑天鹅事件总会发生。

给量化交易者的建议#

  1. 建立多层次风险防线

    • 第一层:单笔止损(如-2%)
    • 第二层:日内VaR限制(如-5%)
    • 第三层:组合最大回撤限制(如-20%)
    • 第四层:压力测试(极端场景)
  2. 定期回溯测试

    • 检验VaR模型的准确性(Kupiec检验)
    • 计算例外率(Exception Rate):实际突破VaR的频率应接近(1-置信水平)
  3. 保持谦逊

    • 风险管理不能消除风险,只能理解和控制风险
    • 市场永远比模型复杂,做好最坏打算
  4. 技术与制度并重

    • 技术:精确的VaR/CVaR计算
    • 制度:风险限额、审批流程、应急预案

进一步学习资源#

  1. 书籍

    • 《Risk Management and Financial Institutions》- John Hull
    • 《Quantitative Risk Management》- McNeil, Frey, Embrechts
  2. 论文

    • Artzner et al. (1999): “Coherent Measures of Risk”
    • Rockafellar & Uryasev (2000): “Optimization of Conditional Value-at-Risk”
  3. Python库

    • pyfolio: 组合分析和风险度量
    • riskparityportfolio: 风险平价组合
    • arch: 波动率建模(GARCH族)

免责声明:本文仅供参考,不构成投资建议。量化交易有风险,入市需谨慎。

量化风险管理实战:VaR与CVaR计算及压力测试框架
https://blog.halo26812.eu.org/blog/risk-management-var-cvar
Author halo
Published at 2026年6月11日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨