halo 的技术博客

返回

某天收盘,你算出来「今日已实现波动率 3.1%」。昨天还是 1.2%。

你第一反应是:「市场出大事了,这是个跳跃。」

但等等——3.1% 里有几成是连续的日内波动(正常该有的),又有几成是真正的瞬时跳跃(开盘跳空、盘中闪崩、重大新闻)?如果分不开,你既没法给期权准确定价(跳跃风险要单独定价),也没法定量「今天到底有多异常」。

已实现方差 RV = Σ 收益² 做不到这一点:它把连续扩散和跳跃都装进平方和里,对跳跃极度敏感。一个 5 倍 sigma 的跳,平方后贡献 25 倍方差。

双幂变差(Bipower Variation, BV) 是 Barndorff-Nielsen & Shephard(2004/2006)的答案:它用「相邻收益绝对值的乘积」代替平方和,对跳跃免疫,只干净地估计连续部分的积分方差。本文从零复现 BV,并演示怎么用它把跳跃从波动里剥出来。

一、为什么 RV 分不清连续和跳跃#

高频对数收益离散化:

drt=σtdWt+JtdNtdr_t = \sigma_t\,dW_t + J_t\,dN_t

其中 σtdWt\sigma_t dW_t 是连续扩散,JtdNtJ_t dN_t 是泊松跳跃(瞬时位移)。

  • 真实连续方差(积分方差):IV=01σt2dtIV = \int_0^1 \sigma_t^2\,dt
  • 已实现方差:RV=t=1nrt2pIV+Jt2RV = \sum_{t=1}^{n} r_t^2 \xrightarrow{p} IV + \sum J_t^2

也就是 RV=IV+跳跃变差RV = IV + \text{跳跃变差}。RV 不仅估了连续部分,还把跳跃的平方也收了进来——所以 RV 永远 ≥ IV,且偏差完全由跳跃造成

问题就在这:你看到 RV 大,不知道是 IV 大了,还是跳大了。

二、双幂变差:用绝对值乘积「跳过」跳跃#

BV 的定义是:

BV=μ12t=2nrtrt1,μ1=2/π0.7979BV = \mu_1^{-2} \sum_{t=2}^{n} |r_t|\,|r_{t-1}|, \qquad \mu_1 = \sqrt{2/\pi} \approx 0.7979

为什么它能只估连续部分?关键点:

  1. 用绝对值而非平方:平方对极端值(跳跃)超级敏感,绝对值温和得多;
  2. 取相邻两个 bar 的乘积 rtrt1|r_t||r_{t-1}|:在连续扩散下,E[rtrt1]μ12IV/nE[|r_t||r_{t-1}|] \approx \mu_1^2 \cdot IV\,/n(用正态绝对值的一阶矩 μ1\mu_1 校正);
  3. 跳跃几乎不可能同时落在相邻两个 bar:如果你只在某个 bar 跳一次,那么乘积里最多一个因子含跳,但 rtrt1|r_t||r_{t-1}|概率极限仍由连续部分主导,跳跃项以更小速率消失——于是 BVpIVBV \xrightarrow{p} IV,完全不受跳跃影响

一句话:BV 把「平方」换成了「相邻绝对值乘积」,跳跃在乘积里被稀释掉了,连续方差被保留。

三、合成高频数据:GBM + 泊松跳跃#

造一组日内 5 分钟(78 根)对数收益,含连续扩散 + 随机泊松跳跃:

真实连续日方差 IV=σ2=0.01320.00017IV = \sigma^2 = 0.013^2 \approx 0.00017

四、单次演示:含跳日 RV/BV 立刻暴露#

取一个含跳日:

day, k = sim_day(jump=True, seed=7)
RV_d, BV_d = rv(day), bv(day)
print(RV_d, BV_d, RV_d / BV_d, k)
# 0.00019  0.00015  1.249  45
python

含跳跃的日内路径:跳跃是连续扩散之外的瞬时位移

图 1:上=累计对数价格,第 45 根 bar 的红点是一个瞬时跳(连续扩散之外的竖直位移);下=5 分钟收益,该 bar 收益明显异常。但光看这根红 bar,你分不清「这是跳、还是连续波动的尾部」——得靠 BV 来拆。

关键读出:

  • RV = 0.00019(含跳,偏大);
  • BV = 0.00015(去掉跳,只估连续,逼近真实 IV=0.00017);
  • RV/BV = 1.249 > 1——比值越偏离 1,跳跃越可疑。

五、蒙特卡洛:无跳日 vs 含跳日系统性分离#

跑 200 天(约 47.5% 的天含跳),对比两类:

M = 200; RVs, BVs, ratios, has_jump = [], [], [], []
for i in range(M):
    x, k = sim_day(jump=True, seed=100 + i)
    RVs.append(rv(x)); BVs.append(bv(x)); ratios.append(rv(x) / bv(x))
    has_jump.append(k is not None)
python

RV-BV 散点与 RV/BV 比值分布:含跳日系统性右移

图 2:左=BV(连续)对 RV(含跳)散点,对角虚线是 RV=BV 基准线,含跳日(红)整体落在线上方;右=RV/BV 比值分布,含跳日(红)系统性右移。

实跑数字:

