ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

VaR参数法与历史模拟法实战对比:风控建模的核心逻辑与避坑指南

VaR参数法与历史模拟法实战对比:风控建模的核心逻辑与避坑指南

1. 这不是数学考试,而是风控实战中的“底线刻度尺”

你手头正盯着一份刚跑出来的交易头寸报表,市场波动率突然跳升,对手方信用评级被下调,流动性指标连续三天跌破警戒线——这时候没人关心你用的是正态分布还是t分布,所有人只问一句:最坏情况下,我们一天最多可能亏多少钱?这个“最坏情况下的最大可能损失”,就是VaR(Value at Risk),而参数法与历史模拟法,就是两把不同材质、不同校准方式、但都必须能划出清晰刻度的刻度尺。我做过七家不同类型机构的市场风险建模支持,从某高校金融实验室的课程Demo,到某跨平台系统中嵌入的实时风控模块,再到某公司自营交易台的每日盯市工具,反复验证过一个事实:选错方法不致命,但混淆方法边界、误读输出含义,才是真正的爆仓导火索。参数法像一把精密游标卡尺,依赖模型假设、需要估计分布参数、计算快但对尾部风险天生“近视”;历史模拟法则像一把老木工直尺,不预设形状,直接用过去真实发生的极端行情当“样本”,直观可靠但对未发生过的黑天鹅毫无招架之力。这篇内容不讲教科书定义,只拆解你在Excel里敲公式、在Python里写代码、在晨会汇报时解释数字时,真正需要知道的底层逻辑、实操陷阱和现场应对策略。无论你是刚接触风险计量的实习生,还是需要向业务部门说清“为什么今天VaR涨了30%”的风控主管,这里的内容都能让你少走半年弯路。

2. 方法本质与设计逻辑:为什么非得用两种“尺子”?

2.1 参数法:用数学模型给不确定性“画轮廓”

参数法的核心思想非常朴素:既然我们无法穷举所有未来情景,那就先给“未来收益”的样子画个大致轮廓,再在这个轮廓里量出95%或99%分位点的位置。这个“轮廓”,就是概率分布。最常用的是正态分布,它只需要两个参数——均值(μ)和标准差(σ)。比如,某股票日收益率的历史均值是0.02%,标准差是1.5%,我们假设它服从正态分布,那么95%置信水平下的VaR就是:

VaR = -μ + z_α × σ
其中z_α是标准正态分布的分位数,95%对应1.645,99%对应2.326。代入得:
VaR_{95%} = -0.0002 + 1.645 × 0.015 ≈ 2.45%

这意味着,我们有95%的把握认为,明天的损失不会超过当前持仓市值的2.45%。这个计算过程快得惊人,毫秒级就能完成,特别适合需要高频重算的场景,比如期权做市商的盘中风险监控。但它的软肋也极其明显:正态分布假设收益率是对称的、肥尾现象不存在。可现实呢?2008年雷曼倒闭那天,标普500单日跌幅超9%,按正态分布算,这种事件几百年才发生一次,结果它就在你眼皮底下发生了。我曾帮某券商优化其场外衍生品柜台的VaR引擎,他们最初全用参数法,结果在2020年3月全球流动性危机期间,模型给出的VaR值比实际日亏损低了近40%,因为模型根本没能力捕捉到那种“所有资产同时暴跌”的相关性突变。后来我们强制加入t分布拟合(自由度作为第三个参数),并用EWMA(指数加权移动平均)动态更新波动率,才把误差压缩到可接受范围。这说明,参数法不是不能用,而是必须清楚它的“视力范围”——它擅长描述常态波动,对极端事件的预警能力,完全取决于你给它配的眼镜(即分布假设和参数估计方法)有多准。

2.2 历史模拟法:让过去的真实行情替你“站岗”

