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 知识体系结构图

下面这张图,是我自己梳理的快照数据解析流程。你看一遍,基本就明白整个脉络了。

快照数据解析知识体系 Level2 快照数据包 基础行情数据 十档买卖盘口 统计汇总数据 昨收价 / 今开盘 最高价 / 最低价 / 最新价 成交量 / 成交额 买一~买十 价格 & 数量 卖一~卖十 价格 & 数量 盘口力度比 总委买量 / 总委卖量 加权平均委买价 加权平均委卖价 工程化应用:实时监控 / 策略信号 / 回测分析

4.5 工程化处理要点

最后,聊几个工程上的坑。我当年做实时行情系统时,总结了几条铁律:

  • 数据校验不能省:每次收到快照,先检查买一价是否小于卖一价。如果违反,直接丢弃。别问我为什么——网络抖动时,什么妖魔鬼怪数据都有。
  • 缓存设计要合理:快照数据一般3秒推送一次。我建议用环形缓冲区存最近10个快照,方便做趋势对比。
  • 计算加权价时注意性能:如果你要实时计算所有股票的加权价,别用double做累加。用整数运算,把价格乘以10000(保留4位小数),速度能快3倍。

我的个人习惯:在工程代码里,我会把十档数据单独封装成一个结构体,和基础行情分开。这样后续如果要扩展成二十档,改一个地方就行。别问我怎么知道的——改代码改到吐的经验换来的。

好了,这一节的内容就到这儿。快照数据是Level2行情的基石,十档盘口更是重中之重。下一节我们会继续深入,讲快照数据中的逐笔成交和逐笔委托——那才是真正有意思的东西。


公众号:蓝海资料掘金营,微信deep3321