3、订单簿基础:订单簿结构与数据模型、买卖盘口深度分析、订单簿动态变化、Level 1/2/3数据详解

好,我们直接进入正题。订单簿这东西,说白了就是交易所的「实时记账本」。你下的每一笔限价单,都会在这里排队。我刚开始做量化那会儿,觉得订单簿不就是个价格列表嘛,有啥好研究的?后来被市场狠狠教育了几次,才明白——订单簿里藏着的,是市场参与者的真实意图。

3.1 订单簿结构与数据模型

先看结构。一个标准的限价订单簿(LOB),由两部分组成:买盘(Bid)卖盘(Ask)。买盘按价格从高到低排列,卖盘按价格从低到高排列。每个价格档位上,挂着对应的委托数量。

数据模型其实很简单。我习惯用这样的结构来表示:

// 伪代码,但很实用
struct OrderBookLevel {
    double price;      // 价格
    double volume;     // 总量
    int    orderCount; // 委托笔数
};

struct OrderBook {
    vector<OrderBookLevel> bids; // 买盘,按price降序
    vector<OrderBookLevel> asks; // 卖盘,按price升序
    int64_t timestamp;           // 快照时间戳
};

嗯,这里要注意:价格精度数量精度一定要跟交易所对齐。我在对接某家交易所时,就因为忽略了价格最小变动单位,导致订单簿数据对不上,排查了半天。

核心要点:订单簿的本质是「价格-数量」的二维映射。买盘是需求,卖盘是供给。两者在最优价位上相遇,就产生成交。

3.2 买卖盘口深度分析

盘口深度,就是看各个价位上的挂单量。光看最优买卖价(Top of Book)是不够的。你想想看,如果买一只有100手,但买二到买五加起来才50手,这深度就很虚。大单砸下来,价格瞬间就穿过去了。

我常用的几个深度指标:

  • 价差(Spread):卖一价 - 买一价。价差越小,流动性越好。
  • 加权深度:比如计算买一到买五的加权平均价格和总挂单量。
  • 深度斜率:价格每变动一个tick,挂单量的变化率。斜率陡峭,说明支撑/阻力强。

举个例子,假设当前盘口数据如下:

档位 买盘价格 买盘数量 卖盘价格 卖盘数量
1 100.00 500 100.10 300
2 99.90 200 100.20 400
3 99.80 100 100.30 100

从这张表能看出什么?买一有500手撑着,但卖一只有300手。如果这时候来一个买入市价单,300手成交后,价格会跳到100.20。买盘这边,100.00的500手被吃掉后,下一个支撑在99.90,只有200手。说白了,买盘深度看似厚实,但结构并不稳固

我的经验:做高频策略时,我很少只看单一档位。我会把前10档的挂单量画成「深度图」,观察形态。比如「尖峰状」的深度,往往意味着有大户在挂单护盘,一旦被突破,行情会加速。

3.3 订单簿动态变化

订单簿不是静止的。每一秒,都有新订单进来,也有订单被撤掉。我把它分为三类事件:

  1. 新增订单:新的限价单进入队列。买盘或卖盘某个价位上的数量增加。
  2. 撤销订单:已有订单被取消。数量减少,甚至整个价位消失。
  3. 成交订单:市价单与限价单撮合。对应价位的数量减少,直至消失。

动态变化的核心,是观察订单流。我曾经在分析某只股票时发现,它的买一价位经常出现「挂单-撤单-再挂单」的循环,频率极高。后来确认,这是做市商在试探市场深度。如果你只看快照,根本发现不了这个规律。

所以,我建议你记录订单簿的增量更新,而不是只存快照。增量更新的数据模型大概是这样:

struct OrderBookUpdate {
    enum Action { ADD, REMOVE, UPDATE };
    Action action;
    Side   side;    // BUY or SELL
    double price;
    double volume;
    int64_t orderId; // 订单唯一标识
};

有了增量数据,你就能重建出任意时刻的订单簿状态,还能分析订单的生存周期。嗯,这个对策略回测特别重要。

避坑指南:我曾经在对接某交易所的WebSocket时,发现它的增量更新偶尔会丢包。如果你只依赖增量,订单簿会越偏越远。一定要定期(比如每10秒)请求一次全量快照,做一次校准。不然,你的策略可能一直在错误的数据上跑。

3.4 Level 1/2/3 数据详解

这三个级别,是数据颗粒度的划分。很多新手搞不清楚,我直接说人话:

  • Level 1(L1):最优买卖价 + 最新成交价 + 成交量。说白了,就是「盘口最上面那一层」。适合看个大概,做趋势跟踪勉强够用。
  • Level 2(L2):多档买卖盘口。通常是前5档、前10档或前20档。能看到深度分布,适合做均值回归、订单簿不平衡策略。
  • Level 3(L3):全量订单簿。能看到每一笔挂单的详细信息,包括订单ID、挂单时间、委托数量等。这是最原始的数据,适合做微观结构研究。

我个人的建议是:做高频,至少用L2。L1的信息量太少,很容易被误导。L3数据量太大,处理起来成本高,除非你专门研究订单流特征,否则没必要。

来看一个L2数据的实际例子(某交易所的JSON格式):

{
  "bids": [
    [100.00, 500, 12],  // [价格, 数量, 委托笔数]
    [99.90,  200, 5],
    [99.80,  100, 3]
  ],
  "asks": [
    [100.10, 300, 8],
    [100.20, 400, 10],
    [100.30, 100, 2]
  ],
  "timestamp": 1695000000000
}

注意那个「委托笔数」字段。它很有用。如果某个价位上数量很大,但笔数很少,说明是机构大单。如果笔数很多,但每笔数量很小,说明是散户聚集。这个信息,L1数据里是看不到的。

总结一下:L1是「看热闹」,L2是「看门道」,L3是「看底牌」。你的策略需要什么级别的数据,取决于你的交易频率和策略逻辑。别盲目追求L3,数据量大、延迟高,处理不好反而拖累性能。

好了,订单簿的基础就讲到这里。下一章,我们会深入订单簿的微观特征,比如订单到达率、撤销率、以及如何用这些特征预测短期价格变动。这些东西,才是真正拉开差距的地方。