行情数据基础:Level-1/Level-2行情、Tick数据、Order Book数据结构
高频交易的核心是对市场微观结构的实时建模。理解不同级别的行情数据是构建收益模型的第一步。本章将系统梳理从公开行情到深度订单簿的数据层级、字段含义与Python中的典型数据结构。
一、行情数据层级总览
全球交易所通常提供两种级别的实时行情数据:Level-1(市场摘要)与Level-2(深度行情)。两者的核心差异在于数据粒度与信息含量。
| 对比维度 | Level-1(标准行情) | Level-2(深度行情) |
|---|---|---|
| 数据内容 | 最新成交价、涨跌幅、最高/最低价、成交量、最佳买一/卖一价与量 | 多档位买卖挂单(通常10~50档)、逐笔成交、逐笔委托 |
| 更新频率 | 秒级或事件驱动(成交触发) | 微秒级,每笔委托变动即推送 |
| 信息粒度 | 聚合快照 | 全量订单簿快照 + 增量更新 |
| 典型用途 | 趋势跟踪、技术指标计算 | 订单簿压力分析、流动性建模、微观结构策略 |
| 数据成本 | 较低(多数券商免费提供) | 较高(需单独订阅或购买) |
关键认知: Level-2 数据是高频策略的“原料”,它揭示了价格形成过程中的供需博弈细节,而不仅仅是价格结果。
二、Tick数据:最细粒度的市场记录
Tick数据是交易所对外发布的最小时间单位数据记录。每一笔成交或委托变动都会产生一个Tick。根据数据来源,Tick可分为两类:
- 成交Tick(Trade Tick):记录每一笔实际成交的价格、数量、时间戳、成交方向(买方主动/卖方主动)。
- 报价Tick(Quote Tick):记录订单簿中任意一档挂单价格或数量的变化。
一个典型的成交Tick数据字段如下:
{
"symbol": "600519.SH",
"timestamp": 1700000001234567, // 微秒级Unix时间戳
"price": 1680.50,
"volume": 200,
"turnover": 336100.0,
"trade_type": "B" // B=买方主动, S=卖方主动
}
实战注意: 国内A股市场Tick数据的时间戳精度通常为毫秒或微秒,但不同数据源可能存在时钟偏差。在回测中,建议对同一交易所的数据做时间戳对齐处理。
三、Order Book(订单簿)数据结构
订单簿是交易所撮合引擎维护的限价委托队列的实时快照。它按价格从高到低排列所有未成交的买单(Bid)和卖单(Ask)。
3.1 订单簿的层级结构
一个标准的多档订单簿包含以下核心元素:
- 价格档位(Price Level):每个价格点为一个档位。
- 委托量(Size):该价格档位上所有未成交委托的总手数。
- 委托笔数(Order Count):该价格档位上挂单的笔数(部分交易所提供)。
- 累计量(Cumulative Volume):从最优价到当前档位的累计委托总量。
以下是一个5档订单簿的示例数据:
{
"bids": [
[1680.00, 1500, 12], // [价格, 总量, 笔数]
[1679.80, 2300, 18],
[1679.60, 800, 5],
[1679.40, 3200, 25],
[1679.20, 1100, 9]
],
"asks": [
[1680.20, 1800, 14],
[1680.40, 2100, 16],
[1680.60, 900, 7],
[1680.80, 2800, 22],
[1681.00, 1300, 10]
],
"timestamp": 1700000001234567
}
3.2 订单簿的增量更新机制
高频场景下,交易所不会每次都推送全量订单簿,而是采用增量快照(Snapshot + Incremental Update)模式:
- 全量快照(Snapshot):每隔一定时间(如100ms)或连接建立时推送一次完整订单簿。
- 增量更新(Update):每次订单簿发生变动时,推送发生变化的档位信息(价格、数量变化、删除或新增)。
增量更新的典型消息格式:
{
"action": "update", // add / update / delete
"side": "bid",
"price": 1679.80,
"size": 2500, // 更新后的新数量
"order_count": 19
}
常见陷阱: 增量更新可能乱序到达,或出现重复/丢失。生产环境中必须维护一个本地订单簿副本,通过序列号(Sequence Number)校验增量消息的连续性,并在检测到断点后请求全量快照重建。
四、订单簿核心指标与SVG结构图
从订单簿数据中,我们可以计算一系列反映市场微观结构的指标:
- 买卖价差(Bid-Ask Spread):最优卖价 - 最优买价。
- 市场深度(Market Depth):各档位累计委托量,反映价格滑点风险。
- 订单簿斜率(Order Book Slope):价格-累计量曲线的斜率,衡量价格弹性。
- 订单簿不平衡(Order Book Imbalance):买方总深度 / 卖方总深度,预测短期价格方向。
下图展示了订单簿的完整数据结构与增量更新流程:
五、Python中的订单簿数据结构实现
在Python中,高频订单簿通常使用有序字典(OrderedDict)或红黑树(如bintrees库)来维护价格档位的快速插入、删除和查询。以下是一个轻量级订单簿类的核心实现:
from collections import OrderedDict
from typing import Dict, List, Tuple
class OrderBook:
def __init__(self):
self.bids: Dict[float, int] = OrderedDict() # 价格 → 总量
self.asks: Dict[float, int] = OrderedDict()
self.sequence: int = 0
def apply_snapshot(self, bids: List[Tuple], asks: List[Tuple], seq: int):
"""全量快照初始化"""
self.bids.clear()
self.asks.clear()
for price, size, _ in bids:
if size > 0:
self.bids[price] = size
for price, size, _ in asks:
if size > 0:
self.asks[price] = size
self.sequence = seq
def apply_update(self, side: str, price: float, size: int, seq: int):
"""增量更新"""
if seq <= self.sequence:
return # 丢弃过期消息
book = self.bids if side == 'bid' else self.asks
if size == 0:
book.pop(price, None) # 删除档位
else:
book[price] = size # 新增或更新
self.sequence = seq
def get_top_n(self, n: int = 5) -> Tuple[List, List]:
"""获取前N档买卖盘口"""
sorted_bids = sorted(self.bids.items(), reverse=True)[:n]
sorted_asks = sorted(self.asks.items())[:n]
return sorted_bids, sorted_asks
def spread(self) -> float:
"""当前买卖价差"""
if not self.bids or not self.asks:
return float('inf')
best_bid = max(self.bids.keys())
best_ask = min(self.asks.keys())
return best_ask - best_bid
性能提示: 在实盘高频场景中,建议使用
sortedcontainers 库的 SortedDict 或 C 扩展实现的红黑树,以应对每秒数万次的订单簿更新。纯 Python 的 OrderedDict 在档位数超过 50 档时可能成为瓶颈。
六、Level-2行情与Tick数据的关联
理解两者关系对构建特征工程至关重要:
- 成交Tick 是订单簿中吃单(Market Order)的结果,它会消耗订单簿中对应档位的委托量。
- 报价Tick 是订单簿中挂单(Limit Order)的变动,包括新增、撤销和部分成交后的数量修改。
- 通过对比成交Tick的方向与订单簿变化,可以识别主动买卖压力,这是高频收益模型的核心输入之一。
下图展示了成交Tick与订单簿之间的联动关系:
七、数据质量与实战避坑
高频数据常见问题:
- 时间戳抖动:同一毫秒内多条消息的时间戳可能相同,需使用序列号排序。
- 数据缺失:网络抖动可能导致部分增量更新丢失,必须实现断点重连与快照重建逻辑。
- 交易所规则差异:不同交易所对Level-2数据的档位数量、更新频率、字段定义存在差异,需仔细阅读API文档。
- 回测中的未来信息:使用Tick数据回测时,务必确保每个Bar的OHLC计算只使用该Bar结束前已产生的Tick,避免引入未来数据。
八、小结
本章建立了高频行情数据的基础认知框架:
- Level-1 提供聚合快照,适合低频策略;Level-2 提供深度订单簿,是高频建模的基石。
- Tick数据 是市场最细粒度的记录,分为成交Tick和报价Tick。
- 订单簿 通过全量快照+增量更新的方式维护,本地引擎需处理乱序和断点问题。
- Python中可使用
OrderedDict或SortedDict实现轻量级订单簿,生产环境需关注性能。