3、做市策略设计:经典做市策略(Avellaneda-Stoikov)、库存风险管理、报价宽度与偏移量
做市策略的核心,说白了就是回答三个问题:报多宽的价?往哪边偏?库存怎么管?
我刚开始做LOF做市的时候,以为只要挂个双边单等着吃价差就行。结果呢?被一波趋势行情直接打穿库存,亏得我怀疑人生。后来我才明白,没有策略框架的做市,跟赌博没啥区别。
今天咱们就聊聊业界最经典的做市模型——Avellaneda-Stoikov,以及它背后的库存风险管理和报价调整逻辑。
3.1 经典做市模型:Avellaneda-Stoikov
这个模型是2008年由Marco Avellaneda和Sasha Stoikov提出的。说实话,它并不复杂,但非常实用。核心思想就一句话:根据库存偏离目标水平的情况,动态调整报价。
模型假设你做市的目标是让库存维持在一个理想水平(通常是0,也就是不持仓)。当库存偏离这个目标时,你就需要调整报价来吸引反向订单,把库存拉回来。
具体来说,模型给出了两个关键公式:
// 报价偏移量(skew)
δ = -γ * (q - q_target) * σ² * (T - t)
// 报价半宽度(half-spread)
s = γ * σ² * (T - t) + (1/γ) * ln(1 + γ/κ)
其中:
q = 当前库存(以份额计)
q_target = 目标库存(通常为0)
σ = 资产波动率
γ = 风险厌恶系数(你的个人参数)
κ = 订单到达率(市场流动性参数)
T - t = 剩余做市时间
嗯,公式看着有点唬人。我拆开给你讲讲。
3.1.1 报价偏移量(Skew)
偏移量决定了你的报价是偏向买方还是卖方。公式里最关键的部分是 -γ * (q - q_target)。
- 当你库存为正(持有很多LOF份额):偏移量为负,意味着你的买价和卖价都往下移。你更愿意低价卖出,降低库存。
- 当你库存为负(做空了LOF):偏移量为正,报价整体上移。你更愿意高价买入,回补库存。
- 库存刚好为目标(0):偏移量为0,报价对称。
我在项目中遇到过一种情况:某LOF突然放量上涨,我的库存瞬间变成正持仓。按照模型,我应该下调报价赶紧出货。但当时我犹豫了,想着再等等更高价。结果呢?价格回调,我不仅没赚到价差,还亏了本金。从那以后,我严格执行模型的偏移量信号,不再凭感觉操作。
3.1.2 报价半宽度(Half-Spread)
宽度决定了你的买卖价差有多大。公式里有两个部分:
- γ * σ² * (T - t):这是库存风险溢价。波动越大、剩余时间越长,价差就要越宽,给自己留足安全垫。
- (1/γ) * ln(1 + γ/κ):这是订单到达率调整。市场流动性越好(κ越大),价差可以收窄;反之则要放宽。
你想想看,如果市场波动剧烈,你还挂着很窄的价差,那不是等着被套利者吃掉吗?
3.2 库存风险管理:做市的命门
做市最大的风险不是价格涨跌,而是库存失控。我见过太多做市商,策略赚钱的时候风光无限,结果一次黑天鹅事件,库存爆仓,前几个月的利润全吐回去。
库存风险管理,我总结了三道防线:
3.2.1 第一道防线:动态报价调整
就是上面讲的Avellaneda-Stoikov模型。通过偏移量和宽度的联动,让库存自然回归。这是最温和的手段,也是日常最常用的。
3.2.2 第二道防线:库存上限与对冲
当动态调整不够用时,你需要硬性限制。
| 指标 | 说明 | 我常用的值 |
|---|---|---|
| 最大净持仓 | 单边持仓不能超过总资金的X% | 20% |
| 最大单边敞口 | 做多或做空的绝对上限 | 总资金的30% |
| 对冲触发线 | 达到此阈值,启动对冲操作 | 15% |
我曾经在一次LOF折价套利中,库存一度占到总资金的40%。虽然模型还在报单,但那个风险敞口让我整晚睡不着。后来我加了硬性上限,超过20%就强制用期货对冲。虽然有时候会少赚一点,但睡得踏实多了。
3.2.3 第三道防线:熔断与暂停
极端行情下,做市策略必须能自己停下来。
- 价格熔断:LOF价格在短时间内波动超过X%,暂停做市。
- 库存熔断:库存达到最大上限的80%,暂停单边报价。
- 流动性熔断:市场深度骤降,价差异常扩大,暂停所有报价。
3.3 报价宽度与偏移量的实战调参
理论模型讲完了,咱们聊聊实战中怎么调参数。说实话,模型给的公式只是一个起点,真正好用的参数都是调出来的。
3.3.1 风险厌恶系数 γ
这个参数决定了你对库存偏离的敏感度。γ越大,调整越激进。
- γ偏小(0.1-0.5):适合高流动性、低波动的LOF。报价稳定,价差窄,但库存恢复慢。
- γ偏大(1.0-5.0):适合低流动性、高波动的LOF。库存恢复快,但报价跳动大,容易错过行情。
我个人习惯先从γ=0.5开始跑模拟,然后根据回测结果逐步调整。记住,没有万能参数,每个LOF都有自己的脾气。
3.3.2 波动率 σ 的估计
模型用的是历史波动率,但实战中我建议用实时波动率。
// 我常用的实时波动率计算(5分钟窗口)
σ = std(ln(P_t / P_{t-1})) * sqrt(252 * 6.5 * 12)
// 其中:
// P_t = 当前价格
// 252 = 年化交易日
// 6.5 = 每日交易小时数
// 12 = 每小时5分钟K线数
为什么要用实时波动率?因为LOF的波动特征会变。上午还风平浪静,下午可能突然放量。用固定波动率,你的报价宽度永远慢半拍。
3.3.3 订单到达率 κ 的估算
κ反映了市场流动性。我一般用过去1小时的成交笔数来估算。
| 市场状态 | κ值范围 | 报价宽度建议 |
|---|---|---|
| 高度活跃 | > 100笔/小时 | 收窄至最小宽度 |
| 正常 | 30-100笔/小时 | 使用模型计算值 |
| 低迷 | < 30笔/小时 | 放宽1.5-2倍 |
3.4 策略框架图
下面这张图展示了整个做市策略的核心逻辑。你可以看到,从市场数据输入到最终报价输出,中间经过了三个关键模块:报价引擎、库存管理器和风险控制器。
这张图里,报价引擎和库存管理器是并行工作的。报价引擎根据市场数据算出理论报价,库存管理器实时监控持仓。然后风险控制器综合两者信息,做最终裁决——要不要调整报价?要不要触发熔断?最后输出到交易所。
反馈回路也很关键。库存变化会反过来影响下一轮的报价计算,形成一个闭环。这就是Avellaneda-Stoikov模型能自适应市场的原因。
3.5 实战中的几个坑
最后分享几个我踩过的坑,希望能帮你少走弯路。
- 坑一:参数过拟合。回测表现完美的参数,实盘可能一塌糊涂。我建议用过去30天的数据做滚动回测,不要用全量数据一次性优化。
- 坑二:忽略交易成本。LOF的申购赎回费、印花税、滑点,这些都会吃掉你的利润。报价宽度至少要覆盖双边交易成本的两倍。
- 坑三:模型太复杂。我见过有人给Avellaneda-Stoikov加了十几个参数,结果哪个都调不明白。记住,做市策略的核心是库存管理,不是数学竞赛。
好了,这一章的内容就到这儿。下一章咱们聊聊如何用Python实现这个策略,包括实时数据获取、参数计算和订单管理。到时候我会把完整的代码框架分享出来。