4. 快照行情协议解析入门
快照行情是交易所对外发布市场状态最基础、最常用的数据形态。它不像逐笔行情那样记录每一笔成交与每一次委托变化,而是在固定或事件触发的时间点上,对当前市场买卖盘、最新成交、累计成交量等关键信息做一次“切片”。理解快照协议,是后续做行情接入、盘口重建、策略信号计算的前提。
本节围绕快照字段含义、买卖盘档位、最新价与成交量、时间戳格式,以及交易所快照样例结构拆解展开,帮助你建立从“看到字段”到“读懂市场状态”的完整认知。
一、核心原理:快照是市场状态的切片
快照行情的本质,是把订单簿在某一时刻的可见状态压缩成一条结构化消息。交易所通常按固定频率(如每500毫秒、1秒)或按行情变化阈值推送快照。每条快照至少回答四个问题:
- 谁:交易标的代码、交易所、市场类型。
- 什么时间:行情时间戳、发送时间戳。
- 买卖意愿:买一至买N、卖一至卖N的价格与数量。
- 成交结果:最新价、成交量、成交额、开高低收等统计值。
与逐笔行情相比,快照丢失了订单簿变化的中间过程,但胜在数据量小、解析简单、对网络抖动容忍度高。对于中低频策略、盘口监控和行情展示,快照往往是首选。
关键认知:快照不是“实时全量订单簿”,而是交易所愿意公开的那一层盘口。不同交易所的档位深度、是否含隐藏单、是否含总委托量,差异很大。
二、买卖盘档位:从买一到买N的排列逻辑
买卖盘档位是快照中最核心的部分。通常用 BidPrice[1..N] 与 BidVolume[1..N] 表示买盘,用 AskPrice[1..N] 与 AskVolume[1..N] 表示卖盘。买一价格最高,卖一价格最低,买一与卖一之间的差额就是盘口价差。
档位深度N因交易所而异:有的只提供买一卖一,有的提供五档、十档,甚至二十档。档位越多,对订单簿的还原越精细,但消息体也越大。解析时要注意:
- 档位价格是否已排序,通常买盘降序、卖盘升序。
- 数量单位是股、手还是张,不同市场不同。
- 空档位如何表示,常见为价格0、数量0或直接缺省。
- 是否包含“总买量/总卖量”等汇总字段。
下面是一个典型的五档快照字段清单:
| 字段名 | 含义 | 示例 | 注意事项 |
|---|---|---|---|
| Symbol | 合约代码 | IF2406 | 需与交易所定义一致 |
| BidPrice1 | 买一价 | 3560.2 | 价格精度按最小变动价位 |
| BidVolume1 | 买一量 | 12 | 单位可能是手 |
| AskPrice1 | 卖一价 | 3560.4 | 卖一应大于买一 |
| AskVolume1 | 卖一量 | 8 | 数量为0表示无挂单 |
| LastPrice | 最新价 | 3560.4 | 可能是成交价或结算价 |
| Volume | 累计成交量 | 152340 | 通常是当日累计 |
| Turnover | 累计成交额 | 5.42e9 | 注意单位与精度 |
| UpdateTime | 行情时间 | 20240607103000123 | 格式需按交易所解析 |
三、最新价、成交量与时间戳格式
最新价(LastPrice)是最近一笔成交的价格,但它不一定等于当前买一或卖一。若市场刚发生主动成交,最新价可能等于卖一或买一;若长时间无成交,最新价可能停留在历史位置。成交量(Volume)通常是当日累计值,解析时要区分“累计”与“增量”,避免重复累加。
时间戳格式是快照解析中最容易出错的环节。常见格式包括:
- YYYYMMDDHHMMSSsss:如
20240607103000123,表示2024年6月7日10点30分00秒123毫秒。 - Unix毫秒时间戳:如
1717727400123,需转换为本地时间。 - 交易所自定义整型:如
103000123,表示10:30:00.123。
解析时间戳时,务必确认时区、是否含毫秒、是否为交易日内的相对时间。建议统一转换为UTC毫秒后再做策略计算。
下面是一段Python伪代码,演示如何解析常见快照时间戳:
def parse_exchange_time(ts: str):
# 格式:YYYYMMDDHHMMSSsss
if len(ts) == 17:
dt = datetime.strptime(ts[:14], "%Y%m%d%H%M%S")
ms = int(ts[14:17])
return dt.replace(microsecond=ms * 1000)
# 格式:Unix毫秒
if len(ts) == 13:
return datetime.fromtimestamp(int(ts) / 1000)
raise ValueError("unknown time format")
四、交易所快照样例结构拆解
不同交易所的快照消息结构差异较大,但通常遵循“消息头 + 业务字段 + 校验”的分层模式。以某期货交易所的二进制快照为例,其结构可拆解为:
struct Snapshot {
uint32 msgType; // 消息类型,如1001表示快照
char symbol[16]; // 合约代码
double bidPrice[5]; // 买一至买五价
uint32 bidVolume[5]; // 买一至买五量
double askPrice[5]; // 卖一至卖五价
uint32 askVolume[5]; // 卖一至卖五量
double lastPrice; // 最新价
uint64 volume; // 累计成交量
double turnover; // 累计成交额
uint32 updateTime; // 时间,如103000123
uint32 checksum; // 校验和
};
解析这类结构时,要特别注意字节序(大端/小端)、字段对齐、浮点数精度和字符串截断。建议先用交易所提供的样例报文做单元测试,再接入实时流。
常见误区:直接把快照中的累计成交量当作增量使用,导致成交量重复计算;忽略时间戳时区,导致跨市场对齐错误;把空档位的价格0当作真实价格参与计算。
五、复盘:从一条快照到市场状态判断
假设你收到一条快照:买一3560.2/12手,卖一3560.4/8手,最新价3560.4,累计成交量152340手。你可以快速判断:
- 盘口价差为0.2,流动性尚可。
- 最新价等于卖一,说明最近一笔是主动买入。
- 买一量大于卖一量,短期买压略强。
- 累计成交量需与上一条快照对比,才能得到增量。
把多条快照按时间序列排列,就能还原出盘口变化、成交活跃度和价格趋势。这正是快照行情在实战中的核心价值:用有限的数据,稳定地刻画市场状态。