前言:
前面写了那么多函数,想用起来并不难,只要把之前写的函数都放在一起就可以了,这里演示怎么使用这个框架,注意要使用模拟盘账号。
代码:
from multiprocessing import Queue
from program.function import *
class CTraderSpi(tdapi.CThostFtdcTraderSpi):
def __init__(self, tduserapi, Account):
tdapi.CThostFtdcTraderSpi.__init__(self)
self.tduserapi = tduserapi
self.Account = Account
# 连接前台
def OnFrontConnected(self):
print("开始建立交易连接")
authfield = tdapi.CThostFtdcReqAuthenticateField()
authfield.BrokerID = str(self.Account.broker_id)
authfield.UserID = str(self.Account.investor_id)
authfield.AppID = str(self.Account.app_id)
authfield.AuthCode = str(self.Account.auth_code)
ret = self.tduserapi.ReqAuthenticate(authfield, 0)
if ret == 0:
print('发送穿透式认证请求成功!')
else:
print('发送穿透式认证请求失败!')
judge_ret(ret)
# 穿透式认证响应
def OnRspAuthenticate(self, pRspAuthenticateField, pRspInfo, nRequestID: 'int', bIsLast: 'bool'):
if pRspInfo.ErrorID != 0 and pRspInfo != None:
print('穿透式认证失败\n错误信息为:{}\n错误代码为:{}'.format(pRspInfo.ErrorMsg, pRspInfo.ErrorID))
else:
print('穿透式认证成功!')
# 发送登录请求
loginfield = tdapi.CThostFtdcReqUserLoginField()
loginfield.BrokerID = str(self.Account.broker_id)
loginfield.UserID = str(self.Account.investor_id)
loginfield.Password = str(self.Account.password)
ret = self.tduserapi.ReqUserLogin(loginfield, 0)
if ret == 0:
print('发送登录交易账户成功!')
else:
print('发送登录交易账户失败!')
judge_ret(ret)
# 用户登录结果返回
def OnRspUserLogin(self, pRspUserLogin, pRspInfo, nRequestID, bIsLast):
if pRspInfo.ErrorID != 0 and pRspInfo != None:
print('登录交易账户失败\n错误信息为:{}\n错误代码为:{}'.format(pRspInfo.ErrorMsg, pRspInfo.ErrorID))
else:
print('登录交易账户成功!')
# 保存数据用于下单
g.frontID = pRspUserLogin.FrontID
g.sessionID = pRspUserLogin.SessionID
g.maxOrderRef = int(pRspUserLogin.MaxOrderRef)
# 保存交易日
g.tradingDay = pRspUserLogin.TradingDay
pSettlementInfoConfirm = tdapi.CThostFtdcSettlementInfoConfirmField()
pSettlementInfoConfirm.BrokerID = str(self.Account.broker_id)
pSettlementInfoConfirm.InvestorID = str(self.Account.investor_id)
ret = self.tduserapi.ReqSettlementInfoConfirm(pSettlementInfoConfirm, 0)
if ret == 0:
print('发送结算单确认请求成功!')
else:
print('发送结算单确认请求失败!')
judge_ret(ret)
# 结算单结果确认
def OnRspSettlementInfoConfirm(self, pSettlementInfoConfirm, pRspInfo, nRequestID, bIsLast):
if pRspInfo.ErrorID != 0 and pRspInfo != None:
print('结算单确认失败\n错误信息为:{}\n错误代码为:{}'.format(pRspInfo.ErrorMsg, pRspInfo.ErrorID))
else:
print('结算单确认成功!')
# 报单通知
# 当委托状态发生变化时,会被回调。常见委托状态主要有:未知、未成交还在队列中、部分成交还在队列中、完全成交等。
# 一次报单,如果数量比较多,一般不会一次全部成交,而是会分多批次成交,
# 所以会不断被回调。随着不断回调,每次返回的委托量、成交量、剩余量等数据会不断变更。
def OnRtnOrder(self, pOrder):
try:
# 报单已提交
if pOrder.OrderStatus == 'a':
print('报单已提交')
g.order_map[pOrder.OrderRef].pOrder = copy.copy(pOrder)
# 未成交
elif pOrder.OrderStatus == '3':
# print(pOrder.StatusMsg)
print('未成交')
# 全部成交
elif pOrder.OrderStatus == '0':
# print(pOrder.StatusMsg)
print('全部成交')
# 撤单
elif pOrder.OrderStatus == '5':
# print(pOrder.OrderStatus)
# 被动撤单
if pOrder.OrderSubmitStatus == '4':
print('被动撤单')
print(pOrder.StatusMsg)
else:
print(pOrder.OrderSubmitStatus)
print('撤单')
print(pOrder.StatusMsg)
# 部分成交,还在队列中
elif pOrder.OrderStatus == '1':
print(pOrder.OrderStatus)
print('部分成交,还在队列中')
else:
print("OnRtnOrder")
print("OrderStatus=", pOrder.OrderStatus)
print("StatusMsg=", pOrder.StatusMsg)
except Exception as e:
red_print(e)
# 报单录入请求响应,基本上成功不会回报,错误会回报, 当前报单者收到的回调
def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast):
print("OnRspOrderInsert")
print("ErrorID=", pRspInfo.ErrorID)
print("ErrorMsg=", pRspInfo.ErrorMsg)
# 成交回报
def OnRtnTrade(self, pTrade):
try:
pTrade={
'报单引用': pTrade.OrderRef,
'交易所代码': pTrade.ExchangeID,
'合约代码': pTrade.InstrumentID,
'成交编号': pTrade.TradeID,
'买卖方向': pTrade.Direction,
'报单编号': pTrade.OrderSysID,
'价格': pTrade.Price,
'数量': pTrade.Volume,
'成交时期': pTrade.TradeDate,
'成交时间': pTrade.TradeTime,
}
print(pTrade)
except Exception as e:
red_print(e)
# 报单操作错误回报,当执行ReqOrderAction后有字段填写不对之类的CTP报错则通过此接口返回
def OnErrRtnOrderAction(self, pOrderAction, pRspInfo):
try:
if pRspInfo.ErrorID != 0 and pR
本主题为课程学员专享,成为股票量化投资课程学员后可免费阅读
成为学员