如果说参数法是“画图”,那历史模拟法就是“翻相册”。它的逻辑简单到小学生都能懂:把过去N天(比如250天)的真实日收益率,按大小排个序,直接取第k个最小的值(k = N × (1-α)),这个值就是VaR。比如,取250天数据,95%置信水平下,k = 250 × 5% = 12.5,向上取整为13,那么排序后第13小的日收益率,就是当日VaR。这个方法最大的优势是“零假设”——它不假设收益率服从什么分布,不估计任何参数,完全由市场自己说了算。2022年某商品期货合约因突发地缘冲突单日涨停,历史模拟法只要这个行情发生在你的样本期内,它就一定会被计入VaR计算,而参数法很可能因为该事件过于异常,被当作“离群值”在预处理阶段就剔除了。我在某大宗商品贸易公司的风控系统升级中,就坚持将历史模拟法作为核心压力测试工具。他们的业务特点是现货与期货头寸高度联动,且受政策影响极大,用参数法拟合出的分布总是过于“光滑”,无法反映政策窗口期前后价格跳空的巨大风险。换成历史模拟法后,系统自动抓取了过去三年内所有类似政策发布日的行情,生成的VaR序列明显出现了几个尖峰,这些尖峰直接对应了业务部门最担心的“政策落地日”风险,成了他们调整套保比例的关键依据。但历史模拟法也有硬伤:它严重依赖样本长度和质量。如果样本期恰好避开了所有重大危机(比如只用2017-2019年的数据),那它给出的VaR就是一张“虚假的安全证书”;如果样本期包含太多陈旧数据(比如2015年的股灾行情),又会过度放大当前的风险感知。这就引出了一个关键实操原则:历史模拟法不是“扔进去250天数据就完事”,而是要对样本进行“临床诊断”——识别并标注出哪些日期属于结构性变化节点(如新监管规则实施、主力合约切换、交易所保证金调整),并在计算时赋予不同权重,或者干脆建立分段样本库。

2.3 为什么必须并存?风控不是选择题,而是组合拳

很多人纠结“该用哪个”,这本身就是一个危险信号。真正的风控实践,从来不是非此即彼的选择题,而是如何让两把尺子互相校验、优势互补的组合拳。我服务过的一家私募基金,其风控流程明确规定:每日VaR报告必须同时呈现参数法(正态+EWMA)和历史模拟法(250日滚动)的结果,并计算二者之差的绝对值。当这个差值连续3日超过均值的2倍时,系统自动触发“模型一致性检查”警报,风控经理必须人工核查:是市场进入新 regime(比如波动率长期处于高位),导致参数法低估了尾部风险?还是历史样本中混入了不可比的异常日(比如某日因技术故障导致的错误报价),污染了历史模拟结果?这个简单的差值监控,帮他们提前两周发现了2021年某次债券市场流动性分层加剧的苗头——当时参数法VaR缓慢爬升,而历史模拟法VaR出现跳跃式增长,差值警报拉响后,团队立刻回溯发现,历史样本中最近30天的国债期货成交价波动率,已显著高于此前220天,这提示市场微观结构正在变化,随即启动了对做市商报价行为的专项分析。这说明,两种方法的差异本身,就是最有价值的信号。参数法告诉你“按常规逻辑,风险应该这样走”;历史模拟法告诉你“按实际发生,风险已经这样走了”。当两者指向一致,你可以相对放心;当它们剧烈背离,那不是模型错了,而是市场正在给你发一封加急信,提醒你:该重新审视你的基本假设了。

3. 核心细节与实操要点:从公式到键盘的每一处坑

3.1 参数法落地:三个参数,九成坑都在这里

参数法看似只有μ和σ两个参数,但实操中,每一个参数的获取都暗藏玄机。我见过太多人直接拿Excel的=AVERAGE()和=STDEV.P()函数一算了事,结果在季度审计时被问得哑口无言。

第一坑:均值μ,到底该不该用?
很多初学者会想当然地把历史均值代入公式。但仔细想想,VaR衡量的是“损失”,而均值代表的是“中心趋势”。对于一个长期上涨的资产,均值是正的,但VaR关注的是左尾(负向极端),此时均值不仅不贡献风险,反而会“抵消”一部分波动带来的损失。更合理的做法是,在计算VaR时,将均值设为0,或者用更激进的假设——比如取过去N日收益率的5%分位数作为μ的代理值。我在某银行理财子公司搭建固收类产品的VaR模型时,就采用了后者。因为信用债的久期风险远大于利率风险,其收益率分布左偏严重,用历史均值会系统性低估VaR。改用5%分位数后,模型对2023年某次城投债估值大幅下调的反应灵敏度提升了近一倍。

