第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 本章小结

曲面构建是波动率交易的基础。插值法简单实用,参数化模型更强大。记住:没有完美的模型,只有适合场景的方法。

嗯,今天就到这里。下一章我们会讲异常点检测——到时候我会分享一个真实案例,那次我差点因为一个异常点亏掉整个月的利润。


专注资料整理