Avellaneda-Stoikov 做市:用库存风险与最优报价拆解买卖价差
用固定种子(20260801)、200 步 tick 级受控模拟,从零复现 Avellaneda-Stoikov (2008) 最优做市模型:保留价格随库存线性偏移,最优价差由「库存风险项」与「成交激励项」两部分构成。核心结论:A-S 的库存偏移报价把终端库存方差相对对称做市砍掉 86.3%(库存标准差 8.14→3.01),代价只是期望利润小幅下降(60.9→57.1),但夏普从 4.71 翻到 9.04——控住库存换来的风险调整收益几乎翻倍。风险厌恶 γ 是一根旋钮:γ 从 0.01 升到 1.0,期望利润从 60.3 单调降到 28.2、库存标准差从 5.35 压到 1.68、夏普在 γ≈0.1 处见顶(9.18)。但最冷的水在最后:教科书参数下这个策略是台印钞机(夏普 9、破产概率 0%),这恰恰是危险信号。一旦注入未知趋势(毒性流)与每笔成本,边际瞬间崩塌——趋势把夏普从 9.3 压到 5.1,而每笔 0.6 的成本(竞争+逆向选择)直接把夏普打到 0.84、破产概率抬到 14%,成本升到 0.9 时 99% 的路径都在亏钱。对抗式检验三项全过:库存为 0 时保留价=中间价、零波动率时价差退化为纯激励项 1.29、γ→0 时价差收敛到 2/κ=1.33。
问题:做市商到底在赚什么、又在怕什么#
做市(market making)表面上是一门”两头赚差价”的生意:在买一挂个买单、在卖一挂个卖单,被买方成交一次、卖方成交一次,就赚到一个价差。听起来像永动机。
但真做过的人都知道,做市的敌人不是”赚不到价差”,而是库存。当你的买单被大量成交,你手里就堆了一堆多头库存 ;如果这时候市场往下走,你的存货就在亏钱——你赚的那点价差远不够填坑。做市商的核心矛盾是:想多成交(多赚价差)就得把报价挂得离中间价近,但挂得越近、成交越频繁,库存越容易失控。
Avellaneda & Stoikov 在 2008 年给了这个矛盾一个漂亮的解析解。它的核心洞察是:不要围绕中间价对称报价,要围绕一个”保留价格”报价,而这个保留价格会随你手里的库存自动偏移——库存多就整体下移(引导别人从你这买走、去库存),库存空就整体上移(引导别人卖给你、补库存)。
本文用一个固定随机种子(20260801)、200 步的 tick 级受控模拟,从零把这个模型跑出来,回答三个问题:A-S 的库存偏移到底值多少钱?风险厌恶 γ 这根旋钮怎么调?以及最重要的——这套东西在真实世界里还剩多少?
先把结论摆前面:在教科书参数下,A-S 相对朴素对称做市把库存方差砍掉 86.3%、夏普从 4.71 翻到 9.04;但这个夏普 9 本身就是个危险信号,加入未知趋势和每笔成本后,它会在几档之内崩到 0.84、破产概率抬到 14%。
模型与模拟设计#
三个核心公式#
保留价格(reservation price)——做市商心里真正的”公允价”,随库存 线性偏移:
其中 是中间价, 是当前库存, 是风险厌恶, 是波动率, 是到收盘的剩余时间。库存为正时 (心里价比市场价低,急着卖);库存为负时 (急着买)。
最优总价差(optimal spread)——买卖两个报价的总宽度:
它由两块拼成:前一项 是库存风险项(越怕风险、波动越大、离收盘越远,价差越宽);后一项 是成交激励项(由订单簿深度 决定,是你愿意为”多成交”让出的利润)。
报价摆放:买卖报价围绕保留价格 对称摆放,而不是围绕中间价 :
成交强度:一个报价离中间价越远,越不容易成交。成交强度按指数衰减:
在每个时间步 内成交的概率取 。
模拟设定#
中间价走几何布朗式随机游走(),初始价 ,,交易周期 (一个交易日归一化),步长 (共 200 步)。基准参数 、、。做市商每一步按 A-S 最优报价挂买卖单,成交后更新库存 与现金,终端 PnL = 现金 + 库存按收盘中间价的市值。全部用 numpy 向量化,几千条路径同步推进。
对抗式检验:先证明公式没写错#
在跑任何模拟之前,先用三个极限情形做 sanity check——一个连极限都过不了的实现,出的数字再漂亮也是假的:
- 库存为 0 时,保留价格必须等于中间价:。✅ 通过。
- 零波动率时,价差退化为纯成交激励项:令 ,库存风险项归零,价差应只剩 。实测价差 = 1.290770,与解析激励项 1.290770 完全吻合。✅
- γ→0 时,价差收敛到 ,库存偏移项归零:当风险厌恶趋近于 0,,策略退化为激进的对称做市。实测 γ=1e-7 时价差 = 1.333334,理论 = 1.333333。✅
三项全过。作为对照,基准参数下()开盘时的完整最优价差是 1.690770(= 库存风险项 0.4 + 激励项 1.29077),后面所有结果都建立在这个已验证的引擎上。
逐图分析#
图1:保留价格如何随库存偏移#