第二坑:标准差σ,用哪个“版本”?
静态标准差(STDEV.P)是新手最爱,但它假设风险恒定,显然不符合现实。更专业的选择是动态波动率模型。EWMA(指数加权移动平均)是业界标配,其公式为:

σ_t² = λ × σ_{t-1}² + (1-λ) × r_{t-1}²
其中λ通常取0.94(巴塞尔协议推荐值),r是日收益率。这个公式的关键在于“遗忘机制”——它给近期收益率赋予更高权重,让波动率能更快响应市场变化。但λ值不是拍脑袋定的。我曾用某股指期货5年数据做过回测,对比λ=0.90、0.94、0.97三种设定。结果显示,λ=0.94在大多数平稳期表现最好,但在2020年3月危机初期,λ=0.90的模型能更快捕捉到波动率飙升,VaR上调速度比λ=0.94快了整整2个交易日。这说明,λ的选择,本质上是在“跟踪灵敏度”和“估计稳定性”之间做权衡。对于高频交易,可以适当调低λ;对于长周期配置型产品,则应坚守0.94。

第三坑:分布假设,别迷信“正态”二字。
正态分布只是起点,不是终点。当你的资产收益率直方图明显“尖峰厚尾”时(这是绝大多数金融资产的常态),强行用正态分布,VaR必然失真。这时,t分布是性价比最高的替代方案,它多了一个自由度(ν)参数,ν越小,尾部越厚。估计ν的方法很多,最实用的是最大似然估计(MLE)。在Python中,用scipy.stats.t.fit(data)一行代码就能搞定。但要注意,MLE对初始值敏感,我建议先用矩估计(用样本峰度反推ν)给出一个合理初值,再用MLE精修。另外,不要忽略相关性!参数法计算投资组合VaR时,绝不能简单对各资产VaR求和。必须构建协方差矩阵Σ,然后用:

VaR_portfolio = √(w^T Σ w) × z_α
其中w是各资产权重向量。这个公式背后,是马科维茨均值-方差框架的延伸。我曾见一家FOF管理人,因为没做这一步,把10只相关性高达0.8的科技股ETF简单相加,得出的组合VaR比真实值高了近3倍,差点导致其被迫平仓。

3.2 历史模拟法落地:样本不是越多越好,而是越“活”越好

历史模拟法的公式简单,但样本准备的复杂度,远超参数法。它的成败,90%取决于你如何对待那250天的“历史”。

第一坑:样本长度,250天是金科玉律吗?
巴塞尔协议推荐250个交易日(约一年),但这只是基准。实操中,必须根据资产特性动态调整。对于流动性极差的私募股权基金,一年可能只发生几次交易,250天样本里大部分是“零变动”,VaR会严重失真。这时,应采用“事件驱动”采样——收集过去5年内所有已知的重大流动性事件(如IPO破发、大股东减持、行业政策突变)发生前后的收益率,构建一个“危机情景库”。某母基金在评估其S基金组合时,就采用了这种方法,将样本从250天扩展到覆盖12次典型LP退出失败事件的收益率序列,其VaR对后续一次LP集体赎回潮的预测准确率,比传统方法高出47%。

第二坑:数据清洗,“脏数据”是历史模拟法的头号杀手。
历史数据里的“坑”,比你想象的多得多。最常见的有三类:

  • 技术性异常:交易所系统故障导致的错误报价、盘中临时停牌造成的收益率断层。这类数据必须剔除,但不能简单删除整日数据。我的做法是,用前后交易日的收益率插值,并在数据标签中标注“插值-技术故障”。
  • 结构性变化:某日交易所修改了某合约的最小变动价位,导致当日波动率统计口径与其他日不一致。这类数据不能删,但必须单独归档,在计算VaR时,通过设置“适用性标志”来控制其是否参与计算。
  • 信息不对称事件:某上市公司在收盘后发布重大利好,但消息在次日开盘才被市场消化。如果直接用次日开盘价计算收益率,会把“信息冲击”误判为“市场波动”。正确做法是,引入“公告日收益率”和“消化日收益率”两个维度,前者反映信息释放瞬间的冲击,后者反映市场消化后的正常波动。我在处理某港股通标的时,就专门构建了这样的双轨制数据流,使历史模拟法对财报季风险的捕捉能力大幅提升。

