halo 的技术博客

返回

问题:正态 VaR 为什么天天被击穿?#

风险管理里最常被问的一句话是:「明天最坏能亏多少?」VaR(Value at Risk,风险价值)给的就是这个数——在给定置信度下,某段时间内损失的下界。1% VaR 等于 100 万仓位,意思是「99% 的日子里,单日亏损不会超过 100 万」。

算 VaR 有三条常见路子:

  1. 历史模拟法:直接拿过去 N 天的收益排序,取 1% 分位数。不做任何分布假设,但吃数据——你想估 1% 分位数,至少得有几百个观测才稳,而且它假设未来长得像过去。
  2. 参数正态法:假设收益服从正态分布,VaR = μ + σ·Φ⁻¹(α)。一行公式,极快,只要均值和标准差。问题在于——收益根本不是正态的
  3. 蒙特卡洛法:拟合一个复杂分布或模型,模拟几万条路径。灵活但慢,而且模型选错了照样偏。

第二条路的诱惑最大:快、省数据、闭式解。但它有个几乎致命的缺陷——正态分布假设收益是对称的、尾巴是薄的,而真实股票收益既左偏(暴跌比暴涨来得更猛更频繁)又肥尾(极端事件的概率远高于正态预言)。

后果是什么?正态 VaR 会系统性低估左尾损失。你以为 99% 的日子安全,实际可能只有 96%、97%。风控模型在最需要它的时候——极端行情——恰恰最不可靠。

正态 VaR 把肥尾左尾的损失低估了一大截:蓝色正态曲线的左尾比实际分布(灰色)薄得多

上图是 30 万个样本的模拟收益(左偏 + 肥尾,偏度约 −0.3、超额峰度约 0.3,贴近真实日收益)。三条竖线一目了然:

  • 正态 VaR₁% = 2.33σ(蓝虚线)——就是标准正态的 −2.326 分位数,雷打不动。
  • 经验 VaR₁% = 2.60σ(绿点线)——直接从数据里取的真值。
  • CF VaR₁% = 2.56σ(红虚线)——本文的主角,几乎贴住了绿线。

正态法比真值低估了 0.27σ。听起来不多?在一个日波动率 1.5%、仓位 1 亿的组合上,这就是每次触发时少算约 40 万的损失缓冲——而且是在你最扛不住的那些日子。

Cornish-Fisher 展开:不换分布,只修分位数#

Cornish-Fisher(CF)展开的思路很聪明:它不去假设一个新分布,而是直接对『分位数』本身做修正。

标准正态分布的 α 分位数记作 z(比如 1% 对应 z = −2.326)。如果真实分布有偏度 S 和超额峰度 K,CF 展开给出一个修正后的分位数 z_CF:

z_CF = z
     + (z² − 1)·S/6
     + (z³ − 3z)·K/24
     − (2z³ − 5z)·S²/36
plaintext

拆开看这几项在干什么:

  • 第一项 z:正态基准,什么都没修。
  • 第二项 (z²−1)·S/6偏度修正。S<0(左偏)时,这一项把左尾的分位数往外推——承认暴跌更极端。
  • 第三项 (z³−3z)·K/24峰度修正。K>0(肥尾)时,进一步加深尾部——承认极端事件更频繁。
  • 第四项 −(2z³−5z)·S²/36:偏度的二阶交叉修正项,量级通常最小。

拿到 z_CF 之后,VaR 的算法和参数正态法一模一样,只是把 Φ⁻¹(α) 换成 z_CF:

核心就是这么几行。整个方法的性价比在于:只多算两个数(偏度、峰度),就把参数法从”系统性低估”拉回到”接近真值”,而且依然是闭式解、依然快、依然省数据。

偏度和峰度,分别怎么拉动分位数#

要用好 CF,得先理解那两个修正项各自的脾气。

负偏度把尾部损失往外推,厚峰度进一步加深——两者对 VaR 的贡献方向一致

左图固定几档峰度,扫偏度:偏度越负,CF VaR 越大(尾部损失越深)。这符合直觉——负偏意味着左尾更长,暴跌更极端。峰度越高,同样偏度下曲线整体上移。

右图固定几档偏度,扫峰度:峰度越高,CF VaR 越大。肥尾意味着「远离均值的事件」概率更高,尾部自然更深。

两个修正方向一致、可叠加,这就是为什么 CF 对「又左偏又肥尾」的股票收益特别对症——它恰好把这两种偏离同时补上。

一个实务提醒:偏度和峰度本身也是估计量,也有抽样误差。 短样本估出来的高阶矩噪声很大——尤其是峰度,它对少数几个极端观测极其敏感(本质上是四次方加权)。所以 CF VaR 的稳定性天然弱于均值方差 VaR。样本太短时,估出来的偏度峰度可能纯粹是噪声,反而把 VaR 修歪。经验上至少要几百个观测,CF 的高阶矩才勉强可信。

有效域:CF 什么时候会失效#

这是 CF 最容易被忽略、也最危险的一点:CF 展开不是在任何偏度峰度下都成立的。

CF 修正本质是一个关于 z 的三次多项式。当偏度或峰度太大时,这个多项式会失去单调性——也就是说,你输入一个更极端的分位数(比如 0.5% 比 1% 更靠尾部),CF 却可能吐出一个”更不极端”的值。分位数函数本该单调,一旦交叉,输出就彻底没有意义了。

CF 变换的有效域:绿色区间单调可用,红色区间修正项失效、分位数交叉

上图在偏度-峰度平面上,逐点检验 CF 变换在常用尾部分位数区间是否保持单调。绿色是有效域(可放心用),红色是失效区(必须拒绝)。本文样本(黑点,S≈−0.27、K≈0.26)稳稳落在绿区中央——这也是为什么它的 CF VaR 那么准。

