队列反应模型:限价簿排队动态的马尔可夫建模
限价簿的最优报价不是一个价格,是一条排队的队列:价格什么时候动,等价于哪边队列先被吃空。队列反应模型(Huang-Lehalle-Rosenbaum 2015)的核心洞见是三类事件强度都是队列长度的函数——小队列抢着补单、大队列吸引市价单、撤单随队列线性增长,生灭过程的平稳分布可以解析求出并被 12 万秒事件级模拟精确复现(众数 q=3,零智能常数强度模型给出错误的 q=1 单调衰减形态)。队列失衡→价格方向的 S 形概率曲线从首达时间竞赛自然涌现:I=+0.8 时上行概率 73.3%、I=−0.8 时 28.3%,无需任何外生 alpha 假设。全簿模拟 3600 秒 11890 个订单事件只产生 173 次价格变动——价格是队列动态的慢变量。做市、执行算法排队价值评估、短周期方向信号三个应用场景+A 股 Level-2 十档快照的工程适配(高阶)
一句话版本#
限价簿的最优报价不是一个价格,是一条排队的队列。价格什么时候动、往哪动,等价于问:买一和卖一两条队列,哪边先被吃空。队列反应模型把这个问题变成一个可解析、可模拟、可校准的马尔可夫生灭过程——它的全部力量来自一个观察:订单到达强度不是常数,而是队列长度的函数。
从「价格序列」退一步到「队列序列」#
大多数量化模型把价格当作原子对象:日线策略看收盘价序列,高频策略看中间价序列。但在 tick 尺度上,价格本身是个离散的慢变量——大部分时间它一动不动,动的那一瞬间发生了什么?
发生的是:某一侧最优报价的队列被清空了。买一价上挂的最后一手要么被市价单吃掉、要么自己撤了,买一价位消失,中间价下移。价格变动是队列耗尽事件的影子。
这个视角转换意味着:想建模高频价格动态,正确的状态变量不是价格,而是最优报价上的队列长度 。价格只在队列首达零点时更新。
最朴素的队列模型是「零智能」(zero-intelligence):限价单以常数强度 到达,市价单以常数强度 消耗,每张挂单以常数率 独立撤单。数学上干净,但它有一个致命的实证缺陷——真实市场的订单流强烈依赖队列状态。
队列反应:强度是队列长度的函数#
Huang、Lehalle 和 Rosenbaum 在 2015 年的论文(Simulating and analyzing order book data: The queue-reactive model)用巴黎泛欧交易所的逐笔数据校准出一个关键事实:三类订单事件的到达强度都随队列长度显著变化,而且方向各不相同:
- 限价单到达 :队列越短,新限价单来得越快。两个原因:价位快消失时做市商急于补充报价维持存在感;短队列意味着排队位置靠前,时间优先权值钱。
- 市价单消耗 :队列越长,市价单越多。长队列是流动性充足的信号,急于成交的对手方敢下市价单;队列很短时市价单会引发价格冲击,交易者转向更谨慎的下单方式。
- 撤单 :近似随队列长度线性增长——每张挂单都有独立的撤单倾向,队列越长总撤单流越大。

用 Python 把这三条曲线写下来只需几行:
import numpy as np
def lam_limit(q): # 限价单到达:小队列时高,指数衰减到基线
return 1.0 * np.exp(-q / 8.0) + 0.15
def lam_cancel(q): # 撤单:随队列线性增长
return 0.12 * q
def lam_market(q): # 市价单:大队列吸引成交后饱和
return 0.45 * (1 - np.exp(-q / 3.0)) + 0.10python队列长度 于是构成一个生灭过程(birth-death process):出生率 ,死亡率 。这是马尔可夫链最友好的形态之一——平稳分布有封闭解。
平稳分布:模型第一个可检验的预言#
生灭过程的平稳分布满足细致平衡:
递推即可求出全部 。我们同时跑一个 12 万秒的事件级模拟做交叉验证:
def stationary_dist(qmax=40):
pi = np.zeros(qmax + 1); pi[1] = 1.0
for q in range(1, qmax):
birth = lam_limit(q)
death = lam_cancel(q + 1) + lam_market(q + 1)
pi[q + 1] = pi[q] * birth / death
return pi / pi.sum()python
三条线的关系值得逐一读:
- 解析平稳分布与模拟经验分布几乎重合(众数都在 ,均值 3.64 vs 3.88)——数学没骗人,代码也没写错。
- 零智能对照组形态完全不同:常数到达强度下平稳分布是从 单调衰减的,众数被钉死在最小值上。而队列反应模型给出先升后降的单峰形态——这正是真实市场上观察到的队列长度分布形状(Huang 等人在 CAC40 成份股上的实证图几乎就是这条曲线)。
- 形态差异的机制很直白:小队列时限价单蜂拥而入( 高、 低),把队列从耗尽边缘推回来;大队列时市价单消耗与撤单联手压制。队列长度存在一个内生的均衡区间,零智能模型没有这个恢复力。
这是队列反应模型的第一重价值:不需要拟合价格,只用订单流强度函数,就能重现限价簿的静态统计形态。
队列失衡 → 价格方向:S 形曲线的涌现#
高频交易最常用的信号之一是队列失衡(queue imbalance):
买一队列比卖一厚,下一次价格变动更可能向上。这个信号为什么有效?大多数使用者只知道「实证上有效」。队列反应模型给出机制层面的答案:这是两条马尔可夫队列首达时间竞赛的直接推论——薄的一侧期望更早触零,触零即价格向该侧移动。
我们模拟九组失衡配置,每组跑 1500 次「哪边先耗尽」的竞赛:
def prob_up(qb, qa, n_sim=1500):
"""买一队列 qb、卖一队列 qa 独立演化,卖一先耗尽 = 价格上行"""
ups = 0
for _ in range(n_sim):
b, a = qb, qa
while b > 0 and a > 0:
rates = [lam_limit(b), lam_cancel(b) + lam_market(b),
lam_limit(a), lam_cancel(a) + lam_market(a)]
ev = rng.choice(4, p=np.array(rates) / sum(rates))
if ev == 0: b += 1
elif ev == 1: b -= 1
elif ev == 2: a += 1
else: a -= 1
ups += (a == 0)
return ups / n_simpython
实测结果:(买一 9 手、卖一 1 手)时上行概率 73.3%, 时 28.3%, 时 49.5%——干净地穿过一半。更重要的是曲线形状:中段平缓、两端陡峭的 S 形,而非线性。 从 0 到 +0.4 只把概率从 0.50 推到 0.54,从 +0.6 到 +0.8 却从 0.63 跳到 0.73。
机制解释:中等失衡下,薄侧队列的「小队列保护机制」( 飙升、 回落)在积极补血,抵消了大部分初始劣势;只有失衡极端到补单流也救不回来时,首达优势才充分兑现。这条 S 形曲线是模型涌现的,不是假设的——它同时告诉你为什么失衡信号在温和区间信噪比很低、为什么实盘上只有极端失衡才值得行动。
全簿模拟:价格是队列动态的慢变量#
把双侧队列拼起来,加一条再生规则(一侧耗尽 → 中间价移动半个 tick → 新最优价位队列再生,且价格移动方向的新暴露队列较薄),就得到一个完整的内生价格模拟器:

