python中框架封装打包_从零架构一个交易框架(一)
最近同时在操作期货和美股,使用的是同一个策略,只是在参数上有一些不一样,但现在遇到了一个问题就是两边的框架是不一样的,在期货这边用的是tqsdk,而美股是用的 backtrader,所以这就导致了很麻烦的一个事情就是如果策略只要有一点改动,就得把同一个逻辑在不同的框架上都进行修改一次,也因此萌生了自己开发一套轻量的统一交易框架的想法。当然也是先重新调研了一下现在最常见的几个综合框架,包括 vnpy
最近同时在操作期货和美股,使用的是同一个策略,只是在参数上有一些不一样,但现在遇到了一个问题就是两边的框架是不一样的,在期货这边用的是tqsdk,而美股是用的 backtrader,所以这就导致了很麻烦的一个事情就是如果策略只要有一点改动,就得把同一个逻辑在不同的框架上都进行修改一次,也因此萌生了自己开发一套轻量的统一交易框架的想法。
当然也是先重新调研了一下现在最常见的几个综合框架,包括 vnpy 和 quantaxis,还有一些基于web的服务比方说三大矿。具体的 vnpy 和 quantaxis 的区别我之前有写文章对比。总的来说还是不太符合我的需求。
概括说一下我的有差异的需求主要集中在这几点:
- 轻量,易理解。
- 架构易扩展,容易快速开发尝试,在未来可支持毫秒级别高频策略
- 服务稳定、健壮,当然架构的清晰与简洁是服务稳定的一大前提,另一方面就是这套服务应该可以很容易地最终部署在 linux 机器上,服务应该采用 web 开发的原则就是尽可能无状态,任何一个模块遇到问题都应该可以随时重启服务就可恢复
那么我们就来分析一下这个交易框架的架构应该怎么实现。首先关于第一点是很主观的,所以我们从第二点出发来分析:
毫秒级高频策略
这就注定了肯定是 C++ 或者 golang 的逻辑,但有一个问题在于无论是 C++ 还是 golang 它们都不容易快速开发尝试,主要原因在于现在有关财经、数学的第三方的库都基本上是基于 Matlab、R、python的,更不用说机器学习这方面的了。所以如果我们需要为高频策略做规划的话,那这里肯定会涉及到多语言的变迁与支持。也许现阶段在开发的时候以Python为主,未来需要某个模块更高效了,就把对应的模块用更有效率的语言做替换。所以就不可避免地需要考虑RPC的选择。
RPC 框架
关于 RPC 框架其实分了两部分,一个是序列化与反序列化,另一个是连接层选型。
序列化与反序列化主要指标在于打包之后的数据大小、打包解包的时间消耗,次要指标在于能方便快捷地debug排查问题,然后加上之前的经验,备选的框架有 msgpack、protobuf、flatbuffers。在网上找到很多资料之后大概的选项排名是 flatbuffers > msgpack > protobuf,有时间我再专门去亲自测试一下,到时再发一篇对比文章上来。现在本着快速开发的思路先以网上资料为主。
第二个是连接层选型,看上去有很多选项,其实并不多。我们可以考虑的有 http(websocket), zeromq, 以及各种MQ。但我们会发现在这些mq 和 http 的选项都太重了,为了一小段代码需要启动一个完整的服务协议出来,无论是逻辑还是效率都不够好。而 zeromq 的优势在于它是一个很灵活(并且高效)的框架,在开发阶段可以采用inproc的方式在同一进程内实现通讯,在部署中低频策略的时候可以采用tcp的连接方式,如果需要做高频策略的话,还可以用本机的 ipc的方式,甚至回归为 inproc 的连接,而且这些切换只需要改个配置地址就可以了,很是方便,同时还可以无缝地支持广播模式来实现各种MQ的功能。
而对于同为 zeromq 的亲兄弟 nanomq 给我的感觉是缺乏开发与维护,并不像 zeromq 一样积极地去迭代。因此不予考虑。
最后我很幸运地发现了这么一些已经做好封装的 python RPC的框架: mprpc, zerorpc, msgpack-rpc-python,对比一下:
- mprpc 性能最高,采用的是原始 tcp + msgpack,为了高效使用的是C语言的封装
- zerorpc 性能最差,采用的是 zeromq + msgpack,它的特点是框架已经实现了 heartbeat,并且支持 generator 的调用封装
- msgpack-rpc-python 性能居中,tornado 的 tcp部分 + msgpack,没啥别的特点
让人感到很差异的是 zerorpc的性能不是一般的差。采用mprpc里的 benchmark 代码:
(Tmp) ➜ mprpc git:(master) ✗ python benchmarks/benchmark.py
call: 10261 qps
call_using_connection_pool: 16305 qps
(Tmp) ➜ mprpc git:(master) ✗ python benchmarks/benchmark_msgpackrpc_official.py
call: 6295 qps
(Tmp) ➜ mprpc git:(master) ✗ python benchmarks/benchmark_zerorpc.py
call: 1567 qps
这完全不是 msgpack 和 zeromq 组合应有的表现。但最后基于心跳协议的完整性,以及 generator 的支持,还是选择 zerorpc这个框架。原因在于在一个项目的早期,要考虑的不是最终的表现,而是快速试错。而我们只需要保证选型的可扩展性就可以了。因为我们对 zeromq 和 msgpack 的组合有信心,所以在早期我们可以快速迭代重要的部分,而到了后期真的遇到瓶颈了,我们就只是换掉 zerorpc 这个封装,自己再去实现一个高效的 zeromq + msgpack 的库就可以了。
因此,在项目早期,我们的RPC选型就采用 zerorpc
本想一次写完的,但发现只把RPC部分写了就有不少内容。系统的模块和架构我就放到下一篇里吧,RPC和模块架构的部分都是思考和查资料为主,所以产出内容还是快一些,之后关于交易框架的写作计划就会慢下来,因为会先把代码完成,再发文。文章作为代码的一个总结和介绍。
刘敬思:从零架构一个交易框架(二)——行情数据zhuanlan.zhihu.com更多推荐


所有评论(0)