指标含跳日(95 天)无跳日(105 天)
RV/BV 均值1.4811.023
BV 均值0.000180.00018
RV 均值(偏高)
  • 无跳日 RV/BV ≈ 1.023,紧贴 1——证明 BV 在无跳时与 RV 一致,干净还原 IV;
  • 含跳日 RV/BV ≈ 1.481,显著右偏——跳跃把 RV 抬离 BV;
  • BV 全样本均值 0.00018,几乎等于真实 IV=0.00017——BV 的连续方差估计是准的;
  • RV 全样本均值 0.00023 > IV——正是跳跃贡献的部分。

六、跳跃检验与波动分解#

把 RV/BV 当成跳跃「筛子」,阈值取 1.10 试检:

  • 含跳日命中 59/95(召回率 62%);
  • 无跳日误报 21/105(误报率 20%)。

召回不算高、误报不算低——这正是朴素阈值法的软肋,也是 BNS 要建正式检验统计量的原因(见下一节)。

更准确的做法是直接分解:

JV=max(RVBV,  0)(跳跃变差)JV = \max(RV - BV,\; 0) \qquad\text{(跳跃变差)} RV=BV+JVRV = BV + JV

RV/BV 比值时序(跳跃检测)+ 连续/跳跃方差分解

图 3:上=每日 RV/BV 时序,越过橙色阈值 1.10 的红点判为跳跃日;下=把每日总方差拆成蓝色(连续 BV)与红色(跳跃 JV)——一眼看出「波动哪天来自跳、哪天只是连续颠簸」。

七、更严谨:BNS 正式跳跃检验统计量#

朴素比值阈值依赖经验,且有限样本下方差大。BNS 给出带渐近零分布的正式检验:

\widehat{V} = \bigl(\mu_1^{-4} + 2\mu_1^{-2} - 5\bigr)\,\frac{1}{n}\sum_{t=1}^{n} |r_t|^4 \;\xrightarrow{d}\; N(0,1) \quad (\text{无跳时})$$ 其中 $\mu_1^{-4}\approx 2.466$, $\mu_1^{-2}\approx 1.571$,故系数 $\mu_1^{-4}+2\mu_1^{-2}-5 \approx 0.608$。跳跃存在时 $RV-BV>0$,$Z$ 显著为正——在 99% 置信下判跳。 实操要点:这个检验的**功效(power)随日内 bar 数 n 增大而提升**。当 n 只有 78(5 分钟)时,第四矩项 $\frac{1}{n}\sum|r_t|^4$ 偏小、Z 方差大,所以本文朴素阈值才出现 20% 误报。**把采样频率提到 1 分钟甚至 tick 级,n 上去,检验立刻变锋利**——这是下一节陷阱 1 的核心。 ## 八、四类真实陷阱 1. **日内频率不足**:BV/Z 的相合性依赖 n→∞。若只用日收益(退化成 RV 本身),BV=RV,根本分不开;用 5 分钟(78 根)尚可但功效有限(见上)。实务至少 5~15 分钟,想精细捕捉盘中跳用 1~5 分钟。 2. **微观结构噪声**:真实 tick 数据有买卖价差造成的「噪声」,会让 RV 在高频下**反而被噪声放大**(Epps 效应),BV 虽比 RV 稳健但仍受污染。落地要用更长抽样间隔或 TSRV(子采样)先去噪,再算 BV。 3. **有限样本偏差**:$\mu_1^{-2}$ 是渐近校正;小样本下 BV 仍有偏。可用有限样本修正(如加入 $\frac{n}{n-2}$ 型调整),或报告 BV 的置信区间而非单点。 4. **非交易时段与隔夜跳**:RV/BV 只在**连续交易时段**内一致。隔夜跳空、午休跳,在合成数据里被塞进第一根 bar,会污染 BV(因为它落在某个相邻乘积里)。真实落地要把隔夜收益单独处理,不混进日内 BV。 ## 九、结论 双幂变差把「波动率」这个含混的词,拆成了两个可分别定价的量: - **连续积分方差 IV**:用 **BV ≈ 0.00018** 还原(本文逼近真实 0.00017),对跳跃免疫; - **跳跃变差 JV** = $\max(RV-BV,0)$,把瞬时冲击单独剥离; - **检测**:RV/BV 比值——无跳日 ≈1.02、含跳日 ≈1.48,显著右移;正式检验用 BNS 的 $Z\sim N(0,1)$; - **分解**:RV = BV + JV,让你看清单日波动究竟「颠」在哪里。 但记住四个坑:日内频率要够、要防微观结构噪声、要校有限样本、要隔离隔夜跳。跳过任何一步,BV 给你的「连续波动」都可能是假的。 --- *本文数据均为自洽合成(日内 5 分钟 GBM + 泊松跳跃),仅用于演示方法。真实落地时:提高日内采样频率增强检验功效、用 TSRV/子采样去微观结构噪声、对 BV 做有限样本修正、隔夜收益单独处理,并把 BV/Z 接入日内波动率监控。代码已全部跑通,数字即输出。*
已实现波动率双幂变差:用 Bipower 检验把连续波动与跳跃剥开
https://blog.halo26812.eu.org/blog/realized-bipower-variation
Author halo
Published at 2026年7月19日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