1. 波动率曲面基础:什么是波动率曲面?为什么需要平滑与插值?
各位同学,欢迎来到《波动率曲面平滑与插值技术实战》的第一课。
我是你们这门课的主讲。在量化交易这行摸爬滚打了十来年,我见过太多人一上来就对着曲面做各种花哨的插值,结果回测漂亮,实盘一跑就崩。为什么?因为连最基础的东西都没搞明白。
今天,我们就先把地基打牢。聊聊波动率曲面到底是什么,以及——我们为什么非得折腾平滑和插值这档子事。
1.1 从BSM模型的一个“缺陷”说起
Black-Scholes-Merton模型,大家应该都熟悉。它假设波动率是常数。但现实呢?你随便拉一组期权数据看看,不同行权价、不同到期日的隐含波动率,几乎从来都不一样。
这就引出了两个核心现象:
- 波动率微笑(Smile):同一到期日下,虚值期权和实值期权的隐含波动率,通常比平值期权高。形状像个笑脸。
- 波动率偏斜(Skew):尤其在股票市场,虚值看跌期权的波动率往往显著高于虚值看涨期权。市场对下行风险的恐惧,都体现在这里了。
把这两个维度结合起来——行权价(或Delta)是一个轴,剩余期限(Tenor)是另一个轴,隐含波动率是第三个轴。你得到的就是一张三维曲面。
我个人习惯把曲面想象成一张“市场恐惧与贪婪的地形图”。每个点,都代表着市场参与者对未来某个时点、某个价位的不确定性定价。
3D 曲面结构示意图
1.2 为什么原始数据“没法直接用”?
你从交易所或者数据商拿到的原始数据,是什么样子的?
说白了,就是一堆散点。比如这样:
| 到期日 | 行权价 | 隐含波动率 |
|---|---|---|
| 2024-01-19 | 3.60 | 18.5% |
| 2024-01-19 | 3.70 | 17.2% |
| 2024-01-19 | 3.80 | 16.8% |
| 2024-02-16 | 3.60 | 19.1% |
| 2024-02-16 | 3.80 | 17.5% |
| 2024-03-15 | 3.70 | 18.0% |
看到问题了吗?
- 稀疏性:不是每个行权价都有报价。尤其深度实值、深度虚值,流动性差,数据经常缺失。
- 噪声:做市商的报价有买卖价差,临近收盘的报价可能失真。我见过有人拿收盘前最后一笔的异常报价去定价,结果亏得底裤都不剩。
- 不一致:不同期限的波动率,在逻辑上应该平滑过渡。但原始数据里,相邻期限的波动率可能突然跳变,这不符合市场逻辑。
1.3 平滑与插值:我们到底在解决什么问题?
好,现在问题清楚了。我们需要一个“干净”的曲面。平滑和插值,就是干这个活的。
- 插值(Interpolation):在已知数据点之间,估算出未知点的值。比如,你有1个月和3个月的波动率,想知道2个月的,就得靠插值。
- 平滑(Smoothing):去除数据中的噪声,让曲面更符合金融直觉。比如,某个点因为流动性差报了个离谱的波动率,平滑算法会把它“拉回来”。
你想想看,如果没有这两步,会发生什么?
- 你没法给任意行权价、任意期限的期权定价。
- 你算出来的风险敞口(希腊字母)是跳跃的,没法做对冲。
- 你构建的套利策略,很可能基于的是数据噪声,而不是真正的市场机会。
1.4 一个简单的插值示例(Python)
光说不练假把式。我们看一段最基础的代码。这里用scipy的线性插值,演示如何补全缺失的期限结构。
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
# 原始数据:只有1个月、3个月、6个月的波动率
tenors = np.array([30, 90, 180]) # 剩余天数
vols = np.array([0.18, 0.20, 0.22])
# 我们想知道2个月(60天)的波动率
target_tenor = 60
# 线性插值
f_linear = interpolate.interp1d(tenors, vols, kind='linear')
vol_60 = f_linear(target_tenor)
print(f"2个月(60天)的插值波动率: {vol_60:.4f}")
# 可视化
tenors_dense = np.linspace(30, 180, 100)
vols_dense = f_linear(tenors_dense)
plt.figure(figsize=(8, 4))
plt.scatter(tenors, vols, color='red', label='原始数据点', zorder=5)
plt.plot(tenors_dense, vols_dense, 'b--', label='线性插值')
plt.axvline(x=target_tenor, color='gray', linestyle=':', alpha=0.7)
plt.scatter(target_tenor, vol_60, color='green', s=100, marker='*', label='插值结果', zorder=5)
plt.xlabel('剩余期限(天)')
plt.ylabel('隐含波动率')
plt.title('期限结构线性插值示例')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
这段代码很简单。但我想强调的是:线性插值在金融里几乎不用。为什么?因为它会产生“尖角”,导致导数不连续。而我们的希腊字母,恰恰依赖于这些导数。
后面几章,我们会讲到更专业的样条插值、核回归等方法。到时候你就明白,为什么线性插值只配做“教学演示”了。
1.5 本章小结
好,我们来捋一捋今天的内容:
- 波动率曲面是隐含波动率关于行权价和剩余期限的三维映射。
- 原始数据存在稀疏、噪声、不一致三大问题,没法直接用。
- 平滑负责去噪,插值负责补全。两者结合,才能得到可用的曲面。
- 插值方法的选择很重要,线性插值只是入门,后面有更强大的工具。
嗯,这一章就到这里。下一章,我们会深入探讨“无套利约束”这个核心概念。你会发现,不是随便插个值就能用的——搞不好会插出套利空间来。
公众号:蓝海资料掘金营,微信deep3321