3. 市场微观结构:订单簿与盘口数据

做高频交易回测,有个东西绕不开——市场微观结构。

说白了,就是市场在极短时间内是怎么运作的。你想想看,我们平时看到的K线图,一分钟一根,里面其实藏了成千上万笔交易。这些交易的细节,才是高频交易真正要啃的骨头。

我个人习惯,把这块内容分成三个层次来讲:订单簿原理、盘口数据级别、以及Tick和快照的区别。咱们一个一个来。

3.1 订单簿(Order Book)原理

订单簿是什么?你可以把它想象成一个实时更新的“买卖挂单大列表”。

买方想低价买,挂个买单。卖方想高价卖,挂个卖单。这些单子按价格排队,就形成了订单簿。

我在项目中遇到过一个问题:刚开始做回测时,我只用了成交数据,忽略了订单簿。结果策略在模拟里赚得飞起,实盘一跑就亏。为什么?因为订单簿里的挂单深度,直接影响你的成交速度和滑点。

核心概念:
  • 买盘(Bid):最高买入价,价格从高到低排列
  • 卖盘(Ask):最低卖出价,价格从低到高排列
  • 价差(Spread):卖一价 - 买一价,流动性越好的品种价差越小
  • 深度(Depth):每个价位上的挂单数量

嗯,这里要注意:订单簿是动态的。每一秒都有新单进来,也有旧单撤掉。你的策略如果只看最后成交价,等于闭着眼睛开车。

下面这张图,是我自己画的一个简化版订单簿结构。你可以直观感受一下买卖双方是怎么“对峙”的。

订单簿(Order Book)结构示意图 卖盘(Ask Side) 卖五:100.50 数量 200 卖四:100.40 数量 150 卖三:100.30 数量 300 卖二:100.20 数量 250 卖一:100.10 数量 180 ← 最低卖价 价差(Spread)= 100.10 - 100.00 = 0.10 买盘(Bid Side) 买一:100.00 数量 350 ← 最高买价 买二:99.90 数量 220 买三:99.80 数量 180 买四:99.70 数量 400 买五:99.60 数量 100 关键说明 1. 买一价 < 卖一价,这是正常状态 2. 价差越小,流动性越好 3. 深度越厚,大单冲击成本越低 4. 买一和卖一就是 Level 1 数据 常见场景: • 市价买入:吃掉卖一到卖N • 限价买入:挂在买一或更低 • 撤单:订单从队列中移除 • 冰山单:只显示部分数量 注:实际订单簿可能有几十个价位

3.2 买卖盘口数据:Level 1 / 2 / 3

盘口数据分三个级别。很多新手搞不清,我简单说一下。

Level 1(最基础)

只包含最优买卖价和对应的数量。也就是买一和卖一。

大多数免费行情接口给的就是这个。做简单策略够用,但做高频?差得远。

我的经验: 如果你做的是日内低频策略,Level 1 数据勉强能用。但做高频回测,至少要用 Level 2。我曾经用 Level 1 数据回测一个做市策略,结果实盘时发现订单簿第二档的深度完全不一样,策略直接失效。

Level 2(常用)

包含多个价位的买卖挂单。一般是前5档或前10档。

比如上面那张图里,买一到买五、卖一到卖五,就是典型的 Level 2 数据。

有了这个,你才能判断市场的真实深度。举个例子:

// 一个简单的 Level 2 数据结构示例
struct Level2Data {
    double bid_prices[10];   // 买价,从高到低
    int    bid_sizes[10];    // 对应数量
    double ask_prices[10];   // 卖价,从低到高
    int    ask_sizes[10];    // 对应数量
    int64_t timestamp;       // 时间戳,纳秒级
};

Level 3(最详细)

这个级别能看到每个订单的详细信息。包括订单ID、下单时间、隐藏数量等。

说实话,Level 3 数据一般只有交易所内部或者做市商才能拿到。我做高频交易这么多年,真正用到 Level 3 的场景其实不多。除非你在做订单流分析或者抢单策略。

注意: Level 3 数据量极大。一个活跃品种一天可能产生几亿条订单事件。存储和处理都是大问题。我见过有人用 Level 3 数据做回测,结果光数据清洗就花了三天。

3.3 Tick级数据与快照数据

这块容易混淆。我分开讲。

Tick级数据

每一笔成交或每一次订单簿变化,都算一个Tick。

说白了,Tick数据就是“发生了什么就记录什么”。比如:

  • 有人以100.10买了100股 → 记录一条Tick
  • 有人撤单了 → 记录一条Tick
  • 有人挂了新单 → 记录一条Tick

我在项目中遇到过一个问题:用Tick数据做回测,数据量太大,回测跑不动。后来我改用快照数据,速度上去了,但精度下降了。这是个取舍问题。

快照数据

每隔固定时间(比如100毫秒)拍一张订单簿的照片。

快照里包含当前时刻的完整订单簿状态。它不记录中间发生了什么,只记录最终结果。

对比维度 Tick数据 快照数据
数据量 极大(每笔事件都记录) 较小(固定间隔采样)
精度 高(无信息丢失) 低(可能错过中间变化)
回测速度
适用场景 高频策略、订单流分析 中低频策略、趋势跟踪
存储成本
我的建议:

做高频回测,优先用Tick数据。但如果你只是验证策略逻辑,快照数据也够用。

我曾经犯过一个错:用1秒快照数据回测一个高频做市策略,结果回测曲线漂亮得不行。实盘一跑,直接亏了5%。为什么?因为快照错过了中间几百次订单簿变化,策略的成交逻辑完全不对。

3.4 实际应用中的注意事项

最后说几个实战中容易踩的坑。

  1. 时间同步问题:不同数据源的时间戳可能不一致。我建议统一用交易所的纳秒级时间戳。
  2. 数据清洗:原始数据里经常有错误。比如卖价低于买价,这种数据要过滤掉。
  3. 回放速度:Tick数据回放时,要控制速度。我一般用事件驱动的方式,而不是按时间轴硬跑。
  4. 内存管理:一天的Tick数据可能占几个G。用内存映射文件或者数据库来管理。
一个小技巧: 如果你刚开始做高频回测,可以先从快照数据入手。等策略逻辑稳定了,再换成Tick数据做精细回测。这样既保证了效率,又不失精度。

嗯,关于市场微观结构这块,今天就先聊这么多。记住一句话:你的回测精度,取决于你对订单簿的理解深度。别想着跳过基础直接上策略,那是在给自己挖坑。


公众号:蓝海资料掘金营,微信deep3321