上图是单条路径的完整演示。黑线是中间价 ,红色虚线是保留价格 ,蓝绿两条细线是卖出/买入报价。关键看红线相对黑线的偏移:下方库存面板显示库存为红色(净多头)的时段,保留价格与整条报价带整体压在中间价下方——做市商在”降价甩货”;库存翻绿(净空头)时,报价带整体抬到中间价上方——在”抬价补货”。
这不是视觉错觉:这条路径上库存与”保留价-中间价”偏移的相关系数是 −0.6169,负相关正是模型的设计意图。库存最大绝对值到过 6 手。还有一个容易忽略的细节:越靠近收盘(),,库存风险项消失,报价带重新收敛成围绕中间价对称——因为再没有时间被库存反噬了。
图2:A-S vs 朴素对称做市,库存方差砍掉 86%#

这是全文最核心的对照。对手是”朴素对称做市”:用同样宽度的价差,但永远对称挂在中间价两侧、完全无视库存。4000 条路径下:
- 终端库存:对称做市的库存标准差 8.14、平均绝对库存 6.48 手;A-S 是 3.01 和 2.37 手。库存方差降低 86.3%。左图里橙色(对称)胖而散,蓝色(A-S)瘦而聚。
- 终端 PnL:对称做市均值 60.86、标准差 12.92;A-S 均值 57.11、标准差 6.32。
读法要诚实:A-S 的期望利润其实略低(57.1 vs 60.9,因为它为了控库存有时会主动错过成交)。但它把 PnL 波动几乎砍半。两者一除,A-S 的夏普是 9.04,对称做市只有 4.71——控住库存换来的风险调整收益几乎翻倍。这就是 A-S 的全部价值:它不是让你多赚,是让你赚得更稳。
图3:风险厌恶 γ 是一根有代价的旋钮#

γ 不是越大越好,也不是越小越好,它是一条有效前沿上的位置选择。扫描 γ 从 0.01 到 1.0:
| γ | 期望利润 | 库存标准差 σ(q) | 成交笔数 | 开盘价差 | 夏普 |
|---|---|---|---|---|---|
| 0.01 | 60.27 | 5.35 | 90.3 | 1.37 | 6.63 |
| 0.10 | 57.15 | 3.04 | 85.4 | 1.69 | 9.18 |
| 0.35 | 47.98 | 2.15 | 74.8 | 2.60 | 8.22 |
| 1.00 | 28.23 | 1.68 | 50.4 | 5.02 | 6.17 |
机制很清楚(右图):γ↑ → 价差变宽 → 成交量下降 → 期望利润下降,但同时库存风险也被压得更小。左图的散点连成一条向右上凸的前沿:想要更低的库存风险,必须交出期望利润。有意思的是夏普并非单调——它在 γ≈0.1 附近见顶(9.18),因为 γ 太小则库存失控(分母大),太大则利润被价差挤没(分子小)。这说明”最优风险厌恶”是个可优化的中间值,不是拍脑袋的极端。
图4:泼冷水——教科书里的印钞机,一碰现实就崩#