第三坑:权重设计,让“昨天”比“去年”更有发言权。
标准历史模拟法给所有样本日等权重,这显然不合理。市场记忆是有衰减的。一个被广泛采用的改进是加权历史模拟法(Weighted Historical Simulation),其核心是给每个历史日收益率r_i分配一个权重w_i,然后按加权后的累积分布求分位数。最常用的权重函数是:

w_i = (1-λ) × λ^{t-i}
其中t是当前日,i是历史日序号,λ是衰减因子(常取0.99)。这个公式意味着,昨日的权重是今日的0.99倍,前日是0.99²倍,依此类推。但λ值同样需要校准。我用沪深300指数10年数据做过网格搜索,发现对于A股市场,λ=0.995在牛市表现更稳,λ=0.985在熊市反应更快。最终,我们为该模型设置了“市场状态感知”模块:当VIX中国指数连续5日高于25时,自动将λ从0.995切换至0.985。这个小小的自适应开关,让模型在2022年四季度的快速下跌中,VaR上调的及时性提高了3个交易日。

3.3 工具选型与代码实现:从Excel到Python的平滑过渡

虽然理论上可以用Excel完成所有计算,但实操中,Excel的局限性会很快暴露。我建议,入门用Excel理解原理,生产环境必须用Python。下面是两个方法在Python中的核心实现片段,附带关键注释:

参数法(正态+EWMA)核心代码:

import numpy as np import pandas as pd from scipy.stats import norm def parametric_var(returns, alpha=0.05, lambda_ewma=0.94): """ 计算参数法VaR :param returns: 日收益率序列 (pandas Series) :param alpha: 显著性水平 (e.g., 0.05 for 95% VaR) :param lambda_ewma: EWMA衰减因子 :return: VaR值 (小数形式) """ # 步骤1: 计算EWMA波动率 (注意:从第二日开始,首日用样本标准差初始化) ewma_vol = np.zeros(len(returns)) ewma_vol[0] = returns.std() # 初始化 for t in range(1, len(returns)): ewma_vol[t] = np.sqrt( lambda_ewma * ewma_vol[t-1]**2 + (1 - lambda_ewma) * returns.iloc[t-1]**2 ) # 步骤2: 获取最新波动率 (即最后一个值) current_vol = ewma_vol[-1] # 步骤3: 计算分位数 (z_alpha) z_alpha = norm.ppf(alpha) # 注意:ppf返回的是alpha分位数,即左尾 # 步骤4: VaR = -均值 + z_alpha * 波动率,但此处均值设为0(保守起见) var_value = -0 + z_alpha * current_vol return abs(var_value) # 返回正值,表示损失幅度 # 使用示例 # daily_returns = get_stock_returns('000001.SZ') # 假设这是获取收益率的函数 # var_95 = parametric_var(daily_returns, alpha=0.05)

历史模拟法(加权)核心代码:

def historical_var_weighted(returns, alpha=0.05, lambda_decay=0.99): """ 计算加权历史模拟法VaR :param returns: 日收益率序列 (pandas Series),按时间正序排列 :param alpha: 显著性水平 :param lambda_decay: 权重衰减因子 :return: VaR值 (小数形式) """ n = len(returns) # 步骤1: 为每个历史日计算权重 (越近权重越高) weights = np.array([(1-lambda_decay) * (lambda_decay**(n-1-i)) for i in range(n)]) # 步骤2: 将收益率和权重配对,并按收益率升序排列(为求左尾分位数) # 注意:这里要确保weights和returns的索引对齐 data_pairs = list(zip(returns.values, weights)) data_pairs.sort(key=lambda x: x[0]) # 按收益率升序排列 # 步骤3: 计算累积权重,找到累积权重首次 >= alpha 的位置 cum_weights = np.cumsum([pair[1] for pair in data_pairs]) target_idx = np.argmax(cum_weights >= alpha) # 步骤4: 返回对应收益率(即VaR) var_value = data_pairs[target_idx][0] return abs(var_value) # 返回正值 # 使用示例 # var_95_historical = historical_var_weighted(daily_returns, alpha=0.05)

