第20章 波动率套利:统计套利在波动率曲面上的应用、配对交易
波动率套利,说白了就是利用期权定价中的“错误”来赚钱。很多人一听套利就觉得是稳赚不赔的买卖,其实不然。我做了这么多年,真正意义上的无风险套利机会少得可怜,更多时候我们做的是统计套利——赌的是波动率会回归到某个合理范围。
这一章,我们就聊聊怎么在波动率曲面上做统计套利,以及配对交易的具体玩法。
波动率曲面的“异常”信号
先问一个问题:你见过完美的波动率曲面吗?反正我没见过。真实市场里,曲面总是坑坑洼洼的。有些行权价的隐含波动率明显偏高,有些又偏低。这些偏差,就是我们的机会。
我个人习惯把波动率曲面想象成一张橡皮膜。正常情况下它应该是平滑的,但如果有人在某个点用力扯了一下,就会出现一个“鼓包”。这个鼓包迟早会消下去——要么被市场修复,要么被套利者抹平。
核心逻辑:统计套利不追求100%确定,而是追求概率优势。我们找的是那些偏离历史均值超过2个标准差的点。
统计套利的具体步骤
嗯,这里要注意,统计套利不是瞎蒙。我一般按下面几步来走:
- 构建基准曲面——用SVI或SSVI模型拟合出“理论”波动率曲面
- 计算残差——每个行权价、每个到期日的实际IV减去理论IV
- 标准化残差——除以历史标准差,得到z-score
- 设定阈值——|z-score| > 2 时视为交易信号
- 执行配对交易——做多被低估的期权,做空被高估的期权
我曾经在2019年做过一次统计套利,当时某科技股的虚值看涨期权IV比模型值高了30%。我果断做空那个期权,同时用Delta对冲掉方向风险。结果一周后IV回归,赚了差不多15%的波动率溢价。
小技巧:别只看单一期限。跨期限的曲面异常往往更可靠。比如近月IV偏高、远月正常,这种结构通常意味着短期情绪过度,反转概率大。
配对交易:波动率曲面的“多空组合”
配对交易在波动率曲面上的应用,其实和股票配对交易思路一样——找到两个相关性高的品种,做多一个、做空另一个,赌它们的价差回归。
但在期权市场,我们配对的是波动率,不是价格。具体来说:
- 同标的、不同期限:比如做多1个月ATM期权,做空3个月ATM期权。赌期限结构回归。
- 同标的、不同行权价:比如做多虚值看跌,做空平值看跌。赌偏斜形态回归。
- 不同标的、同特征:比如做多银行股波动率,做空科技股波动率。赌板块间波动率关系回归。
你想想看,为什么这些配对能赚钱?因为市场情绪会传染,但也会消散。当恐慌来临时,所有期限的IV一起飙升,但短期IV涨得更多。等恐慌消退,短期IV跌得也更猛。这就是期限结构套利的逻辑基础。
实战案例:期限结构套利
我记得有一次,标普500指数因为某个突发事件,近月IV一下子从15%飙到35%,但远月IV只从18%涨到22%。这明显不合理——突发事件的影响不可能持续那么久。
我当时做了这样一个组合:
| 头寸 | 合约 | 方向 | 权重 |
|---|---|---|---|
| 做空 | 近月ATM期权 | 赌IV下跌 | 1份 |
| 做多 | 远月ATM期权 | 赌IV上涨(或至少不跌那么多) | Vega中性配比 |
关键是要做到Vega中性——也就是整体组合对波动率变化的净敞口为零。这样我们赚的就是期限结构回归的钱,而不是赌波动率涨跌。
避坑指南:我曾经犯过一个错误——只做了Vega中性,但没考虑Theta。结果期限结构确实回归了,但时间价值损耗把利润全吃掉了。后来我学乖了,做配对交易时一定要同时检查Vega和Theta的净敞口。
代码示例:波动率曲面残差计算
下面是一个简单的Python代码,用来计算波动率曲面的残差并识别套利机会。代码不复杂,但很实用。
import numpy as np
import pandas as pd
from scipy.optimize import curve_fit
# SVI模型参数化
def svi_model(k, a, b, rho, m, sigma):
return a + b * (rho * (k - m) + np.sqrt((k - m)**2 + sigma**2))
# 假设我们有一组市场IV数据
# strikes: 行权价对数偏离值
# iv: 隐含波动率
strikes = np.array([-0.1, -0.05, 0, 0.05, 0.1])
iv = np.array([0.25, 0.22, 0.20, 0.21, 0.24])
# 拟合SVI模型
popt, _ = curve_fit(svi_model, strikes, iv,
p0=[0.1, 0.1, -0.5, 0, 0.1])
# 计算理论IV
iv_fitted = svi_model(strikes, *popt)
# 计算残差
residuals = iv - iv_fitted
# 标准化残差(假设历史标准差已知)
hist_std = 0.015 # 历史残差标准差
z_scores = residuals / hist_std
# 识别套利信号
for i, z in enumerate(z_scores):
if abs(z) > 2:
print(f"行权价 {strikes[i]:.2f}: z-score = {z:.2f}, 信号级别")
elif abs(z) > 1.5:
print(f"行权价 {strikes[i]:.2f}: z-score = {z:.2f}, 关注级别")
实际应用提示:代码里的历史标准差需要定期更新。我一般用滚动60个交易日的窗口来算,这样能自适应市场环境变化。
波动率套利的风险控制
做统计套利,最怕的就是“统计规律失效”。说白了,就是市场结构变了,历史规律不再适用。比如2020年3月那波,所有波动率模型都失效了,因为市场进入了前所未有的极端状态。
我的风控原则很简单:
- 单笔最大亏损控制在组合净值的2%以内
- 持仓周期不超过2周——统计套利赚的是回归的钱,拖久了容易出问题
- 每天重新计算z-score——如果信号消失,立即平仓,不要恋战
我曾经有一次没及时止损,结果z-score从2.5涨到了4.0,亏了差不多5%。从那以后,我给自己定了个规矩:信号消失就撤,哪怕后面又回归了也不后悔。
本章核心逻辑图
下面这张SVG图,把波动率统计套利的完整流程画出来了。从数据输入到信号执行,一目了然。
这张图把整个流程串起来了。你从左上角开始看,一步步往下走。核心就是那个菱形判断框——|z| > 2?是就干,不是就等。简单粗暴,但有效。
好了,波动率统计套利的内容就这些。记住一句话:套利不是捡钱,是赚概率的钱。做好风控,严格执行信号,长期下来一定能赚钱。