跳到正文

限价订单簿动态:价格优先与时间优先,以及你的排队位置

订单簿不是一张静态列表,是一条队列。撮合引擎怎么排序、你排在第几,决定了谁先成交、谁付点差、谁只能干瞪眼。

第 5 篇 · 共 12 篇 约 8 分钟

市面上大部分讲交易的文章会把订单簿描述成一张静态列表:买价在一边,卖价在另一边,点差夹在中间。给入门看看可以。但真正重要的东西全被漏掉了。

订单簿本质上是个队列。每一笔挂着的限价单都排在一个价格上,你的单子能不能成交,取决于三件事:你排在哪儿;你排队的时候别人在干什么;撮合引擎认不认为有人跟你交叉。这三件事贯穿全文——最后你会看到,它们合起来把”挂单还是吃单”变成一道可以算期望值的题,而且算出来的答案经常让人不舒服。

交易所运行的两条铁律

每家现代交易所(NYSE、Nasdaq、Cboe、CME、Binance、Coinbase、EBS,甚至那些号称”没有订单簿”的暗池)都跑在同一套规则下。价格优先:最优价格先成交,100.02 美元的买单排在所有 100.01 美元的买单前面。时间优先:同一个价格上,先到的单子先成交,先进先出。(NYSE 历史上有过例外,当时由场内经纪人酌情分配,但合并行情看起来还是 FIFO。)

Harris 把这两条叫做交易所的交易规则(Harris,《Trading and Exchanges》,第 4 章)。听起来像废话,其实不是——因为确实有交易所打破其中一条。按比例成交(pro-rata)市场(部分期货交易所,历史上 CME 的某些品种)在同一价格上按挂单量比例分配成交,而不是按时间:你挂 10 手、别人挂 30 手,每笔进来的市价单你都只吃到 25%。还有少见的数量优先(同价偏好大单)和混合制(盘口按比例、盘口下方 FIFO)。

如果你交易的是一个 pro-rata 产品,整个思维框架都得换:你不该追求排到队列最前面,而应该在 touch 上挂一个大单。本文后面不展开这条支线,因为主流的股票和加密交易所都是纯价格-时间制。但请记住,“订单簿到处都这样”是一句谎话。

一笔挂单的五要素

一笔挂着没动的限价单有五个属性决定它的命运:方向(买或卖)、价格(持有人能接受的最差价格)、数量、到达时间(进系统的时刻,也就是 FIFO 时间戳)、订单 ID(交易所分配的标识符,用来处理冲突和追踪单子的一生)。

当一笔可成交订单(marketable order)到达——买价 ≥ 最优卖价,或卖价 ≤ 最优买价——撮合引擎就从对面那侧的最优价格开始往外逐层吃单,每个价格层内部按时间顺序吃。一句话讲完撮合算法;Harris 整本第 4 章就是把这句话展开。

排队位置的数学

假设你在 100.00 美元挂了一笔买单,加入了一个队列。100.00 这条上排在你前面一共有 QQ 股,你自己的单量是 qq。对面吃单事件以每秒 λ\lambda 次的速率到达(每个事件是别人的市价卖单打到买价上,消掉队列里的一些量)。

你的期望成交时间是:

E[Tfill]=Q+qλ⋅pprice_still_at_100E[T_{\text{fill}}] = \frac{Q + q}{\lambda \cdot p_{\text{price\_still\_at\_100}}}

其中 pprice_still_at_100p_{\text{price\_still\_at\_100}} 是你等待期间 100.00 始终是最优买价的概率。这个概率是麻烦的部分。你干等的时候,价格可能跑掉:有人扫掉卖一,新的最优买价变成 100.01,这时候哪怕你到得早,也已经落在新价格层的后面了。

想给这个概率一个粗算,把中间价建模成波动率为 σ\sigma 的随机游走。在水平期 hh 内,中间价向任一方向移动超过半个点差的概率大致是:

pcancel≈2Φ ⁣(−δ/2σh)p_{\text{cancel}} \approx 2 \Phi\!\left(-\frac{\delta/2}{\sigma\sqrt{h}}\right)

其中 δ\delta 是以价格单位衡量的点差,Φ\Phi 是标准正态 CDF(系数 2 就是”两个方向都算”)。为什么两个方向都算坏事?往上走,你永远成交不了、眼看行情跑掉;往下走,你倒是成交了——在下跌途中接了货,这叫逆向选择,第 4 篇细讲。这个信封背面的估算告诉你:点差宽且波动低,你等到天荒地老;点差窄且波动高,你要么撤单要么被行情碾过去。

实操要点:行情快的时候,排队位置是一种会衰减的资产。每多等一秒,条件成交概率都在下降。

订单交叉时会发生什么