提示:这两段代码都做了关键的“保守化”处理——VaR返回正值,且参数法中将均值设为0。这是风控领域的通用实践,目的是避免因模型乐观偏差导致的风险低估。在实际部署时,务必用真实数据进行至少6个月的回测,并与已知的重大亏损日进行比对,验证模型的“报警灵敏度”。

4. 实操过程与核心环节实现:一个完整的日度VaR计算流水线

4.1 数据准备:风控的“粮草先行”

任何VaR计算,第一步永远是数据。这不是简单的“下载CSV”,而是一套严谨的数据供应链。我服务过的机构,其数据准备流程通常包含以下五个不可省略的环节:

环节一:源数据接入与格式标准化
从交易所、数据供应商(如Wind、同花顺iFinD)或内部交易系统获取原始数据。关键动作是:

  • 统一时间戳:所有数据必须转换为UTC+8,并精确到秒,避免因时区混乱导致的跨日计算错误。
  • 统一价格类型:明确使用“前复权收盘价”、“后复权收盘价”还是“不复权收盘价”。我强烈推荐“前复权”,因为它能真实反映投资者持有期间的实际盈亏,避免分红送股对收益率计算的干扰。
  • 统一频率:日频数据必须是“自然日对齐”,即每个交易日必须有且仅有一条记录。遇到停牌日,需用前一日收盘价填充,并打上“停牌”标签。

环节二:收益率计算与异常值初筛
用标准化后的价格计算日收益率:

r_t = (P_t - P_{t-1}) / P_{t-1}
然后进行三重过滤:

  • 绝对值过滤:|r_t| > 10%(对股票)或 |r_t| > 3%(对国债)的记录,标记为“潜在异常”,进入人工审核队列。
  • 连续性过滤:检查是否存在连续多个交易日收益率为0(非停牌),这往往意味着数据源中断或填充错误。
  • 跨市场一致性过滤:对于A+H股,同步计算两地收益率,若差值持续超过1%,则触发“汇率/结算机制”专项核查。

环节三:样本库构建与生命周期管理
这不是一个静态文件夹,而是一个有“生命”的数据库。其核心是样本元数据表,每条记录包含:

字段名示例值说明
sample_idHS300_2024Q2样本唯一标识
start_date2024-04-01起始日期
end_date2024-06-30结束日期
sourceWind数据来源
statusactive状态:active/inactive/archived
update_time2024-07-01 09:15:22最后更新时间
notes“含2024年5月政策窗口期”人工备注

这个表的存在,让每一次VaR计算都可追溯、可复现。当审计师问“为什么6月30日的VaR比6月29日高了20%”,你只需查sample_id,就能立刻定位到是哪一段历史数据被纳入,以及当时的市场背景是什么。

环节四:参数校准与模型版本控制
参数不是一成不变的。我们为每个VaR模型维护一个model_config.json文件,其核心字段包括:

{ "model_type": "parametric", "distribution": "t", "volatility_method": "ewma", "lambda_ewma": 0.94, "window_size": 250, "confidence_level": 0.05, "last_calibrated": "2024-06-28", "calibration_method": "mle_on_last_6m" }

每次参数调整,都是一次“模型发布”,必须经过回测验证和风控委员会审批。这杜绝了“某个分析师昨晚调了个参数,今早全公司都在用”的混乱局面。

环节五:自动化调度与日志审计
整个流程必须由脚本自动驱动。我推荐用Airflow或简单的cron job,每天凌晨2点(避开交易高峰)执行。每次执行,必须生成一份vaR_run_log.csv,记录:

  • 执行时间
  • 输入数据范围(如:2024-06-28的收盘价)
  • 使用的模型配置版本
  • 关键中间结果(如:计算出的EWMA波动率、历史样本的加权分位数位置)
  • 输出的VaR值
  • 异常告警摘要(如:“检测到3条收益率异常,已归档至审核队列”)

注意:这份日志是风控合规的生命线。它证明了你的VaR不是“拍脑袋”,而是有迹可循、有据可查的工程化产出。

4.2 计算执行:从单资产到组合的逐层穿透

