Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

MBO 与 MBP 订单簿数据区别详解

深入解析 MBO 逐笔订单与 MBP 逐价订单数据格式的差异。本文对比了两种数据流的底层逻辑、应用场景以及运行成本,帮助您理解如何根据业务需求选择合适的市场数据架构。

MBO(逐笔订单)与 MBP(逐价订单)订单簿数据是隐藏在同一个标签下的重大区别。两家供应商都可以向您出售所谓的“Level 2”数据:MBP(按价格显示市场)发送每个价格水平上的总挂单量,而 MBO(按订单显示市场)则将每笔订单作为带有唯一 ID 的独立事件发送。前者是订单簿的汇总,后者则是构建订单簿的底层账本,其传输所需的数据流量高出几个数量级。

MBP 和 MBO 订单簿数据的实际内容

MBP(按价格显示市场)是聚合后的深度数据。每次更新都会标明方向、价格水平、该价位上的总显示挂单量,有时还会包含该价位背后的订单数量。作为 MBP-10 产品销售的数据会为您提供买卖双方各十个最优价格水平,即交易平台上的价格阶梯和深度图中的阶梯状显示。

MBO(按订单显示市场)是一个事件流。每条消息对应一笔订单:其 ID、方向、价格、显示数量以及刚刚发生的变动。没有任何预聚合处理。如果同一价格上有四十笔订单,则会有四十条独立消息将其加入,您必须在内存中保留这四十笔订单,才能计算出该价位的总额。

我们的 Level 1 与 Level 2 市场数据指南 涵盖了零售经纪商层级标签的含义。当供应商提到“Level 2”时,MBO 和 MBP 是其内部数据的精确名称,询问架构名称才是有意义的。

MBO 数据源包含的消息动作

MBO 数据源是一套应用于订单 ID 的动作分类。其中四种动作占据了大部分流量:

  • 添加(Add):一笔新订单以新的 ID 加入订单簿的某个价格水平。
  • 修改(Modify):现有 ID 的价格或数量发生变动。增加数量或变动价格会将订单排到该新价位的队列末尾;减少数量通常保持其原有排队位置。
  • 取消(Cancel):一个 ID 全部或部分离开订单簿。
  • 成交或填充(Trade or fill):一笔主动订单与一个或多个被动挂单成交,导致挂单数量减少或被移除。

MBP 不包含这些词汇。MBP 更新是对价格水平的陈述:该价格现在有多少挂单量。无论挂单量是因为取消还是成交而减少,更新内容看起来都一样。下方的面板展示了最精简订单簿(即合并后的最优买卖价)上的限制,即每侧一个价格水平,按此命名为 MBP-1。

查询最优报价变动 (AAPL, 6月16日 10:00-10:30 ET)
每个数字背后的完整 SQL
WITH
    ordered AS
    (
        SELECT
            row_number() OVER (ORDER BY sip_timestamp, sequence_number) AS msg_index,
            bid_price,
            bid_size,
            lagInFrame(bid_price) OVER (ORDER BY sip_timestamp, sequence_number) AS prev_bid_price,
            lagInFrame(bid_size)  OVER (ORDER BY sip_timestamp, sequence_number) AS prev_bid_size
        FROM global_markets.cache_stocks_quotes
        WHERE ticker = 'AAPL'
          AND sip_timestamp >= '2026-06-16 14:00:00'
          AND sip_timestamp <  '2026-06-16 14:30:00'
          AND bid_price > 0
    ),
    classified AS
    (
        SELECT multiIf(
            bid_price != prev_bid_price, 'best bid price changed',
            bid_size  >  prev_bid_size,  'size joined at the best bid',
            bid_size  <  prev_bid_size,  'size left the best bid',
            'bid untouched, ask side updated') AS message_type
        FROM ordered
        WHERE msg_index > 1
    )
SELECT
    message_type,
    count()                                        AS message_count,
    round(100 * count() / sum(count()) OVER (), 1) AS share_pct
FROM classified
GROUP BY message_type
ORDER BY indexOf(['best bid price changed', 'size joined at the best bid', 'size left the best bid', 'bid untouched, ask side updated'], message_type)
Run this yourself

