Level 1 vs Level 2 vs Level 3 数据:三种数据深度的区别
做高频交易,第一关就是搞懂数据。我见过不少新手,一上来就盯着 Level 2 数据看,结果被海量信息淹没了。其实,三种数据各有各的用处,选对了才能事半功倍。
先说说 Level 1 数据
Level 1 数据,说白了就是「最优报价」。它只告诉你当前市场上最好的买价和卖价,以及对应的成交量。比如你看到「买一 10.00 元,1000 股;卖一 10.01 元,500 股」,这就是 Level 1 的全部内容。
我个人习惯把 Level 1 叫做「快照数据」。它就像你站在交易所门口,瞥了一眼大屏幕上的最新价格。信息量少,但更新快,适合做简单的趋势判断。
- 最新成交价(Last Price)
- 买一价与买一量(Bid Price & Size)
- 卖一价与卖一量(Ask Price & Size)
- 当日最高价、最低价
- 累计成交量
我在项目中遇到过一个问题:用 Level 1 数据做高频策略,结果频繁被「假突破」骗进去。为什么?因为你看不到更深层的挂单,不知道那个大单是真是假。
Level 2 数据:看到更多层
Level 2 数据就丰富多了。它展示的是「市场深度」,也就是多个价位的挂单情况。通常能看到 5 档、10 档甚至 50 档的买卖盘口。
举个例子,Level 1 只告诉你买一在 10.00 元,但 Level 2 会告诉你:
卖五 10.05 2000
卖四 10.04 1500
卖三 10.03 1000
卖二 10.02 800
卖一 10.01 500
---
买一 10.00 1000
买二 9.99 1200
买三 9.98 800
买四 9.97 600
买五 9.96 400
看到区别了吗?Level 2 让你看到了「冰山的一角」。你可以判断支撑位和压力位在哪里,大资金在哪个价位埋伏。
Level 3 数据:全量数据
Level 3 数据,也叫「全量深度数据」。它不只是展示多个价位,而是展示每个价位上的所有订单。包括每个订单的 ID、时间戳、挂单量、是买单还是卖单。
说白了,Level 3 让你看到「谁在挂单,挂了多久,什么时候撤单」。这是做市商和机构玩家才有的数据,普通散户基本接触不到。
| 数据层级 | 可见信息 | 典型用途 | 数据量 |
|---|---|---|---|
| Level 1 | 最优买卖价 | 简单趋势跟踪 | 极小 |
| Level 2 | 多档挂单 | 订单簿分析 | 中等 |
| Level 3 | 全量订单 | 做市、套利 | 极大 |
Tick 级数据的价值
Tick 级数据,就是每笔成交的原始记录。它包含:成交时间、成交价格、成交量、成交方向(买方主动还是卖方主动)。
你想想看,普通 K 线数据把 1 分钟内的所有成交压缩成了 4 个数字(开、高、低、收)。但 Tick 数据保留了每一笔的细节。这就像看电影,K 线是 1 秒 1 帧的幻灯片,Tick 数据是 60 帧的流畅视频。
我个人习惯用 Tick 数据做两件事:
- 计算真实成交量——K 线里的成交量是累计的,但 Tick 数据能告诉你大单是在哪个价位成交的
- 识别主力意图——连续的小单买入 + 一个大单卖出,可能是主力在出货
# 一个简单的 Tick 数据解析示例
tick_data = {
'timestamp': '2024-01-15 09:30:01.123',
'price': 10.05,
'volume': 500,
'side': 'buy', # 主动买入
'trade_id': '123456789'
}
# 计算累计成交量
if tick_data['side'] == 'buy':
buy_volume += tick_data['volume']
else:
sell_volume += tick_data['volume']
数据订阅与解析
搞定了数据层级,接下来就是怎么拿到这些数据。嗯,这里坑很多,我一个个说。
订阅方式
主流交易所通常提供两种订阅方式:
- WebSocket——实时推送,适合高频交易。连接建立后,数据会主动推送到你这边
- REST API——轮询获取,适合低频策略。每次请求获取当前快照
我建议做高频交易一定要用 WebSocket。REST API 的延迟太高,而且频繁请求容易被封 IP。
解析要点
数据到了之后,解析是个技术活。不同的交易所格式不同,有的是 JSON,有的是二进制,有的是自定义协议。
# 一个典型的 WebSocket 订阅代码
import websocket
import json
def on_message(ws, message):
data = json.loads(message)
# 解析 Level 2 数据
if data['type'] == 'depth':
bids = data['bids'] # 买单列表
asks = data['asks'] # 卖单列表
# 更新本地订单簿
update_orderbook(bids, asks)
def on_error(ws, error):
print(f"连接出错: {error}")
def on_close(ws, close_status_code, close_msg):
print("连接关闭,准备重连...")
def on_open(ws):
# 订阅 BTC/USDT 的 Level 2 数据
subscribe_msg = {
"op": "subscribe",
"args": ["depth.BTC-USDT"]
}
ws.send(json.dumps(subscribe_msg))
ws = websocket.WebSocketApp(
"wss://example.com/ws",
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
ws.run_forever()
数据存储
Tick 级数据量巨大,存储是个问题。我一般用两种方式:
- 内存数据库(如 Redis)——存最近几天的数据,用于实时策略
- 时序数据库(如 InfluxDB)——存历史数据,用于回测和分析
千万别把 Tick 数据存到关系型数据库里。我试过,一张表几亿条记录,查询一次要等几分钟,根本没法用。
最后说一句,数据订阅和解析看起来简单,但实际做起来细节很多。比如时间戳的处理——交易所给的是 UTC 时间还是本地时间?毫秒还是微秒精度?这些不搞清楚,回测和实盘对不上,策略就废了。