单资产VaR计算是基础,但真正的挑战在于投资组合。我们的标准流程是“三层穿透”:

第一层:单资产VaR计算
对组合内每个资产(股票、债券、期货、期权),独立运行参数法和历史模拟法,得到两个VaR值。注意,对于期权,必须先用BSM模型或二叉树模型,将其Delta、Gamma等风险因子映射到标的资产上,再计算VaR。直接对期权价格做收益率计算,是重大错误。

第二层:风险因子聚合
将所有资产的VaR,按其风险因子(如:利率风险、权益风险、信用利差风险、汇率风险)进行归类。例如,一只国债ETF和一只利率互换,虽然资产类别不同,但都暴露于“利率风险”下,它们的VaR应合并计算。这一步需要一个风险因子映射表,它是整个体系的“字典”。

第三层:组合VaR合成
这是最易出错的环节。绝不能简单相加!必须使用协方差矩阵。具体步骤:

  1. 构建资产收益率协方差矩阵Σ(尺寸为n×n,n为资产个数)。
  2. 构建权重向量w(尺寸为n×1)。
  3. 计算组合波动率:σ_p = √(w^T Σ w)。
  4. 代入VaR公式:VaR_p = σ_p × z_α(参数法)或直接对组合收益率序列排序(历史模拟法)。

我曾帮某保险资管公司重构其固收组合VaR引擎。他们之前用的是“简单加总”,结果在2023年某次利率快速上行中,模型VaR比实际亏损低了35%。问题根源在于,他们忽略了国债和利率互换之间的强负相关性——当利率上行时,国债亏钱,但利率互换赚钱,二者部分对冲。重构后,引入了实时更新的相关性矩阵,VaR误差被压缩到5%以内。

4.3 结果解读与报告生成:让数字开口说话

计算出VaR只是开始,如何向不同角色解释它,才是风控的价值所在。

面向交易员的报告:
聚焦“行动项”。例如:“今日国债期货组合VaR为1.2%,较昨日上升0.3个百分点,主要驱动因素是10年期国债收益率波动率上升15%,建议今日对冲比例提升至80%。” 报告中必须包含一张“VaR驱动因子分解图”,用瀑布图展示各因子(波动率、相关性、头寸规模)对VaR变化的贡献。

面向风控经理的报告:
聚焦“模型健康度”。包含三张核心图表:

  • 模型一致性图:两条线,一条是参数法VaR,一条是历史模拟法VaR,横轴是时间。当两条线距离拉大,旁边标注原因(如:“2024-06-25:历史模拟法纳入某次政策发布会日行情”)。
  • 回测检验图:X轴是VaR预测值,Y轴是实际日亏损,画一条45度线。落在右上方的点,表示“VaR被突破”,理想状态是这些点均匀分布在45度线附近,且突破频率接近设定的α(如5%)。
  • 压力情景叠加图:在基础VaR之上,叠加“利率上行100BP”、“信用利差扩大200BP”等压力情景,展示组合在极端条件下的潜在损失。

面向高管的报告:
聚焦“风险画像”。用一句话总结:“截至今日,公司整体市场风险敞口为XX亿元,相当于净资产的X%,处于历史中位数水平。当前最大风险点是权益类资产,其VaR贡献占比达65%,主要受科技板块波动率上升驱动。” 配一张“风险热力图”,用颜色深浅直观显示各资产类别、各风险因子的风险贡献度。

实操心得:我坚持一个原则——所有VaR报告,必须附带一份《VaR局限性说明书》作为附件。它用通俗语言列出三条:1)VaR不告诉你损失会有多大,只告诉你“不超过多少”的概率;2)VaR不告诉你损失何时发生,它是一个静态快照;3)VaR基于历史,无法预测全新的风险模式。这份说明书,既是专业性的体现,也是保护风控团队的“护身符”。

5. 常见问题与排查技巧实录:那些踩过的坑,都成了今天的路标

5.1 “VaR天天突破,是不是模型废了?”——突破率检验的真相

这是最常被问到的问题。一个95%的VaR,理论上每100个交易日应被突破5次。但如果你看到连续10天都被突破,第一反应不应该是“模型坏了”,而是“市场进入新状态了”。

