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 知识体系总览
下面这张图总结了本章的核心内容,方便你快速回顾:
这张图把数据深度和序列化格式的关系理清楚了。从左到右,数据越来越细;从上到下,格式选择越来越明确。你可以在实际项目中对照这张图做决策。