原创 +1银贝 期货ctp量化系列————ctp框架使用示例

小小的夏天 2023-11-12 125

前言:

前面写了那么多函数,想用起来并不难,只要把之前写的函数都放在一起就可以了,这里演示怎么使用这个框架,注意要使用模拟盘账号。

代码:

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

本主题为课程学员专享,成为股票量化投资课程学员后可免费阅读

成为学员
最新回复 ( 0条评论 )


官方微信
码力十足学量化
Powered by Xiuno BBS 4.0.7

官方微信