到这里为止,A-S 看起来完美得可疑:6000 条路径的中性市场里,均值 57.06、夏普 9.00、破产概率 0%、最差的一条也赚 31.54。一个夏普 9、从不亏钱的策略——这本身就是最大的危险信号。真实做市桌子上没有人的夏普是 9。
问题出在哪?出在两个被教科书假设掉的东西:
一是未知趋势(毒性流/知情交易)。 我给每条路径注入一个未知漂移(,代表”这天到底是趋势市还是震荡市”你事先不知道)。当市场真出趋势,做市商的库存会被反复往一个方向打——你的卖单一直被知情买家吃掉,库存越来越空,而价格还在涨,补回来的成本越来越高。扫描下来:趋势强度从 0 升到 18,夏普从 9.26 一路压到 5.09,最差路径从 +37.6 掉到 −16.4。趋势没能制造大面积破产(因为价差收入太厚),但它实实在在地咬掉了一半的风险调整收益。
二是每笔成本(手续费 + 竞争压缩价差 + 逆向选择)。 现实里价差不是你说了算,是被竞争压出来的,而且你每笔成交都要付费、还系统性地在坏价格上被知情方成交。我在”趋势市”基础上叠加一个每笔单边成本,扫描结果是全文最冷的一张表:
| 每笔成本 | 均值 PnL | 夏普 | 破产概率 |
|---|---|---|---|
| 0.00 | 57.09 | 6.48 | 0.0% |
| 0.30 | 31.42 | 4.10 | 0.1% |
| 0.45 | 18.64 | 2.64 | 1.0% |
| 0.60 | 5.76 | 0.81 | 14.0% |
| 0.90 | −19.86 | −2.75 | 99.0% |
在”趋势 + 每笔 0.6 成本”的现实情景下(右图红色分布),均值 PnL 从 57 塌到 5.83、夏普从 9 塌到 0.84、破产概率从 0 抬到 14%、最差路径亏 42.6。而当成本升到 0.9(约半个价差的量级),99% 的路径都在亏钱。左图两条分布的对比极其刺眼:蓝色是教科书幻觉,红色是加了两桶冷水后的真实尾部。
结论:杀死朴素 A-S 的不是库存风险本身(A-S 恰恰把库存控得很好),而是竞争与成本对价差的侵蚀。整套模型的全部利润都活在”你能以低成本捕获一个够宽的价差”这个假设里,一旦这个假设松动,边际就在几档之内蒸发。
关键代码:报价逻辑#
整个策略的心脏其实只有几行——每一步计算保留价格、算最优价差、围绕保留价格摆买卖单,然后用指数强度决定是否成交:
for i in range(N):
t = i * DT
# 最优总价差 = 库存风险项 + 成交激励项
spread = gamma * sigma**2 * (T - t) + (2.0 / gamma) * np.log(1.0 + gamma / KAPPA)
if strategy == "as":
# 保留价格随库存偏移:库存多则下移,引导卖出
r = s - q * gamma * sigma**2 * (T - t)
p_ask = r + spread / 2.0 # 围绕保留价格摆卖单
p_bid = r - spread / 2.0 # 围绕保留价格摆买单
else: # 朴素对称做市:无视库存,永远对称挂中间价两侧
p_ask = s + spread / 2.0
p_bid = s - spread / 2.0
# 报价离中间价越远,成交强度越低(指数衰减)
d_ask, d_bid = p_ask - s, s - p_bid
p_fill_ask = 1.0 - np.exp(-A * np.exp(-KAPPA * d_ask) * DT)
p_fill_bid = 1.0 - np.exp(-A * np.exp(-KAPPA * d_bid) * DT)
ask_fill = rng.random(M) < p_fill_ask
bid_fill = rng.random(M) < p_fill_bid
# 成交结算:卖出减库存加现金,买入加库存减现金(cost 为每笔单边成本)
cash += ask_fill * (p_ask - cost); q -= ask_fill.astype(float)
cash -= bid_fill * (p_bid + cost); q += bid_fill.astype(float)
s = s + drift * DT + sigma * np.sqrt(DT) * rng.standard_normal(M) # 中间价游走pythonA-S 分支和对称分支的唯一区别,就是报价围绕 r 还是围绕 s——一行之差,换来 86% 的库存方差降低。
三段式总结#
A. 实现细节#
- 信号与执行时点:每一步先用当前中间价 和库存 算报价(signal-on-i),同一步内判定是否成交(execute-on-i),成交结算完再让中间价游走一步。避免用未来价格反算当期成交。
- 成交判定:每步每边成交概率取 (Poisson 首次到达),。成交只判”成/不成”,单位成交量固定为 1 手(A-S 原始设定)。
- PnL 口径:终端 PnL = 累计现金流 + 终端库存 × 收盘中间价,即库存按市价 mark-to-market,不做提前平仓。
- 对称基准的公平性:对称做市用与 A-S 完全相同的价差公式和同一批价格随机数,唯一区别是报价中心( vs ),确保对比只反映”库存偏移”这一个变量。
- 成本与趋势建模:
cost为每笔单边成本(现金流中直接扣减),drift支持每条路径抽一个未知漂移来模拟毒性流/趋势市。全程固定种子20260801。
B. 已知偏差#
- 中间价是无漂移 GBM,且波动率 对做市商完全已知——这是 A-S 相对现实最大的美化。真实 要估计、会跳、有厚尾,估错 会直接算错价差。
- 成交强度参数 恒定且已知:真实订单簿深度随行情剧烈变化, 在波动时会塌。
- 无队列/延迟/被抢单:模型假设你的报价一挂就在队首,忽略了排队优先级、撤改单延迟、被更快的对手抢成交——这些在真实做市里往往是胜负手。
- 逆向选择建模是粗粒度的:本文用”每笔成本”作为竞争+逆向选择的合并代理,没有显式区分”知情单打你”和”手续费”,也没做成交概率的买卖不对称。
- 单标的、单位成交量:忽略了多品种对冲、成交量分布、以及大库存对自身报价的冲击。
C. 结果解读#
- 库存偏移是真价值,但价值形式是”降险”不是”增收”:A-S 期望利润比对称做市还低 6%(57.1 vs 60.9),它的贡献全在把库存方差砍掉 86.3%、夏普翻倍(4.71→9.04)。如果你的目标函数只看总收益不看波动,A-S 对你没意义。
- γ 有最优中值,不是极端:夏普在 γ≈0.1 见顶(9.18),过小库存失控、过大利润被价差挤没。调 γ 本质是在”库存方差”和”期望利润”这条前沿上选点。
- 利润来源高度集中于价差捕获:中性市场里库存与终端 PnL 几乎不相关(因为库存被 A-S 控住了),说明钱主要来自稳定的价差收入,而非方向性押注——这既是优点(稳),也是软肋(一旦价差被压缩,利润无处可寻)。
- 真正的尾部来自成本而非库存:趋势市把夏普从 9.3 压到 5.1 但几乎不制造破产;而每笔 0.6 的成本就能把夏普打到 0.84、破产概率抬到 14%,0.9 时 99% 亏损。这告诉你把研发精力放哪:不是继续优化库存控制,而是死磕成交成本、排队优先级和价差竞争。
- 可交易性冷水:教科书参数下的夏普 9、零破产是一面镜子——任何回测里出现这种数字,第一反应应该是”我假设掉了什么”,而不是”我发财了”。A-S 是理解做市结构的绝佳框架,但直接照搬它的报价去实盘,等于假设自己能免费捕获一个宽价差,这个假设在有竞争的市场里几乎不成立。