先说结论:只数突破次数的 VaR 回测有一个致命盲区——突破的”位置”。本文的模拟实验里,静态正态 VaR 在 1000 个交易日被击穿 46 次(95% VaR 名义预期 50 次),Kupiec POF 检验 p=0.56 轻松通过;但 Christoffersen 独立性检验给出 p=0.000002 的毁灭性拒绝——因为它突破后的第二天再突破的概率高达 23.9%,是无条件突破率 4.6% 的五倍。突破扎堆意味着风险模型在最危险的时刻连续失灵,而这恰恰是风控最不能容忍的失败模式。Christoffersen(1998)用一个一阶马尔可夫链把”突破是否独立”变成了可检验的似然比统计量。
POF 检验的盲区:只数次数,不看位置#
上一篇 Kupiec POF 检验 把 VaR 回测简化成数硬币:数一数实际损失超过 VaR 的天数,用似然比判断这个次数是否与名义覆盖率相容。但考虑两个极端情形,同样是 250 天突破 5 次:
- 情形 A:突破分散在 1 月、3 月、6 月、9 月、12 月,彼此独立
- 情形 B:突破集中在 10 月的连续 5 个交易日
POF 检验对这两种情形给出完全相同的结论——因为它只看总次数。但对风控而言这是天壤之别:情形 B 意味着模型在危机来临时连续五天低估风险,机构会在最脆弱的时刻承受远超资本预算的损失。2008 年金融危机中大量银行的 VaR 模型正是这种模式:全年突破次数勉强达标,但突破全部挤在 9-10 月。
正确校准的 VaR 模型必须满足两个条件:
- 无条件覆盖(unconditional coverage):突破频率 ≈ 名义水平 p
- 独立性(independence):今天是否突破,不应该依赖昨天是否突破
POF 只检验第一条。Christoffersen 检验补上第二条。
一阶马尔可夫链:把”扎堆”形式化#
定义突破指示序列 。独立性的反面是序列相关,最简单的建模方式是一阶马尔可夫链,用两个转移概率描述:
- :昨天平安无事,今天突破的概率
- :昨天刚突破,今天再次突破的概率
如果突破是独立的,那么昨天发生了什么不影响今天,。如果突破扎堆,则 ——突破之后更容易接着突破。
零假设(独立)下的似然只有一个参数 ;备择假设(马尔可夫)下有两个参数 和 ,其中 是从状态 i 转移到状态 j 的次数。似然比统计量:
更进一步,Christoffersen 把次数检验和独立性检验拼成联合检验(conditional coverage):
一次性回答”次数对不对”和”位置对不对”两个问题。
实验:静态 VaR 如何骗过 POF 却栽在独立性上#
用 GARCH(1,1)-t(6) 模拟 1000 天收益(α=0.15,β=0.83,波动持续性 0.98),对比两个 95% VaR 模型:静态正态 VaR(全样本标准差乘正态分位数,一条水平线)和 GARCH-t VaR(每天跟随条件波动率调整)。
import numpy as np
from scipy import stats
def christoffersen_ind(breach):
"""LR_ind:一阶马尔可夫独立性检验"""
n00 = n01 = n10 = n11 = 0
for t in range(1, len(breach)):
if breach[t-1]==0 and breach[t]==0: n00 += 1
elif breach[t-1]==0 and breach[t]==1: n01 += 1
elif breach[t-1]==1 and breach[t]==0: n10 += 1
else: n11 += 1
pi01 = n01 / (n00 + n01) # P(今天破 | 昨天没破)
pi11 = n11 / (n10 + n11) # P(今天破 | 昨天破)
pi = (n01 + n11) / (n00+n01+n10+n11)
sl = lambda x: np.log(x) if x > 0 else 0.0
ll_h0 = (n00+n10)*sl(1-pi) + (n01+n11)*sl(pi)
ll_h1 = (n00*sl(1-pi01) + n01*sl(pi01)
+ n10*sl(1-pi11) + n11*sl(pi11))
lr = -2 * (ll_h0 - ll_h1)
return lr, 1 - stats.chi2.cdf(lr, 1), pi01, pi11python先看突破在时间轴上的分布:

上图静态 VaR 的突破点密集地挤在几个高波动窗口里,低波动期几个月一次都不破;下图 GARCH-t VaR 的突破均匀散布——这正是”正确条件覆盖”该有的样子:每一天的条件突破概率都是 5%,无论市场平静还是动荡。
转移概率是最直观的证据:

