本文章为说明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 线程结束。