3600 秒模拟产生 11890 个订单事件,但只有 173 次价格变动——事件与价格变动之比约 69:1。这个数量级和真实流动性股票的逐笔数据高度一致:限价簿上绝大多数活动是挂单与撤单的拉锯,价格变动是稀有的边界事件。下半图能直观看到每次价格跳变前,总有一侧队列先被磨到零。
这个 69:1 也解释了为什么逐笔数据里 99% 的信息不在成交价里:只盯价格序列的模型,把决定价格何时动、往哪动的队列拉锯战全部扔掉了。
这个模型能用来做什么#
做市与排队价值评估。 你挂了一张限价单排在队列第 位,这张单值多少钱?取决于「队列在我前面被消耗到我 vs 价格先反向移动」的竞赛概率——这正是队列反应模型的首达时间计算。执行算法里「排队还是打过去(join or cross)」的决策可以直接查这张概率表。
短周期方向预测的基线。 S 形失衡曲线就是一个零参数的方向概率模型。任何声称有预测力的高频信号,都应该先和这条曲线比:你的模型比「按队列失衡查表」多赚了多少?很多论文里的「深度学习预测限价簿」模型,扣掉失衡曲线的贡献后所剩无几。
压力场景生成。 因为价格是内生的,可以做反事实实验:把 调高 50% 模拟卖压冲击,观察价格移动频率和失衡分布如何变化——这是用历史数据重放做不到的。
诚实的边界#
三个不该被忽略的简化:
- 独立性假设:模型里买卖两侧队列独立演化,真实市场的订单流有强烈的交叉激励(买一被扫后卖一常同步撤单)。Huang 等人的完整版本用「队列对」联合建模缓解这一点,代价是状态空间平方级膨胀。
- 无信息交易者:所有强度只依赖队列长度,不依赖价格历史。趋势行情中订单流的方向持续性(前一篇 Run Bars 讲的那种)在这个模型里不存在——它是平静市场的模型,新闻时段失效。
- 参数漂移:强度函数需要用近期数据滚动校准,开盘/收盘时段的强度曲线与午盘差异巨大,一套参数打全天是常见错误。
A 股注记#
A 股的适配条件其实相当好:Level-2 行情提供十档委托队列快照和逐笔委托/成交流,强度函数 可以直接从逐笔委托数据分队列长度分桶估计,不需要像美股那样从多交易所碎片化数据里拼簿。两个本土化要点:一是 A 股 tick size 相对价格偏大(低价股尤甚),最优报价队列极厚,队列耗尽事件更稀有,模型的「价格慢变量」特征更极端;二是 T+1 制度不影响这个模型的建模层(它建模的是簿内动态而非持仓策略),但用失衡信号做日内交易时,买入后当日不能卖出,信号周期与持仓约束的错配必须在策略层处理。
系列定位:本文从信息驱动采样系列(美元 Bar → 失衡 Bar → Run Bar)再往微观走一层——那些系列把订单流聚合成 bar,本文直接建模订单流本身的生成机制。下一层的自然延伸是把队列反应模型生成的模拟簿用作执行算法的训练环境。
参考文献:Huang, W., Lehalle, C-A., Rosenbaum, M. (2015). Simulating and analyzing order book data: The queue-reactive model. JASA 110(509); Cont, R., Stoikov, S., Talreja, R. (2010). A stochastic model for order book dynamics. Operations Research 58(3).