本文章为说明https://github.com/nicai0609/Python-CTPAPI的pythonCTP接口的使用方法。
首先我们先从下面这个图表大概了解各个函数的作用
消息 | 格式 | 实例 |
请求 | Req—— | ReqUserLogin |
响应 | OnRsp—— | OnRspUserLogin |
查询 | ReqQry—— | ReqQryInstrument |
查询请求的响应 | OnRspQry—— | OnRspQryInstrument |
回报 | OnRtn—— | OnRtnOrder |
错误回报 | OnErrRtn—— | OnErrRtnOrderInsert |
然后看一个下单的示例代码:
- # -*- coding: utf-8 -*-
- import thosttraderapi as api
-
- #Addr交易服务器地址
- FrontAddr="tcp://180.168.146.187:10101"
- #LoginInfo
- BROKERID="9999"
- USERID="070624"
- PASSWORD="070624"
- #OrderInfo
- EXCHANGEID="CFFEX"
- INSTRUMENTID="IF2012"
- PRICE=50000
- VOLUME=1
- # 空
- # DIRECTION=api.THOST_FTDC_D_Sell
- # 多
- DIRECTION=api.THOST_FTDC_D_Buy
- # open开仓
- OFFSET="0"
- # #close平仓
- # OFFSET="1"
-
- def ReqorderfieldInsert(tradeapi):
- print ("ReqOrderInsert Start")
- orderfield=api.CThostFtdcInputOrderField()
- orderfield.BrokerID=BROKERID
- orderfield.ExchangeID=EXCHANGEID
- orderfield.InstrumentID=INSTRUMENTID
- orderfield.UserID=USERID
- orderfield.InvestorID=USERID
- orderfield.Direction=DIRECTION
- orderfield.LimitPrice=PRICE
- orderfield.VolumeTotalOriginal=VOLUME
- 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=OFFSET
- orderfield.GTDDate=""
- orderfield.OrderRef="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) -> "void":
- print ("OnFrontConnected")
- loginfield = api.CThostFtdcReqUserLoginField()
- loginfield.BrokerID=BROKERID
- loginfield.UserID=USERID
- loginfield.Password=PASSWORD
- loginfield.UserProductInfo="python dll"
- self.tapi.ReqUserLogin(loginfield,0)
- print ("send login ok")
-
- def OnRspUserLogin(self, pRspUserLogin: 'CThostFtdcRspUserLoginField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":
- print ("OnRspUserLogin")
- print ("TradingDay=",pRspUserLogin.TradingDay)
- print ("SessionID=",pRspUserLogin.SessionID)
- print ("ErrorID=",pRspInfo.ErrorID)
- print ("ErrorMsg=",pRspInfo.ErrorMsg)
-
- qryinfofield = api.CThostFtdcQrySettlementInfoField()
- qryinfofield.BrokerID=BROKERID
- qryinfofield.InvestorID=USERID
- qryinfofield.TradingDay=pRspUserLogin.TradingDay
- self.tapi.ReqQrySettlementInfo(qryinfofield,0)
- print ("send ReqQrySettlementInfo ok")
-
-
- def OnRspQrySettlementInfo(self, pSettlementInfo: 'CThostFtdcSettlementInfoField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":
- print ("OnRspQrySettlementInfo")
- if pSettlementInfo is not None :
- print ("content:",pSettlementInfo.Content)
- else :
- print ("content null")
- if bIsLast :
- pSettlementInfoConfirm=api.CThostFtdcSettlementInfoConfirmField()
- pSettlementInfoConfirm.BrokerID=BROKERID
- pSettlementInfoConfirm.InvestorID=USERID
- self.tapi.ReqSettlementInfoConfirm(pSettlementInfoConfirm,0)
- print ("send ReqSettlementInfoConfirm ok")
-
- def OnRspSettlementInfoConfirm(self, pSettlementInfoConfirm: 'CThostFtdcSettlementInfoConfirmField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":
- print ("OnRspSettlementInfoConfirm")
- print ("ErrorID=",pRspInfo.ErrorID)
- print ("ErrorMsg=",pRspInfo.ErrorMsg)
- ReqorderfieldInsert(self.tapi)
- print ("send ReqorderfieldInsert ok")
-
-
- def OnRtnOrder(self, pOrder: 'CThostFtdcOrderField') -> "void":
- print ("OnRtnOrder")
- print ("OrderStatus=",pOrder.OrderStatus)
- print ("StatusMsg=",pOrder.StatusMsg)
- print ("LimitPrice=",pOrder.LimitPrice)
-
- def OnRspOrderInsert(self, pInputOrder: 'CThostFtdcInputOrderField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":
- print ("OnRspOrderInsert")
- print ("ErrorID=",pRspInfo.ErrorID)
- print ("ErrorMsg=",pRspInfo.ErrorMsg)
-
- def main():
- tradeapi=api.CThostFtdcTraderApi_CreateFtdcTraderApi()
- tradespi=CTradeSpi(tradeapi)
- tradeapi.RegisterSpi(tradespi)
- tradeapi.SubscribePrivateTopic(api.THOST_TERT_QUICK)
- tradeapi.SubscribePublicTopic(api.THOST_TERT_QUICK)
- tradeapi.RegisterFront(FrontAddr)
- tradeapi.Init()
- tradeapi.Join()
-
- if __name__ == '__main__':
- main()
然后讲下这个程序函数的调用顺序就能很清楚了。
直接来到main函数,
tradeapi.RegisterSpi(tradespi)调用登陆接口,然后会调用我们重载的OnRspUserLogin函数返回登录是否成功的信息;
在OnRspUserLogin函数下会调用self.tapi.ReqQrySettlementInfo(qryinfofield,0)查询历史结算接口,然后会调用我们重载的OnRspQrySettlementInfo
函数返回历史结算的信息;
在OnRspQrySettlementInfo函数下会调用self.tapi.ReqSettlementInfoConfirm(pSettlementInfoConfirm, 0)确认历史结算接口,然后会调用我们重载的OnRspSettlementInfoConfirm函数返回确认历史结算的信息;
在OnRspSettlementInfoConfirm函数下会调用我们自定义的ReqorderfieldInsert(self.tapi)函数,在该自定义函数下会调用CTP下单接口。
整个流程就是这样了,希望对大家有所帮助。
join函数的作用是阻塞当前线程, 直到 tradeapi 线程结束。