静态模型 对 ——突破后的第二天再突破的概率是平时的 6.5 倍。GARCH-t 模型两者几乎相等(0.055 对 0.055),突破历史不提供任何预测信息。
三个检验的完整对照:
| 检验 | 静态正态 VaR | GARCH-t VaR |
|---|---|---|
| 突破次数(1000 天,名义 50) | 46 | 55 |
| POF(次数)p 值 | 0.557 ✓ | 0.475 ✓ |
| IND(独立性)p 值 | 0.000002 ✗ | 0.986 ✓ |
| CC(联合)p 值 | 0.0000 ✗ | 0.775 ✓ |

静态模型的突破次数无懈可击(46 对名义 50),POF 检验完全无法定罪;独立性检验一击致命。原因在第一性原理层面很简单:静态 VaR 忽略波动聚集,高波动期条件突破概率远超 5%、低波动期远低于 5%,两者在”总次数”上恰好抵消,但在”时间排列”上无处遁形——高波动期本身是持续的,所以突破也是持续的。
功效:波动聚集越强,独立性检验越有牙#
对不同波动持续性(α+β 从 0 到 0.97)的市场各模拟 300 次,统计静态 VaR 被两种检验拒绝的比例:

无波动聚集时(持续性=0),静态模型实际上是正确的,两个检验的拒绝率都在 9% 附近(接近名义 5%,略高是小样本偏差)。随着持续性上升,独立性检验的拒绝率爬升到 44%,明显快于 POF 的 23%——对”动态错配”这类缺陷,看位置比数次数灵敏一倍。但也要诚实:即使在 0.97 的强聚集下,单个 1000 天样本也只有不到一半的概率定罪,独立性检验的功效同样有限,不拒绝 ≠ 模型没问题。
工程实践清单#
用 95% 而非 99% VaR 做独立性检验。99% VaR 在 250 天里只有约 2-3 次突破, 几乎总是 0,马尔可夫链的参数根本估不出来。监管层面用 99%(资本要求),模型诊断层面建议平行跑 95% 甚至 90% 的独立性检验——突破样本多一个数量级,检验才有牙。
一阶马尔可夫只是最低标准。它只能捕捉”连续两天”的扎堆,对”隔一天再破”或更长程的依赖失明。更强的工具是 Engle-Manganelli 的 DQ 检验(把突破指示对滞后突破、滞后 VaR 做回归)和 Berkowitz 的谱检验。实务上一阶马尔可夫 + DQ 是标配组合。
联合检验不能替代分项检验。 把两个自由度混在一起,可能出现”次数轻微超标 + 位置轻微扎堆”联合起来拒绝、但单项都不显著的情形,也可能被某一项的强信号淹没另一项。报告时三个数字都要给:POF 定位”尺度错误”(VaR 整体偏松/偏紧),IND 定位”动态错误”(模型不跟踪波动状态)。修复方向完全不同——前者换尾部分布,后者换波动模型。
独立性违反的根源几乎总是波动模型。如果你的 VaR 突破扎堆,第一嫌疑人是波动率更新太慢(RiskMetrics λ=0.94 在剧烈 regime 切换时就会这样),第二嫌疑人是根本没有条件波动(历史模拟法用等权长窗口时尤甚)。修复手段按性价比排序:EWMA 缩短半衰期 → GARCH → filtered historical simulation。
这些工具回答的都是”模型过去一年合不合格”。监管者还需要一个更粗粒度但更可执行的框架——多少次突破罚多少资本。这就是巴塞尔交通灯检验的领地。
局限#
独立性检验只看突破的 0/1 序列,不看突破的幅度——连续两天各超 0.1% 会被定罪,单日超 20% 却安然无恙,而后者显然更致命(幅度维度需要 expected shortfall 回测或 Acerbi-Szekely 检验补位)。马尔可夫参数在突破稀少时估计方差极大,250 天窗口下即使 95% VaR 也只有约 12 次突破, 的置信区间宽得惊人,结论要用滚动多窗口交叉确认。最后,检验假设突破概率只依赖昨天的突破状态,真实市场的风险状态转移远比一阶链复杂——它是必要条件检验,不是充分条件认证。
延伸阅读:
- Christoffersen, P. (1998). “Evaluating Interval Forecasts”. International Economic Review 39(4).
- Engle, R. & Manganelli, S. (2004). “CAViaR: Conditional Autoregressive Value at Risk by Regression Quantiles”. JBES 22(4).
- Kupiec POF 检验:用失败次数的似然比给 VaR 模型做体检