3、数据结构解析:Level 1、Level 2、Level 3数据深度,JSON与Protobuf格式

做量化交易的朋友,尤其是搞高频的,一定绕不开订单簿数据。说白了,订单簿就是交易所里所有挂单的实时快照。但不同场景下,我们需要的数据深度完全不一样。今天我就带大家把Level 1、Level 2、Level 3这三层数据扒个底朝天,顺便聊聊JSON和Protobuf这两种格式怎么选。

3.1 数据深度:从浅到深的三层结构

我个人习惯把订单簿数据分成三个等级,就像看地图一样——你可以只看城市轮廓,也可以看街道,甚至能看到每栋楼的门牌号。

Level 1:最浅的快照

Level 1数据只告诉你当前最优的买卖价格和数量。也就是我们常说的“买一价”、“卖一价”。

  • 买一价:最高买入价格
  • 卖一价:最低卖出价格
  • 最新成交价:最后一笔交易的价格
  • 成交量:累计成交数量

我在做简单的行情展示时,用Level 1就够了。但如果你要做策略回测,这数据太粗糙了——你根本不知道市场深度如何,一个大单砸下来会不会把价格打穿。

Level 2:市场深度快照

Level 2数据会展示买卖盘口的多档价格和数量。通常交易所会提供5档、10档甚至50档。

举个例子,一个典型的Level 2快照长这样:

{
  "bids": [
    [100.50, 1000],
    [100.40, 2000],
    [100.30, 1500]
  ],
  "asks": [
    [100.60, 800],
    [100.70, 1200],
    [100.80, 1800]
  ]
}

这里bids是买单,asks是卖单。每个数组里第一个数是价格,第二个数是数量。

嗯,这里要注意:不同交易所的Level 2数据格式可能不一样。有的按价格从高到低排列,有的反过来。我建议你拿到数据后先画个图看看,别直接写代码。

Level 3:逐笔委托数据

Level 3是最深的数据,它记录每一笔挂单、撤单、成交的完整信息。说白了,你能看到每个订单的ID、价格、数量、方向、时间戳。

我曾经在分析某次闪崩事件时,就是靠Level 3数据才还原了真相——原来是一个量化基金的程序出了bug,连续撤单再挂单,把市场搅得天翻地覆。

Level 3的数据量非常大,每秒可能产生几万条甚至几十万条消息。所以一般只有做市商和机构才会用。

3.2 JSON vs Protobuf:两种序列化格式

数据有了,怎么传输和存储呢?目前主流就两种:JSON和Protobuf。我分别说说它们的优缺点。

JSON:人类可读,但效率低

JSON的好处是直观,调试方便。你打开一个JSON文件,一眼就能看出数据结构。

{
  "symbol": "BTCUSDT",
  "bidPrice": "100.50",
  "bidQty": "1000",
  "askPrice": "100.60",
  "askQty": "800",
  "timestamp": 1623456789000
}

但JSON有个致命问题:冗余太多。每个字段名都要重复出现,比如"bidPrice"这个字符串,在100万条数据里就要出现100万次。我算过,同样的数据,JSON比Protobuf大3到5倍。

另外,JSON解析速度慢。在高频场景下,每毫秒都很宝贵。我曾经用JSON做实时行情推送,结果CPU占用率飙到80%,换成Protobuf后直接降到15%。

Protobuf:高效但需要定义Schema

Protobuf是Google开发的二进制序列化格式。它需要你先定义一个.proto文件,描述数据结构。

syntax = "proto3";

message OrderBookLevel2 {
  string symbol = 1;
  repeated double bid_prices = 2;
  repeated double bid_qties = 3;
  repeated double ask_prices = 4;
  repeated double ask_qties = 5;
  int64 timestamp = 6;
}

然后你用protoc编译器生成代码,在程序里直接操作这个结构体。序列化后的数据是二进制的,肉眼看不出来,但体积小、解析快。

我个人建议:

  • 开发调试阶段:用JSON,方便看数据
  • 生产环境:用Protobuf,追求性能
  • 数据存储:如果磁盘空间充足,JSON也行;否则用Protobuf

核心对比

特性 JSON Protobuf
可读性
数据体积
解析速度
Schema定义 不需要 需要
跨语言支持

3.3 实战中的选择策略

你想想看,如果你只是做个个人交易工具,每天处理几万条数据,JSON完全够用。但如果你要搭建一个高频交易系统,每秒处理几十万条订单簿更新,那必须上Protobuf。

我记得有一次帮一个团队优化数据管道,他们用JSON传输Level 3数据,结果网络带宽被打满了。换成Protobuf后,带宽占用直接降到原来的四分之一,延迟也降了30%。

我的建议:如果你的数据量不大(每天少于100万条),用JSON省心。如果数据量大或者对延迟敏感,果断上Protobuf。另外,很多交易所的WebSocket接口同时支持JSON和Protobuf,你可以根据场景灵活切换。

避坑指南:我曾经遇到过一个问题——用Protobuf时,字段顺序变了导致解析失败。后来发现是.proto文件里字段编号重复了。记住,Protobuf靠字段编号来识别,不是靠字段名。所以编号一定要唯一,而且不要轻易修改。

3.4 知识体系总览

下面这张图总结了本章的核心内容,方便你快速回顾:

订单簿数据结构解析 数据深度 Level 1 最优买卖价 最新成交价 成交量 适用:简单行情展示 Level 2 多档买卖盘口 价格+数量 市场深度快照 适用:策略回测 Level 3 逐笔委托数据 订单ID/价格/数量 撤单/成交记录 适用:做市商/机构 序列化格式 JSON 人类可读 体积大、解析慢 无需Schema 适用:开发调试 Protobuf 二进制格式 体积小、解析快 需要定义.proto 适用:生产环境

这张图把数据深度和序列化格式的关系理清楚了。从左到右,数据越来越细;从上到下,格式选择越来越明确。你可以在实际项目中对照这张图做决策。

专注资料整理