第 5 章 · 02 VIX Calculator:Riemann+Taylor 方差互换离散化


文档摘要

第 5 章 · 02 VIX Calculator:Riemann+Taylor 方差互换离散化 本节摘要:本节啃全仓库数学密度最高的一块骨头——VIX Calculator。VIX 是 S&P 500 的"恐慌 gauge(恐慌仪表)",但作者的目标更野心勃勃:把 CBOE 白皮书里那套数学严格实现成一个可对任意商品期权、任意预测时长的通用 VIX 计算器(本节用 Henry Hub 天然气期权演示 3 个月预期)。VIX 的数学骨架是把连续的"公平价格方差互换(variance swap)"离散化——核心工具就是黎曼和(Riemann sum)+ 泰勒展开(Taylor series)。

第 5 章 · 02 VIX Calculator:Riemann+Taylor 方差互换离散化

本节摘要:本节啃全仓库数学密度最高的一块骨头——VIX Calculator。VIX 是 S&P 500 的"恐慌 gauge(恐慌仪表)",但作者的目标更野心勃勃:把 CBOE 白皮书里那套数学严格实现成一个可对任意商品期权、任意预测时长的通用 VIX 计算器(本节用 Henry Hub 天然气期权演示 3 个月预期)。VIX 的数学骨架是把连续的"公平价格方差互换(variance swap)"离散化——核心工具就是黎曼和(Riemann sum)+ 泰勒展开(Taylor series)。我们重点讲清楚五个函数:get_settlement_day 跳过周末与联邦假日算到期时间、get_forward_strike 用 call-put 价差最小处算 forward level F=K+e^{rT}*(C-P)、get_options_call/put_inclusion 选 OTM 期权(更流动性)剔 priorSettle=0、compute_sigma 用 ΣQ(K)*e^{rT}*ΔK/K² 再 *2/T-(F/K-1)²/T 算方差互换核心、compute_vix 前月后月时间加权开方 ×100。严格遵循 CBOE 白皮书。

涉及源码:原项目 VIX Calculator.py(约 416 行),数据 henry hub european options.csv + cme holidays.csv + treasury yield curve rates.csv

⚠️ 注意:本节是全书数学最硬的一节。看代码前,强烈建议先扫一眼 CBOE 白皮书(vixwhite.pdf)对方差互换与 VIX 公式的定义,否则会把 compute_sigma 里那一串 Σ、ΔK、e^{rT} 看成天书。本节的目标不是发明新公式,而是忠实复刻白皮书

学习目标

阅读完本节,你应当能够:

  1. 说清 VIX 的金融含义(S&P 500 未来 30 天预期波动率,"恐慌指数")。
  2. 解释 VIX 的数学骨架:用 Riemann sum + Taylor 把连续方差互换离散化。
  3. 还原 get_settlement_day 如何跳过周末与联邦假日、用分钟数算 time_to_expiration。
  4. 推导 forward level 公式 F = K + e^{rT}*(C-P),并解释为何取 call-put 价差最小的行权价。
  5. 讲清楚 compute_sigma 里 ΣQ(K)*e^{rT}*ΔK/K² 与 *2/T-(F/K-1)²/T 各项的含义。
  6. 解释 compute_vix 前月后月时间加权开方 ×100 的逻辑,以及为何前月后月分别代表 1 个月与 3 个月。

金融/数学原理

VIX:市场的恐慌 gauge

VIX 是 CBOE 在 1993 年推出的"波动率指数",全称 Volatility Index,被业界称作 "fear gauge(恐慌仪表)"——它反映市场对 S&P 500 未来 30 天波动率的预期。VIX 高,说明市场恐慌、预期大波动;VIX 低,说明市场平静。

官方 VIX 的构造是:3 周到期的"近月(front month)"期权 + 1 个月到期的"远月(rear month)"期权,时间加权后代表"未来 30 天"的预期波动。但作者的目标不止于此——他把 VIX 公式做成一个通用计算器,可对任意商品期权、任意预测时长计算 VIX 风格的预期波动率。本节用 Henry Hub 天然气欧式期权演示,预测时长设为 3 个月。

数学骨架:方差互换 + Riemann + Taylor

VIX 的理论根基是方差互换(variance swap)——一种场外衍生品,其公平价格的方差 swap rate 等于标的资产未来方差期望。方差互换的公平价格有一个漂亮的对数展开式:

σ² = (2/T) * E[-ln(S_T/S_0)]

其中 T 是到期时间,S 是标的。用泰勒展开(Taylor series)把对数函数 ln 展开:

ln(S/K) ≈ (S-K)/K - (S-K)²/(2K²) + ...

取二阶项,再把连续的期望 E[...] 用期权价格的积分近似——这个积分就用到**黎曼和(Riemann sum)**离散化:把行权价 K 的连续区间切成离散的期权报价点,每个点贡献一个"面积"Q(K)*ΔK/K²。最终得到 VIX 公式:

