接下来第二条消息的解析方法也差不多,不过此时就需要用到各种操作符了。
第一个字段同样是PMAP,对应字节为90
[90] -> [10] -> 左移一位 -> [20] 0010 0000
字段 | 是否占位 | 是否在数据流中出现 | PMAP中对应位的值 |
---|---|---|---|
模板ID | 是 | 不出现 | 0 |
MDStreamID | 是 | 不出现 | 0 |
SecurityID | 是 | 出现 | 1 |
Symbol | 是 | 不出现 | 0 |
NumTrades | 否 | ||
TradeVolume | 否 | ||
TotalValueTraded | 否 | ||
PrevClosePx | 否 | ||
PrevSetPx | 否 | ||
TotalLongPosition | 否 | ||
MDFullGrp | 是 | 不出现 | 0 |
TradingPhaseCode | 是 | 不出现 | 0 |
·模板ID
不出现,继续使用4001模板。
·MDStreamID
不出现,操作符为copy,取前值,即上一条消息的MDStreamID,为"M0301"。
·SecurityID
[B2] -> "10000912"
在数据流中出现,这个时候就需要知道tail操作符的作用了。
tail操作符需要结合前值才能得到实际值,上一条消息中SecurityID为"10000911",所谓tail接尾,就是将前值的尾部替换,在这里,尾部长度为1,值为"2"。所以替换"10000911"的最后一个字符为"2",就得到了实际值"10000912",此时将该值作为SecurityID的新前值。
·Symbol
不出现
·NumTrades
[7C A1] -> 342
去除停止位得到[7C 21] 01111100 00100001 ,符号位为1,说明该值为负数
[7C 21] -> 自减一 -> [01111100 00100000] -> 取反 -> [10000011 11011111] -> 取出有效位(每个字节的低7位) -> [0000011 1011111] -> -479
delta操作符,所以需要加上前值,即上一条消息里的NumTrades 821。实际值为-479 + 821 = 342,作为该字段的新前值。
·TradeVolume
[6B A8] -> 881
[6B A8] -> [6B 28] 01101011 00101000 -> 符号位1,自减一 -> 01101011 00100111 -> 取反 -> 10010100 11011000 -> 取有效位 -> [0010100 1011000] -> -2648
同样为delta操作符,需要加上前值3529, -2648 + 3529 = 881,该值作为TradeVolume的新前值。
·TotalValueTraded
[81] [1D 4A A1] -> 958045
指数部分:[81] -> [01] -> 0,加上前值的指数部分0,实际值0,该值作为TotalValueTraded指数新前值。
尾数部分:[1D 4A A1] -> [1D 4A 21] -> (1D<<7+4A)<<7+21 = 484641 , 加上前值尾数部分473404,实际值为958045,该值作为TotalValueTraded尾数新前值。
TotalValueTraded实际值958045 * 100 = 958045
·PrevClosePx
[82] [81] -> 0.117
delta操作符,decimal类型,和上面一样的解析方法。
·PrevSetPx
[82] [81] -> 0.117
delta操作符,decimal类型,和上面一样的解析方法。
·TotalLongPosition
[7E 74 ED] -> 3241
负数,自减一取反然后拼凑有效位。delta操作符,加上前值。
·sequence
像第一条消息那样解析sequence即可。
需要注意的一点是,每条消息sequence里的字段前值仅在当前消息数据流中有效。因此下一条消息的sequence解析当做一个全新的sequence开始解析即可。
对于普通字段来说,前值在当前FAST数据流中均有效,不需要重置。
sequence解析结果:
|
|
·TradingPhaseCode
不出现,操作符为copy,取前值,值为"T 01"