在那半小时内,17.6% 的消息将最优买入价移动到了不同价格,17.4% 在买入价不变的情况下增加了挂单量,12% 在买入价不变的情况下减少了挂单量,53% 在另一侧变动时保持买入价不变。每一组数据都是关于价格水平的净值陈述。没有任何消息提及订单 ID,也无法通过算术还原缺失的 ID。

各架构能回答与不能回答的问题

MBP-10 可以回答“该价位有多少挂单量”这类问题:价格阶梯的形状、订单簿失衡、中间价附近的流动性以及深度图本身。聚合后的价格水平足以满足上述所有需求。

MBO 可以回答“这笔订单发生了什么”这类问题:当您加入时,您前面有多少挂单量;订单在取消前存活了多久;以及在最优价位上的被动订单在价格变动前成交的概率。这些数量在聚合形式下是不存在的,将订单汇总为价位总额会破坏定义它们的序列。

队列位置是最典型的例子,它仅在 价格-时间优先与比例分配匹配 机制下具有意义,即到达顺序决定了谁先成交。使其变得重要因素的是成交规模:一个价位是由许多小额成交而非一笔大额成交填满的。

查询成交规模分布 (AAPL, 6月16日 10:00-10:30 ET)
每个数字背后的完整 SQL
SELECT
    multiIf(size < 100,  '1 to 99 shares',
            size < 200,  '100 to 199 shares',
            size < 500,  '200 to 499 shares',
            size < 1000, '500 to 999 shares',
            '1000 or more shares')                 AS trade_size_bucket,
    count()                                        AS trade_count,
    round(100 * count() / sum(count()) OVER (), 1) AS share_pct,
    round(avg(size))                               AS avg_shares
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
  AND sip_timestamp >= '2026-06-16 14:00:00'
  AND sip_timestamp <  '2026-06-16 14:30:00'
  AND size > 0
GROUP BY trade_size_bucket
ORDER BY min(size)
Run this yourself

小于 100 股的零股成交占了该窗口期内 92.3% 的交易,而最大的成交区间 1000 or more shares 仅占 0.1%。如果将这些成交规模发送给一个显示 4,000 股挂单的价位,最后加入队列的订单可能会在经历数十次成交后仍未成交。MBP 向您展示的是 4,000 股,而 MBO 向您展示的是排队序列。

两种架构都无法显示隐藏挂单。冰山订单 只显示一小部分,且每次填充后都会以新 ID 刷新,因此储备量永远不会出现在任何消息中。

从 MBO 重建订单簿是一个状态机过程

MBP 数据源直接给您答案。MBO 数据源给您输入,并要求您必须完全准确:

  1. 从快照开始,或从空订单簿加上交易所的清空消息开始。
  2. 以订单 ID 为键,严格按顺序应用每一条添加、修改、取消和成交消息。
  3. 维护第二个按价格水平索引的列表,因为这是您的策略所读取的内容。
  4. 监控序列号,一旦缺失,立即从最新的快照重新同步。

故障模式是静默的。漏掉一条取消消息,一笔虚假订单就会在剩余时段内一直留在您的订单簿中,虚增该价位的挂单量,且不会触发任何异常。MBP 的降级则温和得多:每次更新都会重述价位总额,因此损坏的值会在几条消息内被覆盖。

MBO 也仅存在于直接交易所数据源中,每个交易所一个订单簿,这意味着需要运行并合并多个数据源。综合行情(Consolidated Tape)本质上是汇总数据,关于其拆分情况请参阅 SIP 与直接交易所数据源

额外细节带来的带宽成本

消息数量是衡量差异最诚实的方式。下方的面板对比了在同一固定的半小时内,五家知名公司的综合最优买卖价消息与实际成交记录。

查询报价与成交比率 (6月16日 10:00-10:30 ET)
每个数字背后的完整 SQL
WITH
    quote_load AS
    (
        SELECT ticker, count() AS quote_messages
        FROM global_markets.cache_stocks_quotes
        WHERE ticker IN ('SPY', 'AAPL', 'NVDA', 'MSFT', 'KO')
          AND sip_timestamp >= '2026-06-16 14:00:00'
          AND sip_timestamp <  '2026-06-16 14:30:00'
        GROUP BY ticker
    ),
    trade_load AS
    (
        SELECT ticker, count() AS trades
        FROM global_markets.stocks_trades
        WHERE ticker IN ('SPY', 'AAPL', 'NVDA', 'MSFT', 'KO')
          AND sip_timestamp >= '2026-06-16 14:00:00'
          AND sip_timestamp <  '2026-06-16 14:30:00'
        GROUP BY ticker
    )
