4、快照数据解析(上):十档行情数据结构、买卖盘口数据(Bid/Ask Price & Volume)、加权平均委买委卖价格计算
各位同学,今天我们来啃一块硬骨头——Level2快照数据。说实话,我当年刚接触行情系统时,看到那密密麻麻的十档数据,第一反应是「这玩意儿怎么存得下?」后来踩了不少坑,才慢慢摸清门道。
快照数据,说白了就是交易所每隔几秒给你拍一张「市场快照」。它不像逐笔成交那样细碎,而是把当前时刻的盘口状态完整地告诉你。嗯,这里要注意:快照不是实时流,它是「切片」。
4.1 十档行情数据结构
先看数据结构。我习惯用C语言的结构体来理解,因为交易所底层就是这么定义的。你想想看,一个快照包,里面装着什么?
// 十档行情快照结构(简化版)
struct SnapshotData {
char security_id[8]; // 证券代码
int64_t timestamp; // 时间戳(精确到微秒)
double pre_close; // 昨收价
double open_price; // 今开盘
double high_price; // 最高价
double low_price; // 最低价
double last_price; // 最新价
int64_t total_volume; // 成交总量
double total_amount; // 成交总金额
// 十档买卖盘口
double bid_price[10]; // 买一到买十价格
int64_t bid_volume[10]; // 买一到买十数量
double ask_price[10]; // 卖一到卖十价格
int64_t ask_volume[10]; // 卖一到卖十数量
};
这里有个细节:价格用double,数量用int64_t。为什么?因为价格有小数点,而手数一定是整数。我在项目中遇到过有人用float存价格,结果精度丢失,回测时差了几个tick——那叫一个惨。
核心要点:十档行情中,bid_price[0]是买一价,ask_price[0]是卖一价。买一价永远小于卖一价,否则就是数据异常。
4.2 买卖盘口数据(Bid/Ask Price & Volume)
盘口数据,就是挂在交易所订单簿上的「未成交订单」。买盘是大家想买但还没买到的单子,卖盘是大家想卖但还没卖掉的单子。
我举个例子:
| 档位 | 买价(Bid) | 买量(Volume) | 卖价(Ask) | 卖量(Volume) |
|---|---|---|---|---|
| 1 | 10.00 | 1000 | 10.01 | 800 |
| 2 | 9.99 | 1500 | 10.02 | 1200 |
| 3 | 9.98 | 2000 | 10.03 | 900 |
| ... | ... | ... | ... | ... |
看到没?买一10.00有1000手,卖一10.01有800手。这意味着当前想以10.00买入的人有1000手,想以10.01卖出的人有800手。如果买方愿意加一分钱,就能吃掉卖一的800手——这就是价格跳动的动力来源。
实战技巧:我个人习惯把买一量和卖一量的比值叫做「盘口力度比」。比值大于1.5时,说明买方意愿强;小于0.6时,卖方占优。但这只是参考,不能单独用。
4.3 加权平均委买委卖价格计算
好了,重点来了。十档数据怎么用?一个很常见的指标就是「加权平均委买委卖价格」。说白了,就是把所有档位的价格按数量加权平均,看看市场整体的「心理价位」在哪里。
计算公式很简单:
// 加权平均委买价格
weighted_bid_price = Σ(bid_price[i] * bid_volume[i]) / Σ(bid_volume[i])
// 加权平均委卖价格
weighted_ask_price = Σ(ask_price[i] * ask_volume[i]) / Σ(ask_volume[i])
举个例子,用上面的数据:
买盘加权价 = (10.00*1000 + 9.99*1500 + 9.98*2000) / (1000+1500+2000)
= (10000 + 14985 + 19960) / 4500
= 44945 / 4500
≈ 9.9878
卖盘加权价 = (10.01*800 + 10.02*1200 + 10.03*900) / (800+1200+900)
= (8008 + 12024 + 9027) / 2900
= 29059 / 2900
≈ 10.0203
嗯,算出来买盘加权价9.9878,卖盘加权价10.0203。中间差了约3分钱。这个差值,我管它叫「盘口价差加权值」。差值越小,说明买卖双方越接近,可能很快要成交了。
我曾经踩过的坑:直接用十档数据算加权价时,一定要过滤掉价格为0或数量为0的档位。有些交易所的十档数据不是全满的,比如只有5档有单子,后面5档全是0。如果不做过滤,加权价会被严重拉偏。
4.4 知识体系结构图
下面这张图,是我自己梳理的快照数据解析流程。你看一遍,基本就明白整个脉络了。
4.5 工程化处理要点
最后,聊几个工程上的坑。我当年做实时行情系统时,总结了几条铁律:
- 数据校验不能省:每次收到快照,先检查买一价是否小于卖一价。如果违反,直接丢弃。别问我为什么——网络抖动时,什么妖魔鬼怪数据都有。
- 缓存设计要合理:快照数据一般3秒推送一次。我建议用环形缓冲区存最近10个快照,方便做趋势对比。
- 计算加权价时注意性能:如果你要实时计算所有股票的加权价,别用double做累加。用整数运算,把价格乘以10000(保留4位小数),速度能快3倍。
我的个人习惯:在工程代码里,我会把十档数据单独封装成一个结构体,和基础行情分开。这样后续如果要扩展成二十档,改一个地方就行。别问我怎么知道的——改代码改到吐的经验换来的。
好了,这一节的内容就到这儿。快照数据是Level2行情的基石,十档盘口更是重中之重。下一节我们会继续深入,讲快照数据中的逐笔成交和逐笔委托——那才是真正有意思的东西。
公众号:蓝海资料掘金营,微信deep3321