看个具体的。一笔买单以 100.02 美元到达。订单簿如下:

ASK  $100.02  | 500 shares
ASK  $100.03  | 800 shares
BID  $100.01  | 200 shares
BID  $100.00  | 1200 shares

你这笔 100.02 的买单是可成交的——它等于或高于最优卖价。撮合引擎立即把它和挂在 100.02 的 500 股撮合,你用 100.02 美元买到 500 股(如果你下的量超过 500,剩下的按 100.03 继续吃)。

挂在 100.01 的 200 股买单不参与成交。它们站错了边。撮合引擎不关心 100.01 < 100.02 这个逻辑关系;它只关心买是买、卖是卖,必须买价够到卖价才能撮。

但如果有人下了一笔可成交的限价卖单,价格 100.01 呢?这单会和 100.01 的买价交叉(100.01 ≤ 100.01),在 100.01 成交 200 股。剩余量呢?它的限价是 100.01,够不到下一层 100.00 的买价,于是剩余量以 100.01 挂回簿上的卖侧,成为新的最优卖价。这个行为叫扫单(sweeping):可成交订单逐价格层扫过去,扫到自己限价够不到的那层为止,未成交的残余以限价挂回簿上。一笔可成交的限价单,机制上就是”市价单 + 残余限价单”,这也是 fill-or-kill 这类指令必须在进入时就指明全成或全撤的原因。(Harris,第 4 章,关于订单的生命周期。)

防自成交的边界情况

现代交易所会跟踪你自家的挂单,拒绝自己跟自己撮合。如果你在簿上挂着一笔 100.00 美元的买单,然后又下了一笔 100.01 美元的买单,撮合引擎要么撤销你老的 100.00 单、把新的挂上去(替换行为),要么拒绝跟自己的单成交、把新单排在后面,要么直接把新单拒掉。各家交易所做法不一样。

这是执行算法里很多诡异行为的根源。如果你见过 TWAP 的某个子单莫名”跳过”,多半是因为算法在下可成交买单的时候,同一父单的一笔限价卖单还挂在簿上。

排队位置本身是种资产

这一点散户基本不会去想。你在队列里的位置是一种资产。 不上你的资产负债表,但它有经济价值:这个价值等于你能拿到的价格与排在更后面的人会拿到的价格之差。如果买价上你排第 10 名、点差 0.01 美元,那比起排第 1000 名的人,你大概相当于握着一跳的”插队补偿”——当最优买价被打掉、你的单子成为新的最优买价时,你就拿到了一格价格改善。

这就是 maker-taker 收费结构存在的原因。交易所给挂单方(簿上的限价单)返佣,向吃单方(拿走流动性的市价单)收费;maker 返佣是对排队风险的部分补偿。股票市场上 maker 返佣很小(每股不到一分钱),加密市场大得多——Binance 历史上给过 0.01%–0.02% 的 maker 返佣,对高频策略是真金白银。

你做做市策略的话,应该清楚自己在每一 tick 的期望排队位置和每秒期望成交率。这条线的数学在 Harris 第 13 章和学术文献里都有(参见 Parlour,“Price Dynamics in Limit Order Markets”,1998;Handa、Schwartz、Tiwari,2003)。

实操中如何估算成交概率

把前面两个量(队列消耗速度、价格漂移风险)拼在一起,就是一个还算合理的成交概率估算器:

import numpy as np
from scipy.stats import norm

def fill_probability(queue_ahead, my_size, events_per_sec, vol_per_sec,
                     spread, horizon_sec):
    """
    在点差收窄或价格反向之前,
    挂在 touch 的限价单成交的概率。
    """
    # 前方队列清空所需期望时间
    eta = (queue_ahead + my_size) / max(events_per_sec, 1e-9)

    # 中间价在 eta 秒内上移半 tick 的概率
    # (假设点差不变、touch 失效)
    drift_std = vol_per_sec * np.sqrt(eta)
    prob_uptick = norm.cdf(spread / 2 / max(drift_std, 1e-9))

    return float(np.clip(1.0 - prob_uptick, 0.0, 1.0))


# 玩具示例:前 500 股、自己挂 100、4 单/秒、
# vol = 0.005 $/sqrt(s)、点差 0.02、水平期 60 秒
print(fill_probability(500, 100, 4, 0.005, 0.02, 60))

跑一下你会看到,对典型的短水平期参数,成交概率大概落在 30–80% 之间。这不是研究级的模型——要做研究你得上 Hawkes 过程模拟事件到达、用跳跃扩散模拟中间价——但主要直觉它都覆盖了。

为什么排队位置决定策略选择

