第1章:曲面构建方法——插值法与参数化模型
大家好,我是你们的讲师。今天咱们聊聊波动率曲面构建这件事。说实话,我刚入行那会儿,觉得曲面构建就是个数学游戏,直到有一次实盘交易吃了大亏——嗯,后面我会讲到那个故事。
波动率曲面,说白了就是不同行权价、不同到期日的隐含波动率拼成的一张网。但问题来了:市场上能拿到的期权报价是离散的,你不可能每个行权价、每个到期日都有数据。怎么办?就得靠构建方法把这张网织出来。
核心思路:用有限的数据点,推算出整个曲面的形状。方法分两大类——插值法和参数化模型。
2.1 插值法:简单粗暴,但够用
插值法,我习惯叫它「填坑法」。你有几个已知点,想办法把中间的空缺填上。最常用的两种:线性插值和样条插值。
2.1.1 线性插值
线性插值是最简单的。两点之间画条直线,中间的值按比例算。举个例子:
# 线性插值示例
import numpy as np
from scipy import interpolate
# 已知数据点
strikes = np.array([90, 100, 110])
vols = np.array([0.25, 0.20, 0.22])
# 线性插值函数
f_linear = interpolate.interp1d(strikes, vols, kind='linear')
# 在95处插值
vol_at_95 = f_linear(95)
print(f"95行权价的波动率: {vol_at_95:.4f}")
输出结果:
95行权价的波动率: 0.2250
你看,90到100之间,波动率从0.25降到0.20,95正好在中间,所以是0.225。简单吧?
我的经验:线性插值适合快速预览,但别用在正式交易中。为什么?因为它会产生「尖角」——在数据点处导数不连续,这在期权定价里会出问题。
2.1.2 样条插值
样条插值就聪明多了。它用分段多项式来拟合,保证曲线光滑。我最常用的是三次样条——每个区间用三次多项式,连接处一阶、二阶导数都连续。
# 三次样条插值
f_spline = interpolate.interp1d(strikes, vols, kind='cubic')
# 生成密集点画图
strikes_dense = np.linspace(85, 115, 100)
vols_linear = f_linear(strikes_dense)
vols_spline = f_spline(strikes_dense)
# 对比一下
print("线性插值在95处:", f_linear(95))
print("样条插值在95处:", f_spline(95))
注意:样条插值虽然光滑,但容易「过拟合」。我曾经在极端行权价处看到样条插出负波动率——这在金融里是荒谬的。所以,边界处理要格外小心。
2.2 参数化模型:SVI与SSVI
插值法有个硬伤:它只拟合已知点,对未知区域的外推能力很差。参数化模型就不一样了——它用一个数学公式来描述整个曲面。我个人最常用的是SVI模型。
2.2.1 SVI模型
SVI(Stochastic Volatility Inspired)模型,名字听着高大上,其实公式很简洁:
w(k) = a + b * (rho * (k - m) + sqrt((k - m)^2 + sigma^2))
其中:
- w(k) 是总方差(波动率平方 × 到期时间)
- k 是行权价的对数(log-strike)
- a, b, rho, m, sigma 是五个参数
这五个参数各有含义:
| 参数 | 含义 | 典型范围 |
|---|---|---|
| a | 整体水平 | 通常 > 0 |
| b | 倾斜程度 | 通常 > 0 |
| rho | 偏斜方向 | [-1, 1] |
| m | 曲线中心 | 实数 |
| sigma | 曲率 | 通常 > 0 |
# SVI模型实现
def svi_vol(k, a, b, rho, m, sigma):
"""计算SVI波动率"""
w = a + b * (rho * (k - m) + np.sqrt((k - m)**2 + sigma**2))
return np.sqrt(w) # 返回波动率
# 示例参数
params = {'a': 0.04, 'b': 0.1, 'rho': -0.5, 'm': 0.0, 'sigma': 0.2}
k_test = np.linspace(-0.5, 0.5, 10)
vols_svi = svi_vol(k_test, **params)
print("SVI波动率:", vols_svi)
为什么我喜欢SVI?因为它参数少、解释性强,而且能保证无套利条件。我在做期权做市商系统时,就用SVI来实时校准曲面——每秒更新一次参数,效果很好。
2.2.2 SSVI模型
SSVI(Surface SVI)是SVI的升级版,专门处理整个曲面(多个到期日)。它加了一个时间结构函数phi(T),让参数随时间平滑变化。
# SSVI模型(简化版)
def ssvi_vol(k, T, theta, phi, rho):
"""
theta: 平价波动率(ATM vol)
phi: 时间结构函数
rho: 偏斜参数
"""
w = theta * (1 + rho * phi * k + np.sqrt((phi * k + rho)**2 + 1 - rho**2))
return np.sqrt(w / T) # 转换为波动率
# 示例
T = 0.5 # 半年到期
theta = 0.2**2 * T # ATM总方差
phi = 0.5
rho = -0.7
k_test = np.linspace(-0.3, 0.3, 5)
vols_ssvi = ssvi_vol(k_test, T, theta, phi, rho)
print("SSVI波动率:", vols_ssvi)
避坑指南:我曾经在SSVI的参数校准上栽过跟头。phi函数的选择很关键——用错了会导致曲面在远月出现「蝴蝶效应」,即价差套利机会。后来我改用分段phi函数,才解决了这个问题。
2.3 插值法 vs 参数化模型:怎么选?
这个问题我经常被问到。我的建议是:看场景。
- 快速原型、数据预览 → 线性插值就够了
- 需要光滑曲面、风险计算 → 样条插值
- 做市、实时定价、套利检测 → SVI/SSVI参数化模型
- 研究分析、学术论文 → 参数化模型更受认可
我个人习惯是:先用样条插值快速看个大概,再用SVI做精细校准。两个方法互补,不是非此即彼。
2.4 本章小结
曲面构建是波动率交易的基础。插值法简单实用,参数化模型更强大。记住:没有完美的模型,只有适合场景的方法。
嗯,今天就到这里。下一章我们会讲异常点检测——到时候我会分享一个真实案例,那次我差点因为一个异常点亏掉整个月的利润。