CTP Python API(利用Swig 封裝)Windows版(traderapi)
前言:
目前上期技術CTP系統提供的API版本是C++
版本,本文主要介紹Windows 32位平臺下利用Swig工具將CTP C++介面trader API轉換為python可呼叫的介面。此版本是在原先版本上的升級,解決了onfrontconnected回撥的宕機問題。感謝知乎網友@warlock 一起探討。
1. 準備工作
從CTP官網上下載
CTP API
點選下載。32位的API檔案包清單如下:
error.dtd
error.xml
ThostFtdcMdApi.h
ThostFtdcTraderApi.h
ThostFtdcUserApiDataType.h
ThostFtdcUserApiStruct.h
thostmduserapi.dll
thostmduserapi.lib
thosttraderapi.dll
thosttraderapi.libThostFtdcUserApiDataType.h
中找出如下幾行註釋掉(對使用者沒有影響,但會影響python API編譯)
///銀行發起銀行資金轉期貨
//#define THOST_FTDC_VTC_BankBankToFuture '102001'
///銀行發起期貨資金轉銀行
//#define THOST_FTDC_VTC_BankFutureToBank '102002'
///期貨發起銀行資金轉期貨
//#define THOST_FTDC_VTC_FutureBankToFuture '202001'
///期貨發起期貨資金轉銀行
//#define THOST_FTDC_VTC_FutureFutureToBank '202002'
///銀行發起銀行轉期貨
//#define THOST_FTDC_FTC_BankLaunchBankToBroker '102001'
///期貨發起銀行轉期貨
//#define THOST_FTDC_FTC_BrokerLaunchBankToBroker '202001'
///銀行發起期貨轉銀行
//#define THOST_FTDC_FTC_BankLaunchBrokerToBank '102002'
///期貨發起期貨轉銀行
//#define THOST_FTDC_FTC_BrokerLaunchBrokerToBank '202002'
- 安裝Swig軟體,本文中所用的Swig是
swigwin-2.0.11
版本,點選下載。 - 安裝python,注意要安裝32位版本,將環境變數配置好。本文所用的是
2.7.12
版本。
2. 通過Swig得到python介面檔案
在剛剛下載得到的API資料夾20160606_tradeapi_windows
內,新建檔案thosttraderapi.i
,內容如下
%module(directors="1") thosttraderapi
%{
#include "ThostFtdcTraderApi.h"
%}
%feature("director") CThostFtdcTraderSpi;
%include "ThostFtdcUserApiDataType.h"
%include "ThostFtdcUserApiStruct.h"
%include "ThostFtdcTraderApi.h"
這是一個介面檔案,用於告訴swig為哪些類和方法建立介面。開啟windows cmd
工具,cd
到當前目錄\20160606_tradeapi_windows
下。 在cmd
中執行命令
swig -threads -c++ -python thosttraderapi.i
等到執行完成後,可以看到當前目錄下生成了
thosttraderapi_wrap.h
thosttraderapi_wrap.cxx
thosttradeapi.py
.h
和.cx
檔案是用於包裝原來C++
介面的檔案,下面要用。.py
檔案是python呼叫方法的介面檔案。
3. 通過C++得到python可呼叫的pyd動態庫
在當前資料夾下建立一個C++工程,工程的應用程式型別選DLL
,工程名為_thosttraderapi
,將如下檔案拷貝到_thosttraderapi\_thosttraderapi\
資料夾下:
ThostFtdcTraderApi.h
ThostFtdcUserApiDataType.h
ThostFtdcUserApiStruct.h
thosttraderapi.lib
thosttraderapi_wrap.cxx
thosttraderapi_wrap.h
在c++
工程中新增現有項,將這些檔案全部新增到工程中去。下面還要做幾步:
- 將你安裝的python下include資料夾的路徑新增至
C++
附加包含目錄。我的路徑是C:\Python27\include;
,C++
附加包含目錄在工程-屬性-配置屬性-c/c++
處。 - 將你安裝的python中python27.lib新增至工程附加依賴項中。我的lib路徑是
C:\Python27\libs\python27.lib
,附加依賴項在工程-屬性-配置屬性-連結器-輸入處。
這樣全部完成之後,我們按F7編譯,在\_thosttraderapi\Debug
目錄底下可見_thosttraderapi.dll
動態庫檔案,說明編譯成功,將其重新命名為_thosttraderapi.pyd
,這樣CTP Python API
就編譯成功了。
如果編譯出現一些問題,可以百度解決。可能涉及到要修改pyconfig.h,object.h,Python.h
三個檔案。
4. Python Demo
新建檔案traderapi_demo.py,注意檔案同目錄底下要有如下三個檔案:
thosttradeapi.py
thosttraderapi.dll
_thosttradeapi.pyd
本demo實現登入成功後報單,收報單回報的功能。完整的demo程式碼如下:
# -*- coding: gbk -*-
import thosttraderapi as api
def ReqorderfieldInsert(tradeapi):
print "ReqOrderInsert Start"
orderfield=api.CThostFtdcInputOrderField()
orderfield.BrokerID="8000"
orderfield.InstrumentID="sc1412"
orderfield.UserID="000005"
orderfield.InvestorID="000005"
orderfield.Direction=api.THOST_FTDC_D_Sell
orderfield.LimitPrice=52050
orderfield.VolumeTotalOriginal=1
orderfield.OrderPriceType=api.THOST_FTDC_OPT_LimitPrice
orderfield.ContingentCondition = api.THOST_FTDC_CC_Immediately
orderfield.TimeCondition = api.THOST_FTDC_TC_GFD
orderfield.VolumeCondition = api.THOST_FTDC_VC_AV
orderfield.CombHedgeFlag="1"
orderfield.CombOffsetFlag="0"
orderfield.GTDDate=""
orderfield.orderfieldRef="1"
orderfield.MinVolume = 0
orderfield.ForceCloseReason = api.THOST_FTDC_FCC_NotForceClose
orderfield.IsAutoSuspend = 0
tradeapi.ReqOrderInsert(orderfield,0)
print "ReqOrderInsert End"
class CTradeSpi(api.CThostFtdcTraderSpi):
tapi=''
def __init__(self,tapi):
api.CThostFtdcTraderSpi.__init__(self)
self.tapi=tapi
def OnFrontConnected(self):
print "OnFrontConnected"
loginfield = api.CThostFtdcReqUserLoginField()
loginfield.BrokerID="8000"
loginfield.UserID="000005"
loginfield.Password="123456"
loginfield.UserProductInfo="python dll"
self.tapi.ReqUserLogin(loginfield,0)
def OnRspUserLogin(self, *args):
print "OnRspUserLogin"
rsploginfield=args[0]
rspinfofield=args[1]
print "SessionID=",rsploginfield.SessionID
print "ErrorID=",rspinfofield.ErrorID
print "ErrorMsg=",rspinfofield.ErrorMsg
ReqorderfieldInsert(self.tapi)
def OnRtnOrder(self, *args):
print "OnRtnOrder"
rtnfield=args[0]
print "OrderStatus=",rtnfield.OrderStatus
print "StatusMsg=",rtnfield.StatusMsg
print "LimitPrice=",rtnfield.LimitPrice
def OnRspOrderInsert(self, *args):
print "OnRspOrderInsert"
rspinfofield=args[1]
print "ErrorID=",rspinfofield.ErrorID
print "ErrorMsg=",rspinfofield.ErrorMsg
def main():
tradeapi=api.CThostFtdcTraderApi_CreateFtdcTraderApi()
tradespi=CTradeSpi(tradeapi)
tradeapi.RegisterFront("tcp://172.19.125.39:39233")
tradeapi.RegisterSpi(tradespi)
tradeapi.SubscribePrivateTopic(api.THOST_TERT_RESUME)
tradeapi.SubscribePublicTopic(api.THOST_TERT_RESUME)
tradeapi.Init()
tradeapi.Join()
if __name__ == '__main__':
main()
本人所編譯的CTP0606版本的交易、行情Python API
,點選下載。宣告:僅是個人愛好編譯,對此API引起的你的任何損失不負責任。