2022年 11月 3日

python,CTP接口函数调用逻辑

本文章为说明https://github.com/nicai0609/Python-CTPAPI的pythonCTP接口的使用方法。

首先我们先从下面这个图表大概了解各个函数的作用

消息 格式 实例
请求 Req—— ReqUserLogin
响应 OnRsp—— OnRspUserLogin
查询 ReqQry—— ReqQryInstrument
查询请求的响应 OnRspQry—— OnRspQryInstrument
回报 OnRtn—— OnRtnOrder
错误回报 OnErrRtn—— OnErrRtnOrderInsert

 然后看一个下单的示例代码:

  1. # -*- coding: utf-8 -*-
  2. import thosttraderapi as api
  3. #Addr交易服务器地址
  4. FrontAddr="tcp://180.168.146.187:10101"
  5. #LoginInfo
  6. BROKERID="9999"
  7. USERID="070624"
  8. PASSWORD="070624"
  9. #OrderInfo
  10. EXCHANGEID="CFFEX"
  11. INSTRUMENTID="IF2012"
  12. PRICE=50000
  13. VOLUME=1
  14. # 空
  15. # DIRECTION=api.THOST_FTDC_D_Sell
  16. # 多
  17. DIRECTION=api.THOST_FTDC_D_Buy
  18. # open开仓
  19. OFFSET="0"
  20. # #close平仓
  21. # OFFSET="1"
  22. def ReqorderfieldInsert(tradeapi):
  23. print ("ReqOrderInsert Start")
  24. orderfield=api.CThostFtdcInputOrderField()
  25. orderfield.BrokerID=BROKERID
  26. orderfield.ExchangeID=EXCHANGEID
  27. orderfield.InstrumentID=INSTRUMENTID
  28. orderfield.UserID=USERID
  29. orderfield.InvestorID=USERID
  30. orderfield.Direction=DIRECTION
  31. orderfield.LimitPrice=PRICE
  32. orderfield.VolumeTotalOriginal=VOLUME
  33. orderfield.OrderPriceType=api.THOST_FTDC_OPT_LimitPrice
  34. orderfield.ContingentCondition = api.THOST_FTDC_CC_Immediately
  35. orderfield.TimeCondition = api.THOST_FTDC_TC_GFD
  36. orderfield.VolumeCondition = api.THOST_FTDC_VC_AV
  37. orderfield.CombHedgeFlag="1"
  38. orderfield.CombOffsetFlag=OFFSET
  39. orderfield.GTDDate=""
  40. orderfield.OrderRef="1"
  41. orderfield.MinVolume = 0
  42. orderfield.ForceCloseReason = api.THOST_FTDC_FCC_NotForceClose
  43. orderfield.IsAutoSuspend = 0
  44. tradeapi.ReqOrderInsert(orderfield,0)
  45. print ("ReqOrderInsert End")
  46. class CTradeSpi(api.CThostFtdcTraderSpi):
  47. tapi=''
  48. def __init__(self,tapi):
  49. api.CThostFtdcTraderSpi.__init__(self)
  50. self.tapi=tapi
  51. def OnFrontConnected(self) -> "void":
  52. print ("OnFrontConnected")
  53. loginfield = api.CThostFtdcReqUserLoginField()
  54. loginfield.BrokerID=BROKERID
  55. loginfield.UserID=USERID
  56. loginfield.Password=PASSWORD
  57. loginfield.UserProductInfo="python dll"
  58. self.tapi.ReqUserLogin(loginfield,0)
  59. print ("send login ok")
  60. def OnRspUserLogin(self, pRspUserLogin: 'CThostFtdcRspUserLoginField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":
  61. print ("OnRspUserLogin")
  62. print ("TradingDay=",pRspUserLogin.TradingDay)
  63. print ("SessionID=",pRspUserLogin.SessionID)
  64. print ("ErrorID=",pRspInfo.ErrorID)
  65. print ("ErrorMsg=",pRspInfo.ErrorMsg)
  66. qryinfofield = api.CThostFtdcQrySettlementInfoField()
  67. qryinfofield.BrokerID=BROKERID
  68. qryinfofield.InvestorID=USERID
  69. qryinfofield.TradingDay=pRspUserLogin.TradingDay
  70. self.tapi.ReqQrySettlementInfo(qryinfofield,0)
  71. print ("send ReqQrySettlementInfo ok")
  72. def OnRspQrySettlementInfo(self, pSettlementInfo: 'CThostFtdcSettlementInfoField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":
  73. print ("OnRspQrySettlementInfo")
  74. if pSettlementInfo is not None :
  75. print ("content:",pSettlementInfo.Content)
  76. else :
  77. print ("content null")
  78. if bIsLast :
  79. pSettlementInfoConfirm=api.CThostFtdcSettlementInfoConfirmField()
  80. pSettlementInfoConfirm.BrokerID=BROKERID
  81. pSettlementInfoConfirm.InvestorID=USERID
  82. self.tapi.ReqSettlementInfoConfirm(pSettlementInfoConfirm,0)
  83. print ("send ReqSettlementInfoConfirm ok")
  84. def OnRspSettlementInfoConfirm(self, pSettlementInfoConfirm: 'CThostFtdcSettlementInfoConfirmField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":
  85. print ("OnRspSettlementInfoConfirm")
  86. print ("ErrorID=",pRspInfo.ErrorID)
  87. print ("ErrorMsg=",pRspInfo.ErrorMsg)
  88. ReqorderfieldInsert(self.tapi)
  89. print ("send ReqorderfieldInsert ok")
  90. def OnRtnOrder(self, pOrder: 'CThostFtdcOrderField') -> "void":
  91. print ("OnRtnOrder")
  92. print ("OrderStatus=",pOrder.OrderStatus)
  93. print ("StatusMsg=",pOrder.StatusMsg)
  94. print ("LimitPrice=",pOrder.LimitPrice)
  95. def OnRspOrderInsert(self, pInputOrder: 'CThostFtdcInputOrderField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":
  96. print ("OnRspOrderInsert")
  97. print ("ErrorID=",pRspInfo.ErrorID)
  98. print ("ErrorMsg=",pRspInfo.ErrorMsg)
  99. def main():
  100. tradeapi=api.CThostFtdcTraderApi_CreateFtdcTraderApi()
  101. tradespi=CTradeSpi(tradeapi)
  102. tradeapi.RegisterSpi(tradespi)
  103. tradeapi.SubscribePrivateTopic(api.THOST_TERT_QUICK)
  104. tradeapi.SubscribePublicTopic(api.THOST_TERT_QUICK)
  105. tradeapi.RegisterFront(FrontAddr)
  106. tradeapi.Init()
  107. tradeapi.Join()
  108. if __name__ == '__main__':
  109. 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 线程结束。