实务规则很简单:

def cf_is_valid(skew, exkurt, z_range=np.linspace(-3, 0, 40)):
    """检验 CF 变换在给定分位数区间是否保持单调(有效域检查)。"""
    q = cornish_fisher_quantile(z_range, skew, exkurt)
    return np.all(np.diff(q) > 0)     # 单调递增才有效

# 用之前先查
if cf_is_valid(s, k):
    var = cf_var(r, 0.01)
else:
    # 失效:退回历史模拟或换用 EVT / t 分布
    var = -np.quantile(r, 0.01)
python

每次算 CF VaR 之前都应该跑一遍这个检查。 危机时期偏度峰度会瞬间飙升——恰恰是你最想用 CF 的时候,它最可能滑出有效域。这时候老老实实回去用历史模拟或极值理论(EVT),比硬套一个失效的公式安全得多。

滚动回测:CF 到底修得有多准#

理论讲完,看实战。VaR 模型的唯一验收标准是违约回测(backtesting):在 1% VaR 下,理论上应该有约 1% 的日子实际损失超过 VaR 阈值——次数太多说明低估风险,太少说明过度保守浪费资本。

滚动 VaR 违约回测:期望违约 12.5 次,正态 VaR 被击穿 36 次(严重低估),CF 收敛到 23 次

模拟 1500 天时变波动 + 左偏肥尾的收益,用 250 天滚动窗口分别算正态 VaR 和 CF VaR,统计违约:

方法期望违约次数实际违约次数结论
正态 VaR₁%12.536严重低估,违约率约 2.9%(应为 1%)
CF VaR₁%12.523明显改善,但仍略偏低估

正态 VaR 的违约次数是期望的近 3 倍——在一个真实风控体系里,这意味着监管资本严重不足、爆仓概率被系统性掩盖。CF 把违约次数几乎砍半,虽然没完全收敛到 12.5(因为峰度估计的抽样误差 + 时变波动本身难追),但已经是量级上的改进,而代价只是多算两个矩。

图里蓝色圆点标出了所有正态 VaR 的违约日——可以看到它们集中在高波动段(正弦波峰附近),这正是正态假设崩得最狠的地方:波动放大时收益分布更肥尾,而正态法对此完全无感。

A. 实现细节#

  • 信号字段:仅用收益序列的四个矩——均值、标准差、偏度、超额峰度。scipy 的 stats.kurtosis 默认返回超额峰度(正态基准为 0),与 CF 公式一致,无需再减 3。
  • VaR 口径:本文用标准化收益演示,报的是”多少个 σ”。实盘直接用 mu + sigma * z_cf 得到收益率口径的 VaR,再乘仓位得金额。
  • 符号约定:VaR 取正值表示损失幅度,故公式里加了负号 -(mu + sigma*z_cf)
  • 有效域检查:每次估计前用 cf_is_valid 检验单调性,失效即退回历史模拟——这是硬门槛,不是可选项。
  • 滚动窗口:250 交易日(约一年),每日重估四个矩。窗口越短高阶矩噪声越大。

B. 已知偏差#

  • 高阶矩抽样误差:偏度尤其是峰度对极端观测极其敏感,短样本估计噪声巨大。CF VaR 的稳定性天然弱于均值方差 VaR——它把”估计误差”从两个矩扩大到了四个矩。
  • 有效域约束:偏度峰度过大时 CF 修正失去单调性、完全失效。危机时期高阶矩飙升,恰恰是 CF 最可能滑出有效域的时候,反而在最关键时刻不可用。
  • 仍是参数近似:CF 是对分位数的泰勒式展开,不是真实分布。它修正到四阶矩为止,对更高阶的尾部结构(比如幂律尾)依然无能为力,深尾(0.1% 分位)处的误差会比 1% 处更大。
  • 模拟数据的局限:本文用混合正态制造左偏肥尾,是可控的”温和肥尾”。真实市场的尾部可能更极端(如 2008、2020),届时 CF 的改进幅度会打折,甚至滑出有效域。

C. 结果解读#

  1. CF 的核心价值是”性价比”:它不追求历史模拟的精度,而是用两个额外的矩,把参数法从”系统性低估”拉到”接近真值”,同时保留闭式解的速度和省数据优势。在需要对成千上万个组合快速批量估 VaR 的场景(如实时风控面板),这个性价比无可替代。

  2. 违约回测是量级改进:正态 VaR 违约 36 次 vs CF 的 23 次(期望 12.5)。CF 没做到完美收敛,但把”错得离谱”变成”略偏保守可接受”,这在风控上是本质区别——前者会让你在极端行情裸奔,后者不会。

  3. 失效点比准确点更重要:本文样本落在有效域中央所以 CF 很准,但这不是运气而是设计——真正的风险在于偏度峰度大到滑出有效域时,如果不做单调性检查,CF 会悄无声息地吐出无意义的数字。用 CF 的纪律,是每次都检查有效域,而不是无脑套公式。

  4. 它是工具箱里的一层,不是终点:CF 适合日常快速估计和批量筛查。真要给尾部风险定价(比如 0.1% 极端 VaR、压力测试),该上极值理论(EVT)或历史模拟。CF 的定位是”比正态好得多、比 EVT 省得多”的中间层——知道它的边界,才用得好。

一句话总结:Cornish-Fisher VaR 用偏度和峰度两个修正项,几乎零成本地把正态 VaR 的肥尾低估补回来——但它有一个必须每次检查的有效域,越过边界就该果断换工具。

Cornish-Fisher VaR:用偏度峰度修正正态分位数,给肥尾风险一个快速估计
https://blog.halo26812.eu.org/blog/cornish-fisher-var
Author halo
Published at 2026年7月27日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