SELECT
    q.ticker                              AS ticker,
    round(q.quote_messages / 1000, 1)     AS quote_messages_thousands,
    round(t.trades / 1000, 2)             AS trades_thousands,
    round(q.quote_messages / t.trades, 1) AS quotes_per_trade_ratio
FROM quote_load AS q
INNER JOIN trade_load AS t ON t.ticker = q.ticker
ORDER BY quotes_per_trade_ratio DESC
Run this yourself

SPY 的每笔成交对应的报价流量最重,每笔交易对应 9.6 条消息,三十分钟内共 510 千条消息。这五家公司之间的差异很大:在面板底部,MSFT 每笔成交仅对应 0.7 条报价消息,即每笔交易不到一条消息。请记住该列统计的内容:每侧一个价格水平,且该数据源已将所有交易所合并为单一的最优买卖价。十级深度产品会成倍增加该数量,而逐笔订单数据源则会再次成倍增加,因为每个交易所每个价位背后的每笔订单,无论是否成交,都会产生自己的添加、修改和取消消息。同样的算术逻辑在 期权报价数据源规模 中以更大规模呈现。

策略需要哪种订单簿数据源?

大多数工作运行在 MBP-10 上。深度图、失衡特征、价格流动性测量、执行成本模型,以及几乎所有关于“某价位挂单量”的研究问题,都可以从聚合后的价格水平中得到答案,且消息量仅为一小部分。

当答案取决于特定订单时,才需要 MBO:队列位置、订单存续时间、取消行为、最优价位上的被动成交概率。如果一个策略的成败取决于其在队列中是处于 200 股还是 20,000 股的位置,那么聚合数据无法提供支持,且必须为此支付许可费、带宽、存储空间以及保持重建订单簿全天准确的工程成本。

这些面板是如何构建的
  • 每个面板背后的数据源均为综合最优买卖价(每侧一个价格水平)加上成交记录。它不是深度数据源,也不是逐笔订单数据源,因此这些面板旨在说明消息量问题,而非直接采样 MBO。
  • 时间窗口固定在过去的特定日期,即 2026 年 6 月 16 日美国东部时间上午 10:00 至 10:30,存储为协调世界时 14:00 至 14:30。固定窗口可确保数据在重新生成时保持稳定。
  • 分类面板根据序列中的前一条消息对每条消息进行标记。它无法区分取消和成交,这正是本文所描述的局限性。

常见问题解答

MBO 和 MBP 市场数据有什么区别?

MBP(按价格显示市场)聚合了每个价格水平上的显示挂单量,并为每个价位发送一次更新。MBO(按订单显示市场)发送每一笔独立订单及其唯一 ID,以及针对该订单发生的添加、修改、取消和成交事件。

Level 2 数据等同于 MBO 数据吗?

通常不等同。零售经纪商处的“Level 2”几乎总是指聚合后的深度数据,即包含 5 到 20 个价格水平的 MBP。少数供应商以相同的层级名称销售逐笔订单数据源,因此架构名称而非层级名称决定了您实际接收到的内容。

MBO 数据源比 MBP 数据源大多少?

大几个数量级,具体取决于交易所和标的。仅综合最优买卖价一项,上述面板中最繁忙的标的每笔成交就对应 9.6 条消息。逐笔订单数据源会增加每个交易所每个价位背后的所有添加、修改和取消消息,包括绝大多数从未成交的订单。

可以从 MBO 数据中重建 MBP 订单簿吗?

可以,这是常规的处理流程:将每个订单事件应用到以订单 ID 为键的订单簿中,然后发布价位总额。反之则不可能:一旦订单被汇总为价位总额,原始的订单 ID 及其到达顺序就丢失了。


此处每个面板均附带其底层的 SQL 代码。若要统计不同标的或时段的相同消息,请在 Strasmore 终端用简单的英语提问。