第27章 曲面在算法交易中的应用:做市商报价、Delta对冲执行
说实话,很多做期权交易的朋友,学了波动率曲面之后,第一反应是——这东西到底怎么赚钱?
我当年刚入行的时候也有这个困惑。直到我开始做做市商,才真正体会到曲面不是用来欣赏的,它是用来吃饭的。说白了,曲面就是你的报价地图和风控罗盘。
27.1 做市商报价:曲面就是你的定价引擎
做市商的核心工作是什么?报双边价格,赚买卖价差。但问题来了——市场上几百个期权合约,你不可能一个个手动算价格。
曲面就是你的批量定价工具。你只需要维护几个核心参数,整个矩阵的价格就全出来了。
我习惯的做法是这样的:
- 实时校准曲面参数——用最近成交的期权价格反推曲面参数
- 生成全矩阵波动率——根据曲面公式,算出所有行权价和期限的波动率
- 叠加做市商价差——在理论波动率上加一个偏移量,形成买卖报价
举个例子,假设我用SVI模型来拟合曲面。代码大概长这样:
import numpy as np
from scipy.optimize import minimize
class SVIMarketMaker:
def __init__(self, params):
# params: [a, b, rho, m, sigma]
self.a, self.b, self.rho, self.m, self.sigma = params
def svi_vol(self, k, t):
"""SVI模型计算波动率"""
# k: log-moneyness, t: 期限
w = self.a + self.b * (self.rho * (k - self.m) +
np.sqrt((k - self.m)**2 + self.sigma**2))
return np.sqrt(w / t)
def quote_spread(self, k, t, spread_bps=5):
"""生成双边报价"""
mid_vol = self.svi_vol(k, t)
bid_vol = mid_vol - spread_bps / 10000
ask_vol = mid_vol + spread_bps / 10000
return bid_vol, mid_vol, ask_vol
这里有个坑,我踩过好几次——曲面参数不能一成不变。市场在动,你的曲面也得跟着动。我建议每5-10秒重新校准一次,至少也要每分钟一次。
27.2 Delta对冲执行:曲面告诉你该对冲多少
做市商最怕什么?方向性风险。你报出去的价格,如果方向判断错了,可能一把亏光。所以Delta对冲是必修课。
但问题来了——Delta怎么算?很多人直接用Black-Scholes公式,输入一个波动率就完事了。这其实不对。
你想想看,不同行权价的期权,它们的隐含波动率不一样。你用同一个波动率算Delta,结果能准吗?
正确的做法是:用曲面上的局部波动率来计算每个期权的Delta。
def delta_with_surface(spot, k, t, r, surface_model):
"""用曲面波动率计算Delta"""
vol = surface_model.svi_vol(np.log(k/spot), t)
d1 = (np.log(spot/k) + (r + 0.5*vol**2)*t) / (vol*np.sqrt(t))
delta = norm.cdf(d1) # 看涨期权
return delta
# 批量计算整个组合的Delta
portfolio_delta = 0
for option in my_positions:
delta = delta_with_surface(
spot, option.strike, option.expiry,
r, surface_model
)
portfolio_delta += delta * option.quantity * option.multiplier
我遇到过一种情况——用曲面算出来的Delta,和用平值波动率算出来的,差了将近15%。对于一个千万级别的组合,这就是150万的方向敞口。你说重不重要?
27.3 曲面在算法交易中的完整流程
把上面两个部分串起来,就是一个完整的做市商算法交易系统。我画了个流程图,你看看:
这个流程里,最关键的就是那个反馈循环。每次成交之后,你要用成交价格重新校准曲面。为什么?因为成交价里包含了最新的市场信息,你的曲面必须跟上。
27.4 实战中的几个关键点
做市商不是光有曲面就够的。我总结几个实战中容易翻车的地方:
- 不要用同一个曲面参数做所有期限——近月和远月的波动率行为完全不同,我建议分期限段拟合
- 小心跳跃风险——曲面在突发事件时会剧烈变形,你的对冲策略要能快速响应
- 注意交易成本——频繁对冲会吃掉利润,我一般设置一个Delta容忍区间,比如±0.5%才动手
我曾经在一次财报发布前,曲面突然变得非常陡峭。近月期权波动率飙升,远月反而没怎么动。如果我用统一的曲面参数,近月报价就会严重偏离市场。还好我当时做了分期限拟合,及时调整了近月的参数,才没被市场打脸。
27.5 代码实战:一个简单的做市商报价系统
最后,我给你一个完整的示例代码。这个代码虽然简单,但包含了做市商报价的核心逻辑:
class MarketMakerSystem:
def __init__(self, spot, r, surface_params):
self.spot = spot
self.r = r
self.surface = SVIMarketMaker(surface_params)
self.position = {} # 持仓记录
self.delta_target = 0 # 目标Delta敞口
def update_surface(self, trades):
"""根据最新成交更新曲面"""
# 用成交数据重新拟合SVI参数
# 这里省略优化过程
pass
def generate_quotes(self, strikes, expiries):
"""生成所有合约的报价"""
quotes = {}
for t in expiries:
for k in strikes:
bid_vol, mid_vol, ask_vol = self.surface.quote_spread(
np.log(k/self.spot), t
)
# 转成价格
bid_price = bs_price(self.spot, k, t, self.r, bid_vol, 'call')
ask_price = bs_price(self.spot, k, t, self.r, ask_vol, 'call')
quotes[(k, t)] = (bid_price, ask_price)
return quotes
def hedge_delta(self):
"""执行Delta对冲"""
current_delta = self.calc_portfolio_delta()
delta_gap = current_delta - self.delta_target
if abs(delta_gap) > 0.005 * self.spot: # 0.5%阈值
# 买卖标的资产
trade_qty = -delta_gap / self.spot
execute_trade('SPOT', trade_qty)
print(f"对冲执行:买卖 {trade_qty:.0f} 股标的资产")
这个系统虽然简单,但骨架是完整的。你可以在上面加各种优化——比如用机器学习预测短期波动率变化,或者加入订单簿深度信息来优化报价策略。
好了,这一章的内容就到这里。曲面在算法交易中的应用,说白了就是两件事——用曲面定价,用曲面风控。把这两件事做好了,做市商的基本功就算扎实了。
公众号:蓝海资料掘金营,微信deep3321