σ² = (2/T) * Σ [Q(K) * e^{rT} * ΔK / K²] - (F/K₀ - 1)² / T
  • T:到期时间(年化)。
  • Q(K):行权价 K 处的期权报价(OTM call/put 的 priorSettle)。
  • ΔK:行权价间距(半步长)。
  • F:forward level(由 call-put 平价算出)。
  • K₀:不超过 F 的最大行权价。
  • e^{rT}:贴现因子,r 是无风险利率(用国债收益率 CMT)。

最后 VIX = sqrt(σ²) × 100。这就是 CBOE 白皮书的核心公式——Riemann 离散化连续积分 + Taylor 展开对数项,本节代码就是它的忠实实现。

算法与代码精读

① get_settlement_day / get_time_to_expiration:算到期时间

L57-90get_settlement_day 算结算日:从当前日加 time_horizon 个月,定位到月末,再往前倒数跳过周末(周六日)与联邦假日,直到遇到第 expiration_day 个交易日。expiration_hour 是到期小时(天然气期权是 16:00)。

get_time_to_expiration(L100-111)直接用 timedelta 算分钟数:

return (settlement_day - current_day).total_seconds() / 60 / 525600

把结算日与当前日的秒数差转成分钟,再除以"一年的分钟数"525600(365×24×60),得到年化的到期时间 T。注意:这里算到期时间不用跳假日(那是结算日的事),直接用自然时间差即可。

② get_forward_strike:Forward Level 与 K₀

L118-136 算 forward level F 与 K₀。先 pivot 出每个行权价的 call/put 报价,找 call-put 价差绝对值最小的行权价——这就是 forward 所在:

min_diff_ind = (find_forward['call'] - find_forward['put']).apply(abs).idxmin() min_diff = float(decimal.Decimal(find_forward['call'][min_diff_ind].astype(str)) - decimal.Decimal(find_forward['put'][min_diff_ind].astype(str))) forward = min_diff_ind + np.e**(interest_rate*time_to_expiration) * (min_diff)

F = K + e^{rT}*(C - P) ——这是 call-put 平价(forward parity)的直接推论。选价差最小的 K 是为了让 e^{rT}*(C-P) 这一项的误差最小(在那个 K 上 call/put 流动性最好、报价最准)。

然后 K₀ 取不超过 F 的最大行权价:

strike = find_forward.index[find_forward.index <= forward][-1]

注意 decimal 模块:decimal.Decimal(...astype(str)) 把 float 转成字符串再转 Decimal,避开浮点误差——这是金融代码里算 forward 的标准手法,float64 在小数位上会抖动,Decimal 保证精确。

③ get_options_call/put_inclusion:选 OTM 期权

L144-175(call)与 L183-215(put)选 OTM(out-of-the-money)期权——OTM 期权流动性更好,报价更可信。call 选行权价 > K₀ 的(看涨 OTM),put 选行权价 < K₀ 的(看跌 OTM)。

关键细节是剔除 priorSettle=0 的期权:

options_call_otm_zeros = options_call_otm[options_call_otm['options-priorSettle']==0] if options_call_otm_zeros[options_call_otm_zeros['index'].diff()==1].empty: ind = len(options_call_otm) else: ind = options_call_otm_zeros['index'][options_call_otm_zeros['index'].diff()==1].iloc[0] options_call_inclusion = options_call_otm[options_call_otm['options-priorSettle']!=0][:ind]

逻辑:我们没有 bid/ask,用 priorSettle(前结算价)代替。一旦出现连续两个行权价的 priorSettle 都为 0,说明这一档已经没有交易,更远的 OTM 期权更不会有报价,全部排除index.diff()==1 就是找"连续两个 0"的起点,从那里截断。

④ compute_sigma:方差互换核心(Riemann + Taylor)

L222-245 是全节的数学高潮。对 call 与 put 两个 inclusion 集合,累加每个行权价的贡献:

contributions = 0.0 for i in [options_call_inclusion, options_put_inclusion]: for j in i.index: # ΔK:行权价间距 if j-1 < 0: delta = abs(i['options-strikePrice'][j] - i['options-strikePrice'][j+1]) elif j+1 == len(i): delta = abs(i['options-strikePrice'][j] - i['options-strikePrice'][j-1]) else: delta = abs(i['options-strikePrice'][j-1] - i['options-strikePrice'][j+1]) / 2 contributions += i['options-priorSettle'][j] * np.exp(interest_rate*time_to_expiration) * delta / (i['options-strikePrice'][j])**2 sigma = contributions * 2 / time_to_expiration - ((forward/strike - 1)**2) / time_to_expiration

逐项解读:

  • ΔK:行权价间距。中间点用左右两邻居之差的一半(中心差分),首尾点用与唯一邻居之差。这就是黎曼和的"梯形/矩形宽度"。
  • Q(K) * e^{rT} * ΔK / K²:每个行权价的"面积贡献"——期权报价(贴现到现值)乘以行权价间距、除以行权价平方。Q(K) 是被积函数,e^{rT} 是贴现,ΔK/K² 是积分微元。这就是 Riemann sum 离散化连续积分
  • * 2 / T:乘 2 除 T——对应公式里的 2/T 因子。
  • - (F/K₀ - 1)² / T:减去一个修正项,这是 Taylor 展开对数项的二阶修正——保证 σ² 是真正的方差而非近似偏差。

