富途牛牛是唯数不多的互联网券商,有详细的API文档(同样有开放API的雪盈、老虎)但技术上都没有富途那么专业和强大。
最近刚好要写一个拉取富途行情数据的接口,用来做小工具—价格向右回撤提醒工具,一旦价格符合设定的点立即电话通知我出货。
这些年对过的API接口也不少,一开始我以为能很快用Ruby对接好,但实际上我错了,整整花费了大半个月。借此我也更深入的了解http与tcp之间的关系。自定义的tcp协议要如何对接等。
其实市场上是有其他开源的php/go/java对接好的源代码,但我不信,我就是想要用Ruby来对接…..
文档地址:https://openapi.futunn.com/futu-api-doc/
文档使用了自定义tcp头 + google Protobuf 协议介绍
这就导致了只有http api对接经验的我,一下子要对接tcp协议一下懵逼了,也没有人能请教,只有自己死磕。
这里讲一讲自己的理解:
http是应用层协议基于tcp传输层,所以tcp更底层一点,tcp有协议头和协议体。其中协议体可以用富途提供的Google protobuf来解析出具体数据,这里重点是协议头,在ruby中要如何解析,解析出来之后,每次通信就能算得我们想要的数据了
这里直接上Ruby代码解析协议头的代码:
首先安装2个相关的gem:
12gem 'google-protobuf'gem 'bindata'解析和序列Tcp头部信息相关的代码:
这里按websocket协议写的协议头信息,可能写官方API文档不太一样
1234567891011121314151617请求Request的相关代码class ReqHead < BinData::Recordendian :bigstring :sign, read_length: 8uint32 :cmduint64 :sectionend响应Response的相关代码class ResHead < BinData::Recordendian :bigstring :sign, read_length: 8uint32 :cmduint64 :sectionuint32 :errorstring :errmsg, read_length: 20end每次请求,Request的头部信息这样序列:
123456def header body_binary, idres = Futu::ReqHead.new sign: "ft-v1.0\x00",cmd: id,section: serial_idres.to_binary_send每次接收到请求时这样解析:
123def parse_header binaryFutu::ResHead.read binaryend
解决完协议头部信息后,再来解决协议体的解析
协议体是从44位开始的,所以也挺简单,假设我们接收到的response赋值给raw_data,那么解析方法如下:
|
|
具体这个TrdGetAccList::Response文件要怎么生成和引入,请参考:https://developers.google.com/protocol-buffers/docs/reference/ruby-generated
说说Websocket连接时和普通tcp连接的区别
- 不再需要间隔一段时间发送keep alive保活
- 协议头有所变化,见我上方代码中的协议头