Avellaneda-Stoikov 做市:保留价和库存风险
做市看上去简单:双边报价、赚点差。难在库存会积累、价格会动、报价太紧会被打穿。Avellaneda-Stoikov (2008) 把这套权衡解成两条公式:保留价和最优价差。
做市是金融里理论上最干净、实际上最难的策略。逻辑简单:挂买卖报价,赚点差,管理库存。现实是:你的成交是随机的,价格在动,库存会在你最不想要的方向上越积越多。做市商每一秒都在回答两个问题——报价中心放哪、点差开多宽——而这两个问题的答案互相纠缠。
数学上的现代处理是 Avellaneda-Stoikov (2008)。它的漂亮之处在于把这两个问题干净地解耦了:报价中心由一条保留价公式决定,点差由另一条公式决定,各管各的经济学。这是学术做市的标准参考,也是很多量化做市策略的骨架。Harris 在第 13 章专门讲了做市,对 dealer 行为有大量讨论。下面把模型和两条公式推出来,再讲怎么把它落到实盘。
做市商的问题
你在资产 上做市。你挂买价 和卖价 ,中间价 ,半点差 。
流量是价格敏感的:买方以速率 到达(你的买价越不激进,等得越久),卖方以速率 到达(同理)。有人打你的买价,你买入,库存增加;有人抬你的卖价,你卖出,库存减少。你持有库存 (正 = 多,负 = 空)。中间价在最简版本里是无漂移布朗运动:
目标是最大化终点财富的期望效用。Avellaneda-Stoikov 用指数效用:
其中 是终点现金、 是终点库存按中间价的市值, 是风险厌恶。指数效用不是随手选的:它让最优策略不依赖财富水平,问题才解得动。变体里也有人加库存的运行惩罚项,结构不变。
注意这个设定里没有知情交易者——价格是外生的,流量只对你的报价距离敏感。这一点等下对比 Glosten-Milgrom 时会变得重要。
Avellaneda-Stoikov 解
用值函数 ——库存 、中间价 、时刻 下的最优继续价值——写 HJB 方程求解,最优报价的结构是:
报价不再围着中间价摆,而是围着一个新的中心 ——保留价——摆。这就是前面说的解耦:先定中心,再定宽度。
保留价是市商在买和卖之间无差异的价格:
其中 是当前库存, 是风险厌恶, 是中间价波动率, 是剩余时间。读一下它的方向:你多仓()时,保留价压到中间价之下——你愿意便宜点卖(想降库存),买入则要求更低的价。空仓反过来。偏移量随波动率和剩余时间放大:仓位可能伤你越狠、你还要扛它越久,你就把整个报价结构挪得越狠。
宽度那半的答案是最优半点差:
其中 是到达速率对报价距离的弹性(流量模型里 的那个 )。在 的极限(很流动的市场,流量对价格极敏感)下:
两项各有各的经济学,值得分开看。
第一项 是库存风险的价码。风险厌恶越高、波动越大、剩余时间越长,它越宽。逻辑是:在波动的市场里持有库存有风险,点差是你收的风险补偿。点差开宽了,成交概率下降、流量变少,但每笔的利润变厚——这条公式就是在这个权衡上取的最优。
第二项 是基础点差:即使零库存你也要报的宽度。它由流量弹性定价—— 大(流量对价格敏感,流动市场),你收不了多少租,点差紧; 小(流量无弹性),你可以收宽点差。经验上流动市场的 更大,加密主流品种的 比小盘股高。要说清楚的是:在 AS 模型内部,这一项来自流量弹性,不是逆向选择——模型里根本没有知情交易者。现实中逆向选择当然存在,它是你在模型外要另外补的账,下面会回到这一点。
合起来
把保留价和半点差拼起来,最优报价是:
时报价关于中间价对称。(多仓)时,整个结构下移:买卖价都低,你在劝市场买你的货、别再卖给你。 时上移,反之。库存重到一定程度,你的卖价甚至会压到中间价以下——不是 bug,是模型在逼你降库存。
一个数值算例(含一个单位陷阱)
先踩坑。有人拿”看着顺眼”的参数直接算:,。基础点差 = ——每边 0.65 美元?对一只 $100 的股票这是 130 bp 的全点差,荒谬地宽。数字没算错,错在把 $\gamma\kappa$当成了无量纲数。它们都带单位(1/价格),跟$\sigma^2$(价格²/时间)、$T-t$(时间)必须配套。参数不配单位,这个模型给出的报价可以差出几个数量级——这是用 AS 时的第一检查项。
配好单位重来。股价 ,日波动 2%(即 美元/√天,),剩余水平期 天(约 40 分钟),(1/美元),(1/美元),库存 股多仓。
保留价偏移: 美元,所以 。
半点差:库存分量 ,可以忽略;基础分量 美元。半点差 。
报价:买 ,卖 。
看清楚发生了什么:你的卖价 $99.90 低于中间价 $100.00。500 股的多仓让模型宁可”亏”10 美分相对中间价出货,也不愿继续抱着库存赌方向。这就是保留价机制的全部意义——报价中心跟着库存走,点差只管宽度。实操的量级感:(库存每股的报价偏移斜率)配出来后,主动做市商的总点差通常落在 1 bp 到 100 bp 之间,具体取决于资产波动率、风险容忍度和水平期。
跟 Glosten-Milgrom 和 Ho-Stoll 的关系
现代视角把做市拆成两个正交的问题:逆向选择(我的对手方是不是比我知道得多?)和库存管理(我的仓位风险怎么控?)。Glosten-Milgrom(第 4 篇)是前者的标准模型:dealer 报静态买卖价,点差纯粹补偿被知情者挑着打的损失,没有库存概念。Ho-Stoll (1981) 和 Avellaneda-Stoikov 是后者的模型:点差和报价倾斜管理库存风险,模型里没有知情者。
在 AS 里令 ,库存项全部消失,只剩 的基础点差——结构上呼应了 Glosten-Milgrom 的核心洞见”零库存也要有点差”,但经济学不同:GM 的点差是信息租,AS 的基础点差是流量弹性租。真实做市商两种租都要收:AS 给你库存那半的公式,逆向选择那半要靠 GM 的思路在模型外补。两个模型不是竞争关系,是同一张账单的两行。
再加上 Almgren-Chriss(第 9 篇)——最优执行之于单边大单,正如 Avellaneda-Stoikov 之于双边报价,连风险厌恶参数的角色都平行。这三个模型都吃透,现代微观结构的骨架就齐了。
从模型到实盘:缺的那几块
AS 的报价是起点,不是终点。真实高频做市商在它上面至少要补这些账。
排队位置。模型假设你挂了就能成交;现实是你排在队尾,好成交轮不到你,坏成交(价格要穿过你了)你跑不掉。Harris 第 13 章和第 1 篇讲过这个。报价被狙击。HFT 检测到你的陈旧报价后反向成交——他们不是基本面意义上的知情者,这是报价变动上的统计套利,但对你的账本来说效果跟逆向选择一模一样。延迟。模型是连续时间的;你有毫秒级延迟,撤单永远慢半拍。Tick 网格。模型价格连续;现实报价必须落在离散 tick 上(美股 1 美分,加密随交易所和交易对而异),取整本身就会改变你的排队命运。借券成本。空头库存要付借券费,负库存一侧的报价要把它算进去。费用与返佣。maker-taker 收费结构直接进出每笔成交的损益。
一个生产做市系统在 AS 骨架上叠几百条这类调整。核心公式给结构,剩下的是工程。
标定与实现
要把模型跑起来,三个参数要估。 用中间价的已实现波动率,1–5 分钟滚动窗口。 从报价距离与成交强度的关系里估(报价更新数据回归)。 没法从数据里估——它是你的风险偏好,由交易授权设定,模型单位下常见量程 1 到 ;设太小,报价紧到被人打穿,设太大,你宽到没有流量。波动率飙升的市况下要么让 的估计快速跟上、要么直接调高 ——总之别拿平静市况的参数硬扛崩盘,这个模型的所有输入都是市况的函数。
核心逻辑几行就写完了:
import numpy as np
def avellaneda_stoikov_quotes(mid, inventory, sigma, T_remaining,
gamma=1.0, kappa=1.0):
"""
按 Avellaneda-Stoikov 计算最优买卖报价。
mid: 当前中间价
inventory: 当前库存(正 = 多)
sigma: 中间价每期波动率
T_remaining: 剩余时间水平期(跟 sigma 同单位)
gamma: 风险厌恶
kappa: 到达速率弹性
"""
reservation = mid - inventory * gamma * sigma**2 * T_remaining
half_spread = (gamma * sigma**2 * T_remaining) / 2 + \
(1 / gamma) * np.log(1 + gamma / kappa)
return reservation - half_spread, reservation + half_spread
真实实现在这上面加 tick 取整、排队位置调整和库存硬限制——最后这条特别要强调:模型本身不约束库存,它只是温和地把你推回 ;真实 desk 的硬限制必须在模型外面加,别指望倾斜项替你挡住极端行情里的单边积累。
Arithmion 把这套流程打包了。arithmion.marketmaking.AvellanedaStoikov 提供带标定参数的实时报价计算、库存跟踪与倾斜、每笔成交的 P&L 归因、用真实 L2 数据的回测,以及多资产、跳跃扩散中间价、借券成本这些扩展;MarketMaker 模块负责自动标定——你给历史 L2 数据,它估 、,帮你选 。整条链接到 arithmion.execution 和 arithmion.tca 做完整绩效分析。
用它交易时真正要盯的东西
把模型当日常工具用的时候,几条经验值得写在屏幕边上。保留价是你的锚:库存一重,报价中心就该动,抗拒这个倾斜等于跟模型对赌方向。半点差是你的风险预算:紧一分,成交多一分,风险也多一分。如果你老老实实跟着模型走,库存会均值回复到零附近——反过来说,库存长期不回零,说明有什么东西(延迟、毒性流量、参数漂移)在模型外面漏水。最要紧的一条:AS 不检测逆向选择。就算点差挂对了,你还是会输给知情者;在多个水平期上监控你的已实现价差,如果它是负的,你有毒性问题,需要模型之外的一个独立信号(流量毒时干脆不报价)。
Harris 第 13 章有实战派的完整视角,Avellaneda-Stoikov 原文是正式参考,Cartea-Jaimungal-Penalva (2015) 把这个模型和它的各路扩展整理成了教科书。
参考文献
- Harris, L. Trading and Exchanges: Market Microstructure for Practitioners. Oxford University Press, 2003. 第 13 章(dealers 和做市商)。ISBN: 978-0-19-514470-3.
- Avellaneda, M., Stoikov, S. “High-Frequency Trading in a Limit Order Book.” Quantitative Finance, 2008.
- Glosten, L., Milgrom, P. “Bid, Ask and Transaction Prices in a Specialist Market with Heterogeneously Informed Traders.” Journal of Financial Economics, 1985.
- Ho, T., Stoll, H. “Optimal Dealer Pricing Under Transactions and Return Uncertainty.” Journal of Financial Economics, 1981.
- Cartea, A., Jaimungal, S., Penalva, J. Algorithmic and High-Frequency Trading. Cambridge University Press, 2015.