合起来就是白皮书里的 σ² 公式。这一行 sigma = contributions*2/T - ((forward/strike-1)**2)/T 是全节最该背下来的一行。

⑤ compute_vix:前月后月时间加权

L252-262 把前月(front)与后月(rear)的 σ² 时间加权,再开方 ×100:

sum1 = time_to_expiration_front * sigma_front * \ (time_to_expiration_rear*num_of_mins_year - num_of_mins_timeframe) / \ (time_to_expiration_rear*num_of_mins_year - time_to_expiration_front*num_of_mins_year) sum2 = time_to_expiration_rear * sigma_rear * \ (num_of_mins_timeframe - time_to_expiration_front*num_of_mins_year) / \ (time_to_expiration_rear*num_of_mins_year - time_to_expiration_front*num_of_mins_year) vix = ((sum1 + sum2) * num_of_mins_year / num_of_mins_timeframe)**0.5 * 100

num_of_mins_timeframe 是预测时长的总分钟数(3 个月 = 3×30×24×60),num_of_mins_year 是一年的分钟数(365×24×60)。前月权重与后月权重之和为 1,分别在"目标时长"两侧插值——前月离目标更近权重大,后月更远权重小。最后开方(σ² → σ)再 ×100,得到 VIX。

图: VIX计算器

上图展示了 VIX 计算器的输出:输入 Henry Hub 天然气期权数据后,打印出一个代表"未来 3 个月预期波动率"的数字。这个数字越大,说明天然气市场预期未来 3 个月波动越剧烈。

🎯 反直觉发现:本节的反直觉不在某一行代码,而在整个项目的定位。VIX 官方只算 S&P 500、只算 30 天,但作者把它抽象成一个通用方差互换离散化器——换上 Henry Hub 天然气期权,就能算天然气的"VIX";换上任意预测时长,就能算任意时间窗口的预期波动。这背后的洞察是:VIX 的本质不是 S&P 500 专属,而是"用期权报价反推方差互换公平价格"的一套数学,谁有 OTM 期权报价,谁就能算自己的 VIX。Riemann sum + Taylor 不是为了炫技,而是把"连续方差互换"这个理论概念,变成任何商品都能套用的工程工具。

关键技巧

  1. 到期时间用分钟数年化:(settlement-current).total_seconds()/60/525600,525600 = 365×24×60。
  2. 跳假日只算结算日,不算到期时间:结算日要倒数跳周末与联邦假日,到期时间直接用自然时间差。
  3. Forward 用 call-put 价差最小的 K:F = K + e^{rT}*(C-P),选价差最小的 K 保证 e^{rT}*(C-P) 误差最小。
  4. decimal 模块避浮点误差:decimal.Decimal(x.astype(str)) 算 forward,金融代码的标准手法。
  5. K₀ 取不超过 F 的最大行权价:find_forward.index[find_forward.index<=forward][-1]
  6. OTM 期权更流动:call 选 K>K₀,put 选 K<K₀;且剔除连续两个 priorSettle=0 之后的全部期权。
  7. ΔK 中心差分:中间点用左右邻居之差的一半,首尾用唯一邻居之差。
  8. CMT 国债收益率贴现:interest_rate = cmt_rate[maturity==timeframe][Date==tradedate]/100,用同期限国债收益率作无风险利率。
  9. 前月后月时间加权插值:num_of_mins_timeframe 是目标时长,前月后月在其两侧插值,开方 ×100 得 VIX。

本节要点

  1. VIX 是 S&P 500 的"恐慌 gauge",反映市场对未来 30 天波动率的预期;作者把它做成可对任意商品、任意时长的通用计算器。
  2. 数学骨架:Riemann sum 离散化连续方差互换 + Taylor 展开对数项,严格遵循 CBOE 白皮书。
  3. get_settlement_day 跳周末与联邦假日算结算日;get_time_to_expiration 用分钟数/年分钟数算 T。
  4. get_forward_strike:F = K + e^{rT}*(C-P),取 call-put 价差最小的 K;K₀ 是不超过 F 的最大行权价。
  5. get_options_call/put_inclusion 选 OTM 期权(更流动),剔除连续 priorSettle=0 之后的所有档。
  6. compute_sigma:σ² = Σ[Q(K)*e^{rT}*ΔK/K²]*2/T - (F/K₀-1)²/T,这是 Riemann + Taylor 的最终落地。
  7. compute_vix:前月后月 σ² 时间加权,开方 ×100 得 VIX。
  8. 关键技巧:decimal 避浮点误差、CMT 国债收益率贴现、ΔK 中心差分。

第 5 章到此结束。我们从线性的股票/期货世界跨入了非线性的期权世界——Straddle 教会我们"赌波动率而非方向"和"quantamental 选行权价",VIX Calculator 教会我们"用 Riemann+Taylor 把理论方差互换变成任意商品可用的工程工具"。下一章,我们将把这些思维全面展开——Oil Money 是一个 quantamental 大项目,把基本面(石油产量、GDP、利率)与量化(协整、聚类、回归)熔于一炉,正是 Straddle 节那个观点的终极实践。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U