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即可。