VNPY之gateway封装思路

vnpy目录下的gateway封装了各种交易接口,以ctp为例,从源码开始,看看vnpy是如何将c++接口一步步转化为python接口,并且实现与系统的交互。

初始材料:交易所提供的c++版本dll以及头文件

ThostFtdcMdApi.h和ThostFtdcTraderApi.h分别是ctp的行情和交易接口,我们就拿行情接口研究(交易接口原理一样)

头文件中定义了2个类 CThostFtdcMdSpi(简称spi)和CThostFtdcMdApi(简称api),他们的具体实现封装在thostmduserapi_se.dll中,api包含主动请求接口,spi是api请求接口的具体实现中会去回调的函数,可以理解为:调用api的ReqUserLogin方法时,ReqUserLogin方法内部会去调用spi的OnRspUserLogin方法。
为了实现c++到python的接口转换,首先构造一个新的C++类:MdApi

MdApi继承自spi,成员变量包含api,以及负责处理回调数据的任务队列task_queue,spi回调函数OnRspMethod此处overwrite,将回调数据封装为task格式推送到task_queue中,最后根据task类型分发给各自的processRspMethod方法进行处理,processRspMethod方法中调用MdApi的onRspMethod方法(on为小写 spi的OnRspMethod为大写)。将api的请求函数统称为Method,其运行流程如下:

MdApi.Method()--->api.Method()--->spi.OnRspMethod()--->回调产生的task--->task_queue.push(task)--->task_queue.pop()--->-MdApi.processRspMethod()-->MdApi.onRspMethod()

将上述c++对象通过pybind11模块编译为python的MdApi类,CtpMdApi继承MdApi,重载onRspMethod方法(实现回调函数逻辑代码),按需求实现接口函数。
到这一步,就完成了接口封装的任务,剩下还需要实现交易接口每次触发回调事件的时候通知事件引擎,相继执行注册在事件引擎中的其他处理函数。vnpy定义了BaseGateway这个交易接口的抽象类

这个类包含:
1.一系列on_event方法,负责生成各种类型的event,推送到事件引擎。
2.一些列行情以及交易需要实现的抽象方法接口。
所以很简单,CtpGateway继承BaseGateway,通过内部成员CtpMdApi去实现父类的抽象函数,然后CtpMdApi的每个onRspMethod中调用BaseGateway的on_event方法,即完整实现了整个调用过程。
另外,当接口变更时,因为vnpy上层逻辑都是通过BaseGateway去实现,所以需要不同接口实现行情交易等功能时,只需要通过反射寻找到相匹配的Gateway即可。

posted @ 2021-07-26 21:15  LazyTiming  阅读(1153)  评论(0编辑  收藏  举报