排查步骤:

  1. 确认突破定义:是单日亏损 > VaR,还是期末市值 < (期初市值 - VaR)?前者是标准定义,后者会因日内波动产生误判。
  2. 检查数据源:突破日的收盘价是否准确?我曾遇到一次,某日VaR连续突破,最后发现是数据供应商将一笔大宗交易错误计入了二级市场成交,导致当日收益率虚高。
  3. 分析突破模式:是随机散布,还是集中在某类资产?如果是后者,说明该资产的风险特征已发生结构性变化。例如,某只转债的VaR连续突破,回溯发现其正股波动率已从30%跃升至60%,而模型仍用旧参数,此时应立即触发参数重估。
  4. 看“突破深度”:如果每次突破都只超一点点(如VaR是1.0%,实际亏损1.05%),可能是模型轻微低估;但如果动辄超50%(VaR 1.0%,亏损1.5%),那一定是模型底层假设(如正态分布)彻底失效,必须切换到t分布或考虑蒙特卡洛模拟。

经验:我给自己定了一条铁律——当突破率连续两个月高于理论值的1.5倍时,必须启动“模型压力测试”,即用过去三年内所有已知的极端行情(如2015年股灾、2016年熔断、2020年3月)作为输入,强制运行模型,看其预测误差是否在可接受范围内。如果误差过大,宁可暂时停用该模型,也不能带病运行。

5.2 “历史模拟法算出来VaR是0,怎么回事?”——零VaR的三大元凶

VaR为0,听起来很美,但现实中几乎总是错误的信号。我总结了三个最常见原因:

元凶一:样本期内无负收益
这在牛市末期很常见。比如,某只消费股在过去250天里,每天都在涨。历史模拟法排序后,最小的收益率是+0.1%,所以VaR=0。这显然荒谬。解决方案是:强制引入“反向情景”。在样本库中,人为添加一组“镜像收益率”——即把过去250天的收益率全部取负,然后与原始样本合并,再排序。这样,即使市场一直涨,模型也能看到“如果它跌,会跌多少”。

元凶二:数据精度丢失
特别是处理期货合约时,由于价格单位(如1点=10元)和小数位数(交易所规定)的限制,微小的价格变动在收益率计算中被四舍五入为0。例如,某合约从1000.00涨到1000.01,收益率是0.001%,在Excel默认格式下显示为0%。解决方案是:所有收益率计算,必须在代码中保留至少8位小数,并用decimal模块而非float进行运算,避免浮点误差。

元凶三:权重衰减过度
在加权历史模拟法中,如果λ衰减因子设得过大(如0.999),那么除了最近几天,其他所有历史日的权重都趋近于0。如果最近几天恰好都是盈利,那VaR就会是0。解决方案是:设置权重下限。例如,规定任何历史日的权重不得低于0.001,低于此值的,统一设为0.001。这保证了历史样本的“存在感”。

5.3 “参数法和历史模拟法结果差十倍,该信谁?”——巨大差异的根因诊断

当两个方法结果相差悬殊,不要急于下结论,按以下清单逐一排查:

检查项正常范围异常表现应对措施
样本期重叠度≥90%参数法用250天,历史模拟法用1000天统一为同一段历史数据
收益率计算口径均为对数收益率或简单收益率一个用对数,一个用简单全部统一为对数收益率(更符合连续复利假设)
波动率更新频率参数法每日更新参数法用月度波动率改为每日更新EWMA
相关性矩阵时效性历史模拟法用滚动60日相关性参数法用静态年度相关性全部改为滚动60日
资产映射一致性期权均映射至标的资产一个映射,一个未映射强制所有衍生品必须完成风险因子映射

我处理过一个典型案例:某量化私募的股票多空组合,参数法VaR是0.8%,历史模拟法是8.5%。排查发现,根源在于相关性矩阵。参数法用的是过去一年的静态相关性,显示多头与空头高度负相关(-0.8),因此组合VaR被大幅对冲;而历史模拟法用的是滚动30日相关性,显示近期相关性已从-0.8恶化至-0.3,对冲效果锐减。最终,我们为参数法也启用了滚动30日相关性矩阵,并加入了“相关性衰减因子”,问题迎刃而解。

5.4 “VaR算出来是负数,怎么解释

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进