一、前言
FAST协议可以支持金融机构间高吞吐量、低延迟的数据通讯,目前我知道的应用领域是沪深交易所的Level-2行情传输。网络上无论是FAST协议本身,还是使用相关工具(openfast、quickfast)对FAST行情进行解析,相关的资料都是凤毛麟角,能够找到本篇的同学那是缘分不浅了。
如果要理解FAST协议,建议还是先用会openfast或quickfast,先用现成的工具实现数据的编码和解码,然后再自己理解协议并手写编码解码,简单来说就是有个对照。我这里使用的是openfast。
二、openfast的编码与解码
如果想了解openfast如何解析FAST数据的完整示例,可以参考我之前的博文。这里我们先简单回顾一下openfast的编码和解码。
完整代码下载:https://share.weiyun.com/jQseMppi
1、消息模版
如下图所示,我们借用UA3815这个消息模版。
2、编码、解码
如下图所示,使用openfast自己先编码再解码,我是参考的一条真实UA3815消息的FAST数据。
输出结果如下,第一行是FAST消息解码结果(解码验证),第二行是将FAST数据按byte输出(编码验证)。
实验结果证明编码与解码的结果符合预期。实际上我也对FAST的byte输出进行了验证,与实际的收到的FAST数据是一致的。
三、openfast逆解析
我找了不少文档看,是真的看不明白,最后想到既然有openfast这个工具,为啥不利用工具来逆解析呢?事实证明效果非常好,而FAST协议真的很简单。下面我们直接来看结果。
1、示例代码
对模版和代码进行修改简化。
代码这里只是做个修改的示例,后面的修改不再赘述。
2、一个int32
下图分别是对空数据、0、1、2、3...256进行FAST编码后的结果,将其转为2进制后可以看到非常明显的规律。
规律一:FAST编码后的数据可以分为三个区域
如下图所示。而且区域三很明显是数值部分,也就是对int 0 FAST编码后的结果就是1000 0000。对256编码的结果就是0000 0010 1000 0000。接着我们就能发现下一个规律。
规律二:数值部分是128进制
也就是每一段(一个byte)满128向前进一位。
127-> 0000 0000, 1111 1111
128-> 0000 0001, 0000 0000
对于更大的数,则是128*128=16384进一位,这时候就需要第三段。
16383-> 0000 0000, 0111 1111, 1111 1111
16384-> 0000 0001, 0000 0000, 1000 0000
以此类推,如果是大于等于128*128*128=2097152,则需要第四段
2097152-> 0000 0001, 0000 0000, 0000 0000, 1000 000
3、两个int32
我们修改代码,这次输入2个int32值看下FAST编码的结果。
规律三:每一个byte的第一位是“分隔符”(停止位)
这里的分隔不仅将不同区域分隔,同一区域的不同字段也使用首位的“1”来分隔。
规律四:区域一标识了当前有多少个字段。
区域一的值:
空-> 1100 0000
一个数值字段-> 1110 0000
两个数值字段-> 1111 0000
我试了下14个数值字段:0111 1111,0111 1111,1100 0000
如下图,区域一标识了区域二(占一位),区域三(有多少个字段就标识多少个1)。同时区域一还遵循了规律三。
4、修改模版ID
输出结果:
规律五:区域二标识的是注册的模版ID,但与模版文件里的ID无关系。
5、数值类型
做沪市FAST行情解析,目前来看只用到了int32、int64、string三种类型,我们各放一个字段试试。
修改模版:
修改代码:
输出结果:
可以看到,int32和int64在FAST编码时无区别。
String则是直接转成了ASCII码:55->7、56->8、(185-128)=57->9
四、FAST编码解码基本规则
综上,我们通过openfast的使用,对FAST编码解码规则有了一些较为浅显的理解,现结合官方文档(https://jettekfix.com/education/fix-fast-tutorial/)总结如下:
规则一:FAST数据可分为三个区域,区域一是PMap字段(存在图),作用是标识出消息中的字段数量。区域二是模版ID字段,作用是标识出你注册的模版ID号,但这个ID与模版文件中的ID无关系。区域三是数值部分,可由多个字段顺序组成。
规则二:字段大小可变,通过对“停止位”的使用,将每个字节的第一位置为0或1以标识出该字段是否结束。其中0表示未结束,1表示结束。
规则三:数值需要按byte去掉第一位的0或1再来算值。Int类型直接二进制转整数,string类型则是二进制先转整数再由ASCII码表转字符。
五、回顾
本篇我们利用openfast来逆解析FAST协议,这么做之前,看相关文档资料即使是中文的也看不明白,但自己尝试了一下之后,发现即使是英文文档也能看明白了。
但目前只是总结了一些基本规律,看文档发现,还有很多知识点在模版上,后面再花时间研究了。关于这部分,可能直接翻译官方文档并使用openfast验证比较好。