同一个量,在不同水平期上的重要性天差地别。你做长线投资,排队位置就是噪音:市价单成交、付几个基点的点差,你根本不在乎。你做高频做市,排队位置就是一切:共置、更快的撤改、抢占盘口,巨大的工程投入全是为了往队列前面挪,因为排队位置的每一微秒都是期望盈亏。

零售和机构的执行算法处在中间,必须做选择:被动挂单(吃限价、赚点差、承担不成交风险),还是主动吃单(市价单、付点差、保证成交)?答案取决于父单紧急程度、簿上深度、波动率、时间段。这就是执行算法存在的根本原因——后面讲 Almgren-Chriss、VWAP 和 implementation shortfall 的文章,全部可以读成这一句话的展开:每一笔执行决策,本质上都是排队位置决策。

撤单的隐形代价

你在成交之前撤销一笔限价单,没人收你费。但你付出了别的东西:信息。撤得很快,市场可能推断出你丢了优势(或者根本没等到成交)。高频做市商会把撤单率当作毒性(toxicity)信号盯着。Harris 第 13 章关于 dealer 行为那部分专门讨论这个——它也是纯粹”挂单祈祷”策略总被逆向选择的原因之一。

真账本里的真数字

来点真实量级的数字。你在买价上挂 200 股买单。买价 100.00,卖价 100.01。前方队列 800 股。接下来 60 秒里,你看到 12 笔市价卖单打在买价上(每笔消掉队列里一些量),另有 4 笔挂单撤掉。现实的队列消耗事件率 λ≈0.27\lambda \approx 0.27/秒。

不算价格漂移,期望等待时间:

E[Tfill]≈800+2000.27≈3700 秒E[T_{\text{fill}}] \approx \frac{800 + 200}{0.27} \approx 3700 \text{ 秒}

差不多一个小时。一小时里价格大概率不会老实待着。如果日波动 0.02 美元、交易日 6.5 小时,每秒波动率约 0.02/23400≈0.000130.02/\sqrt{23400} \approx 0.00013 美元;一小时的典型漂移是 0.00013×3600≈0.00780.00013 \times \sqrt{3600} \approx 0.0078 美元,而半点差只有 0.005 美元。中间价在一小时内向任一方向移动超过半点差的概率:

pagainst=2⋅Φ ⁣(−0.0050.0078)≈2⋅Φ(−0.64)≈0.52p_{\text{against}} = 2 \cdot \Phi\!\left(-\frac{0.005}{0.0078}\right) \approx 2 \cdot \Phi(-0.64) \approx 0.52

而两个方向都不是好事:往上你白等,往下你在接刀。你大约只有 48% 的机会在价格还没跑之前干净成交。抛硬币。0.0002 美元的 maker 返佣(股票的常见水平)或 0.002%(加密的常见水平),值不值这个赔率?单笔看几乎不值。挂单的每股期望收益:

E[payoff per share]=0.48⋅(midprice−your_price)+0.52⋅(midprice−your_price−adverse)E[\text{payoff per share}] = 0.48 \cdot (\text{midprice} - \text{your\_price}) + 0.52 \cdot (\text{midprice} - \text{your\_price} - \text{adverse})

其中 adverse 是价格跑掉时你多亏的半点差甚至更多。这个期望值经常落在零附近或略负——裸做市流血就是这么流的。怎么把它做成正的(用报价偏移管理库存和逆向选择),是 Avellaneda-Stoikov 那篇的主题。

Arithmion SDK 对簿干了什么

如果你用 Arithmion 跑执行算法回测,模拟器必须建模排队位置才能给出真实的成交。arithmion.microstructure 里的 OrderBookSimulator 为每笔挂单维护按订单 ID 的时间戳,在每个价格层内按 FIFO 撮合可成交订单,这是基线。想更真实,可以启用撤改竞速(进来的撤单可能”晚了”,因为同价的市价单已经开始撮合)、部分扫层后的优先权保留(市价单扫过一层时,剩余挂单保留原时间优先权)、以及逐单延迟(每笔订单带自己的时间戳,按到达顺序撮合)。

这就是学术回测和现实回测的差距。多数散户回测假设你想成交就能成交——看完这篇你知道,那是幻想:订单簿是队列,排队位置就是资产,而大多数回测把这份资产当成了免费的。

参考文献

  • Harris, L. Trading and Exchanges: Market Microstructure for Practitioners. Oxford University Press, 2003. 第 4 章(交易规则、订单类型与撮合),第 13 章(dealer 行为)。ISBN: 978-0-19-514470-3.
  • Parlour, C. “Price Dynamics in Limit Order Markets.” Journal of Financial Economics, 1998.
  • Handa, P., Schwartz, R., Tiwari, S. “Quote Setting and Price Formation in an Order Driven Market.” Journal of Financial Markets, 2003.