4、VaR(在险价值):三种核心计算方法与局限性

VaR,全称Value at Risk,中文叫在险价值。

说白了,它就是回答一个问题:“在给定的置信水平下,我的投资组合在未来一段时间内,最大可能亏损是多少?”

举个例子:95%置信水平下,日VaR为100万。意思是,有95%的把握,明天亏损不超过100万。反过来,有5%的概率,亏损会超过100万。

这个指标在风控领域太常见了。我早期做量化的时候,每天开盘前第一件事就是看VaR。它就像一个风险仪表盘,告诉你今天油门能不能踩到底。

4.1 参数法(方差-协方差法)

参数法是最经典的方法。它假设资产收益率服从正态分布。

既然是正态分布,那只需要知道均值和标准差,就能算出VaR。

计算公式:

VaR = - (μ × t + Z_α × σ × √t) × P

其中:

  • μ:收益率均值
  • σ:收益率标准差
  • Z_α:置信水平对应的分位数(95%对应1.645,99%对应2.326)
  • t:持有期(天)
  • P:投资组合市值

Python实现:

import numpy as np

def parametric_var(returns, confidence=0.95, portfolio_value=1_000_000):
    mu = np.mean(returns)
    sigma = np.std(returns)
    z_score = {
        0.90: 1.282,
        0.95: 1.645,
        0.99: 2.326
    }[confidence]
    
    var = - (mu + z_score * sigma) * portfolio_value
    return var

# 示例
daily_returns = np.random.normal(0.001, 0.02, 252)
var_95 = parametric_var(daily_returns, 0.95)
print(f"95%置信水平下,日VaR为:{var_95:.2f}元")
我的经验:参数法计算快,适合大盘蓝筹股。但有个坑——金融数据往往有厚尾特征。我见过太多人直接用正态假设,结果VaR严重低估了极端风险。2015年股灾时,很多机构的参数法VaR完全失效,就是因为尾部风险被忽略了。

4.2 历史模拟法

历史模拟法不假设任何分布。它直接用过去N天的收益率数据,排序后取分位数。

你想想看,这方法多直观:过去100天里,最差的第5天亏损是多少?那就是95%置信水平的VaR。

计算步骤:

  1. 收集过去N天的历史收益率
  2. 对收益率从小到大排序
  3. 取第 (1-置信水平) × N 个位置的数值
  4. 乘以投资组合市值

Python实现:

def historical_var(returns, confidence=0.95, portfolio_value=1_000_000):
    sorted_returns = np.sort(returns)
    index = int((1 - confidence) * len(sorted_returns))
    var = - sorted_returns[index] * portfolio_value
    return var

# 示例
var_95_hist = historical_var(daily_returns, 0.95)
print(f"历史模拟法:95% VaR = {var_95_hist:.2f}元")
注意:历史模拟法依赖历史数据。如果市场结构变了,历史会骗人。我曾经用2018年的数据去预测2020年疫情下的VaR,结果差了3倍。历史不会简单重复,但历史模拟法假设它会。

4.3 蒙特卡洛模拟法

蒙特卡洛模拟法,说白了就是“暴力枚举”。

它生成成千上万条可能的未来价格路径,然后看最坏的情况。

核心思路:

  • 假设收益率服从某种随机过程(通常是几何布朗运动)
  • 随机生成大量路径(比如10000条)
  • 对每条路径计算最终损益
  • 取分位数作为VaR

Python实现:

def monte_carlo_var(initial_price, mu, sigma, days=1, 
                    n_simulations=10000, confidence=0.95,
                    portfolio_value=1_000_000):
    dt = 1/252  # 日频
    final_prices = []
    
    for _ in range(n_simulations):
        price = initial_price
        for _ in range(days):
            epsilon = np.random.normal(0, 1)
            price *= np.exp((mu - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * epsilon)
        final_prices.append(price)
    
    returns = (np.array(final_prices) - initial_price) / initial_price
    var = - np.percentile(returns, (1 - confidence) * 100) * portfolio_value
    return var

# 示例
var_95_mc = monte_carlo_var(100, 0.08, 0.2, 1, 10000, 0.95)
print(f"蒙特卡洛模拟:95% VaR = {var_95_mc:.2f}元")
我的建议:蒙特卡洛最灵活,可以加入跳跃、波动率聚集等复杂特征。但计算量大,不适合高频场景。我一般用它做压力测试,或者验证参数法和历史模拟法的结果是否合理。

4.4 三种方法对比

方法 优点 缺点 适用场景
参数法 计算快,公式简单 正态假设不现实 流动性好的大盘股
历史模拟法 无分布假设,直观 依赖历史,无法预测新风险 数据充足、市场稳定时
蒙特卡洛模拟 灵活,可模拟复杂情况 计算慢,依赖模型假设 压力测试、衍生品定价

4.5 VaR的局限性

VaR虽然好用,但坑也不少。我踩过几个,分享给你:

  • 不满足次可加性:组合的VaR可能大于各部分VaR之和。这违反了风险分散化的直觉。
  • 忽略尾部风险:VaR只告诉你“最差5%的边界”,但边界之外有多惨?它不说。2008年金融危机,很多机构的VaR显示正常,但实际亏损远超VaR。
  • 对参数敏感:历史窗口选100天还是250天,结果可能差30%。我见过有人为了好看,故意选一个低VaR的窗口期。
  • 无法处理非线性风险:期权等衍生品的损益是非线性的,VaR很难准确刻画。
避坑指南:我曾经用VaR管理一个期权组合,结果连续三天VaR都正常,第四天市场波动率飙升,组合直接爆仓。后来我改用CVaR(条件在险价值)来补充,它关注的是尾部损失的均值,比VaR更保守。

4.6 知识体系图

VaR在险价值 参数法 历史模拟法 蒙特卡洛模拟 正态假设 计算快速 无分布假设 依赖历史 灵活复杂 局限性:不满足次可加性 | 忽略尾部风险 | 参数敏感 | 非线性失效 补充:CVaR / 压力测试
核心总结:VaR是风控的起点,不是终点。三种方法各有优劣,我建议你根据数据特征和业务场景灵活选择。记住,任何模型都有假设,而市场永远在打破假设。

专注资料整理