Пример #1
0
class Test:
    def __init__(self):
        self.Session = ''
        self.q = Quote()
        self.t = Trade()
        self.req = 0
        self.ordered = False
        self.needAuth = False
        self.RelogEnable = True

    def q_OnFrontConnected(self):
        print('connected')
        self.q.ReqUserLogin(BrokerID=self.broker,
                            UserID=self.investor,
                            Password=self.pwd)

    def q_OnRspUserLogin(self, rsp, info, req, last):
        print(info)

        #insts = create_string_buffer(b'cu', 5)
        self.q.SubscribeMarketData('rb1810')

    def q_OnTick(self, tick):
        f = CThostFtdcMarketDataField()
        f = tick
        #print(tick)

        if not self.ordered:
            _thread.start_new_thread(self.Order, (f, ))
            self.ordered = True

    def Order(self, f):
        print("报单")
        self.req += 1
        self.t.ReqOrderInsert(
            BrokerID=self.broker,
            InvestorID=self.investor,
            InstrumentID=f.getInstrumentID(),
            OrderRef='{0:>12}'.format(self.req),
            UserID=self.investor,
            OrderPriceType=OrderPriceTypeType.LimitPrice,
            Direction=DirectionType.Buy,
            CombOffsetFlag=OffsetFlagType.Open.__char__(),
            CombHedgeFlag=HedgeFlagType.Speculation.__char__(),
            LimitPrice=f.getLastPrice() - 50,
            VolumeTotalOriginal=1,
            TimeCondition=TimeConditionType.GFD,
            #GTDDate=''
            VolumeCondition=VolumeConditionType.AV,
            MinVolume=1,
            ContingentCondition=ContingentConditionType.Immediately,
            StopPrice=0,
            ForceCloseReason=ForceCloseReasonType.NotForceClose,
            IsAutoSuspend=0,
            IsSwapOrder=0,
            UserForceClose=0)

    def OnFrontConnected(self):
        if not self.RelogEnable:
            return
        print('connected')
        if self.needAuth:
            self.t.ReqAuthenticate(self.broker, self.investor, '@haifeng',
                                   '8MTL59FK1QGLKQW2')
        else:
            self.t.ReqUserLogin(BrokerID=self.broker,
                                UserID=self.investor,
                                Password=self.pwd,
                                UserProductInfo='@haifeng')

    def OnRspAuthenticate(self,
                          pRspAuthenticateField=CThostFtdcRspAuthenticateField,
                          pRspInfo=CThostFtdcRspInfoField,
                          nRequestID=int,
                          bIsLast=bool):
        print('auth:{0}:{1}'.format(pRspInfo.getErrorID(),
                                    pRspInfo.getErrorMsg()))
        self.t.ReqUserLogin(BrokerID=self.broker,
                            UserID=self.investor,
                            Password=self.pwd,
                            UserProductInfo='@haifeng')

    def OnRspUserLogin(self, rsp, info, req, last):
        i = CThostFtdcRspInfoField()
        i = info
        print(i.getErrorMsg())

        if i.getErrorID() == 0:
            self.Session = rsp.getSessionID()
            self.t.ReqSettlementInfoConfirm(BrokerID=self.broker,
                                            InvestorID=self.investor)
        else:
            self.RelogEnable = False

    def OnRspSettlementInfoConfirm(
            self,
            pSettlementInfoConfirm=CThostFtdcSettlementInfoConfirmField,
            pRspInfo=CThostFtdcRspInfoField,
            nRequestID=int,
            bIsLast=bool):
        #print(pSettlementInfoConfirm)
        _thread.start_new_thread(self.StartQuote, ())

    def StartQuote(self):
        api = self.q.CreateApi()
        spi = self.q.CreateSpi()
        self.q.RegisterSpi(spi)

        self.q.OnFrontConnected = self.q_OnFrontConnected
        self.q.OnRspUserLogin = self.q_OnRspUserLogin
        self.q.OnRtnDepthMarketData = self.q_OnTick

        self.q.RegCB()

        self.q.RegisterFront(self.frontAddr.split(',')[1])
        self.q.Init()
        #self.q.Join()

    def Qry(self):
        sleep(1.1)
        self.t.ReqQryInstrument()
        while True:
            sleep(1.1)
            self.t.ReqQryTradingAccount(self.broker, self.investor)
            sleep(1.1)
            self.t.ReqQryInvestorPosition(self.broker, self.investor)
            return

    def OnRtnInstrumentStatus(self,
                              pInstrumentStatus=CThostFtdcInstrumentStatusField
                              ):
        pass

    def OnRspOrderInsert(self,
                         pInputOrder=CThostFtdcInputOrderField,
                         pRspInfo=CThostFtdcRspInfoField,
                         nRequestID=int,
                         bIsLast=bool):
        print(pRspInfo)
        print(pInputOrder)
        print(pRspInfo.getErrorMsg())

    def OnRtnOrder(self, pOrder=CThostFtdcOrderField):
        #print(pOrder)
        if pOrder.getSessionID() == self.Session and pOrder.getOrderStatus(
        ) == OrderStatusType.NoTradeQueueing:
            print("撤单")
            self.t.ReqOrderAction(self.broker,
                                  self.investor,
                                  InstrumentID=pOrder.getInstrumentID(),
                                  OrderRef=pOrder.getOrderRef(),
                                  FrontID=pOrder.getFrontID(),
                                  SessionID=pOrder.getSessionID(),
                                  ActionFlag=ActionFlagType.Delete)

    def Run(self):
        #CreateApi时会用到log目录,需要在程序目录下创建**而非dll下**
        api = self.t.CreateApi()
        spi = self.t.CreateSpi()
        self.t.RegisterSpi(spi)

        self.t.OnFrontConnected = self.OnFrontConnected
        self.t.OnRspUserLogin = self.OnRspUserLogin
        self.t.OnRspSettlementInfoConfirm = self.OnRspSettlementInfoConfirm
        self.t.OnRspAuthenticate = self.OnRspAuthenticate
        self.t.OnRtnInstrumentStatus = self.OnRtnInstrumentStatus
        self.t.OnRspOrderInsert = self.OnRspOrderInsert
        self.t.OnRtnOrder = self.OnRtnOrder
        #_thread.start_new_thread(self.Qry, ())

        self.t.RegCB()

        self.frontAddr = 'tcp://180.168.146.187:10000,tcp://180.168.146.187:10010'
        self.broker = '9999'
        self.investor = '008105'
        self.pwd = '1'

        self.t.RegisterFront(self.frontAddr.split(',')[0])
        self.t.SubscribePrivateTopic(nResumeType=2)  #quick
        self.t.SubscribePrivateTopic(nResumeType=2)
        self.t.Init()
        self.t.Join()
Пример #2
0
class CtpTrade(TradeAdapter):
    """"""
    def __init__(self):
        super().__init__()
        self._req = 0
        '''防止重连时启用太多查询线程'''
        self.qryStart = False
        self.__dic_orderid_sysid = {}
        self.__posi = []
        self.t = Trade()

    def __qry(self):
        """查询帐号相关信息"""
        self.qryStart = True
        # restart 模式, 待rtnorder 处理完毕后再进行查询,否则会造成position混乱
        ord_cnt = 0
        while True:
            time.sleep(0.5)
            if len(self.DicOrderField) == ord_cnt:
                break
            ord_cnt = len(self.DicOrderField)
        self.t.ReqQryInstrument()
        time.sleep(1.1)
        while not self.Account or self.IsLogin:
            """查询持仓与权益"""
            time.sleep(1.1)
            self.t.ReqQryInvestorPosition(self.BrokerID, self.Investor)
            time.sleep(1.1)
            self.t.ReqQryTradingAccount(self.BrokerID, self.Investor)

    def __OnFrontConnected(self):
        self.OnFrontConnected()

    def __OnFrontDisconnected(self, nReason):
        self.IsLogin = False
        self.OnFrontDisConnected(nReason)

    def __OnRspUserLogin(self,
                         pRspUserLogin=CThostFtdcRspUserLoginField(),
                         pRspInfo=CThostFtdcRspInfoField,
                         nRequestID=int,
                         bIsLast=bool):

        self.Investor = pRspUserLogin.getUserID()
        self.BrokerID = pRspUserLogin.getBrokerID()

        self.SessionID = pRspUserLogin.getSessionID()
        self.TradingDay = pRspUserLogin.getTradingDay()

        if pRspInfo.getErrorID() != 0:
            info = InfoField()
            info.ErrorID = pRspInfo.getErrorID()
            info.ErrorMsg = pRspInfo.getErrorMsg()
            self.OnRspUserLogin(info)
        else:
            self.t.ReqSettlementInfoConfirm(self.BrokerID, self.Investor)
            if not self.qryStart:
                time.sleep(0.5)
                """查询持仓与权益"""
                _thread.start_new_thread(self.__qry, ())  # 开启查询

    def __OnRspQryInstrument(self,
                             pInstrument=CThostFtdcInstrumentField,
                             pRspInfo=CThostFtdcRspInfoField,
                             nRequestID=int,
                             bIsLast=bool):
        """"""
        inst = InstrumentField()
        inst.InstrumentID = pInstrument.getInstrumentID()
        inst.ProductID = pInstrument.getProductID()
        inst.ExchangeID = pInstrument.getExchangeID()
        inst.VolumeMultiple = pInstrument.getVolumeMultiple()
        inst.PriceTick = pInstrument.getPriceTick()
        inst.MaxOrderVolume = pInstrument.getMaxLimitOrderVolume()
        self.DicInstrument[inst.InstrumentID] = inst

    def __OnRspQryAccount(self,
                          pTradingAccount=CThostFtdcTradingAccountField,
                          pRspInfo=CThostFtdcRspInfoField,
                          nRequestID=int,
                          bIsLast=bool):
        """"""
        if not self.Account:
            self.Account = TradingAccount()
        self.Account.Available = pTradingAccount.getAvailable()
        self.Account.CloseProfit = pTradingAccount.getCloseProfit()
        self.Account.Commission = pTradingAccount.getCommission()
        self.Account.CurrMargin = pTradingAccount.getCurrMargin()
        self.Account.FrozenCash = pTradingAccount.getFrozenCash()
        self.Account.PositionProfit = pTradingAccount.getPositionProfit()
        self.Account.PreBalance = pTradingAccount.getPreBalance(
        ) + pTradingAccount.getDeposit() + pTradingAccount.getWithdraw()
        self.Account.Fund = self.Account.PreBalance + pTradingAccount.getCloseProfit(
        ) + pTradingAccount.getPositionProfit(
        ) - pTradingAccount.getCommission()
        self.Account.Risk = self.Account.CurrMargin / self.Account.Fund
        if not self.IsLogin:
            self.IsLogin = True
            info = InfoField()
            info.ErrorID = 0
            info.ErrorMsg = '正确'
            self.OnRspUserLogin(info)

    def __OnRspQryPosition(self,
                           pInvestorPosition=CThostFtdcInvestorPositionField,
                           pRspInfo=CThostFtdcRspInfoField,
                           nRequestID=int,
                           bIsLast=bool):
        """"""
        if pInvestorPosition.getInstrumentID() != '':  # 偶尔出现NULL的数据导致数据转换错误
            self.__posi.append(
                pInvestorPosition)  # Struct(**f.__dict__)) #dict -> object

        if bIsLast:
            # 先排序再group才有效
            self.__posi = sorted(
                self.__posi,
                key=lambda c: '{0}_{1}'.format(
                    c.getInstrumentID(), DirectType.Buy if c.getPosiDirection(
                    ) == PosiDirectionType.Long else DirectType.Sell))
            # direction需从posidiction转换为dictiontype
            for key, group in itertools.groupby(
                    self.__posi, lambda c: '{0}_{1}'.format(
                        c.getInstrumentID(), DirectType.Buy
                        if c.getPosiDirection() == PosiDirectionType.Long else
                        DirectType.Sell)):
                pf = self.DicPositionField.get(key)
                if not pf:
                    pf = PositionField()
                    self.DicPositionField[key] = pf
                pf.Position = 0
                pf.TdPosition = 0
                pf.YdPosition = 0
                pf.CloseProfit = 0
                pf.PositionProfit = 0
                pf.Commission = 0
                pf.Margin = 0
                pf.Price = 0
                cost = 0.0
                for g in group:
                    if not pf.InstrumentID:
                        pf.InstrumentID = g.getInstrumentID()
                        pf.Direction = DirectType.Buy if g.getPosiDirection(
                        ) == PosiDirectionType.Long else DirectType.Sell
                    pf.Position += g.getPosition()
                    pf.TdPosition += g.getTodayPosition()
                    pf.YdPosition = pf.Position - pf.TdPosition
                    pf.CloseProfit += g.getCloseProfit()
                    pf.PositionProfit += g.getPositionProfit()
                    pf.Commission += g.getCommission()
                    pf.Margin += g.getUseMargin()
                    cost += g.OpenCost
                # pf.Position <= 0 ? 0 : (g.Sum(n => n.PositionCost) / DicInstrumentField[pf.InstrumentID].VolumeMultiple / pf.Position);
                vm = self.DicInstrument[pf.InstrumentID].VolumeMultiple
                pf.Price = 0 if pf.Position <= 0 else cost / vm / pf.Position
            self.__posi.clear()

    def __OnRtnOrder(self, pOrder=CThostFtdcOrderField):
        """"""
        id = '{0}|{1}|{2}'.format(pOrder.getSessionID(), pOrder.getFrontID(),
                                  pOrder.getOrderRef())
        # of = OrderField()
        of = self.DicOrderField.get(id)
        if not of:
            of = OrderField()
            l = int(pOrder.getOrderRef())
            of.Custom = l % 1000000
            of.InstrumentID = pOrder.getInstrumentID()
            of.InsertTime = pOrder.getInsertTime()
            of.Direction = DirectType.Buy if DirectionType(pOrder.getDirection(
            )) == DirectionType.Buy else DirectType.Sell
            ot = OffsetFlagType(ord(pOrder.getCombOffsetFlag()[0]))
            of.Offset = OffsetType.Open if ot == OffsetFlagType.Open else (
                OffsetType.CloseToday
                if ot == OffsetFlagType.CloseToday else OffsetType.Close)
            of.Status = OrderStatus.Normal
            of.StatusMsg = pOrder.getStatusMsg()
            of.IsLocal = pOrder.getSessionID() == self.SessionID
            of.LimitPrice = pOrder.getLimitPrice()
            of.OrderID = id
            of.Volume = pOrder.getVolumeTotalOriginal()
            of.VolumeLeft = of.Volume
            self.DicOrderField[id] = of
            self.OnRtnOrder(of)
            # _thread.start_new_thread(self.OnRtnOrder, (of,))  # call client OnRtnOrder event
        elif pOrder.getOrderStatus() == OrderStatusType.Canceled:
            of.Status = OrderStatus.Canceled
            of.StatusMsg = pOrder.getStatusMsg()

            if of.StatusMsg.find('被拒绝') >= 0:
                info = InfoField()
                info.ErrorID = -1
                info.ErrorMsg = of.StatusMsg
                self.OnRtnErrOrder(of, info)
            else:
                self.OnRtnCancel(of)
        else:
            if pOrder.getOrderSysID():
                of.SysID = pOrder.getOrderSysID()
                self.__dic_orderid_sysid[pOrder.getOrderSysID(
                )] = id  # 记录sysid与orderid关联,方便Trade时查找处理
            # _thread.start_new_thread(self.OnRtnOrder, (of,))

    def __OnRtnTrade(self, f):
        """"""
        tf = TradeField()
        tf.Direction = DirectType.Buy if f.getDirection(
        ) == DirectionType.Buy else DirectType.Sell
        tf.ExchangeID = f.getExchangeID()
        tf.InstrumentID = f.getInstrumentID()
        tf.Offset = OffsetType.Open if f.getOffsetFlag(
        ) == OffsetFlagType.Open else OffsetType.Close if f.getOffsetFlag(
        ) == OffsetFlagType.Close else OffsetType.CloseToday
        tf.Price = f.getPrice()
        tf.SysID = f.getOrderSysID()
        tf.TradeID = f.getTradeID()
        tf.TradeTime = f.getTradeTime()
        tf.TradingDay = f.getTradingDay()
        tf.Volume = f.getVolume()

        self.DicTradeField[tf.TradeID] = tf

        id = self.__dic_orderid_sysid[tf.SysID]
        of = self.DicOrderField[id]
        tf.OrderID = id  # tradeid 与 orderid 关联
        of.TradeTime = tf.TradeTime
        # of.AvgPrice = (of.AvgPrice * (of.Volume - of.VolumeLeft) + pTrade.Price * pTrade.Volume) / (of.Volume - of.VolumeLeft + pTrade.Volume);
        of.AvgPrice = (of.AvgPrice *
                       (of.Volume - of.VolumeLeft) + tf.Price * tf.Volume) / (
                           of.Volume - of.VolumeLeft + tf.Volume)
        of.TradeVolume = tf.Volume
        of.VolumeLeft -= tf.Volume
        if of.VolumeLeft == 0:
            of.Status = OrderStatus.Filled
            of.StatusMsg = '全部成交'
        else:
            of.Status = OrderStatus.Partial
            of.StatusMsg = '部分成交'
        # 更新持仓 *****
        if tf.Offset == OffsetType.Open:
            key = '{0}_{1}'.format(tf.InstrumentID, tf.Direction)
            pf = self.DicPositionField.get(key)
            if not pf:
                pf = PositionField()
                self.DicPositionField[key] = pf
            pf.InstrumentID = tf.InstrumentID
            pf.Direction = tf.Direction
            pf.Price = (pf.Price * pf.Position +
                        tf.Price * tf.Volume) / (pf.Position + tf.Volume)
            pf.TdPosition += tf.Volume
            pf.Position += tf.Volume
        else:
            key = '{0}_{1}'.format(
                tf.InstrumentID, DirectType.Sell
                if tf.Direction == DirectType.Buy else DirectType.Buy)
            pf = self.DicPositionField.get(key)
            if pf:  # 有可能出现无持仓的情况
                if tf.Offset == OffsetType.CloseToday:
                    pf.TdPosition -= tf.Volume
                else:
                    tdclose = min(pf.TdPosition, tf.Volume)
                    if pf.TdPosition > 0:
                        pf.TdPosition -= tdclose
                    pf.YdPosition -= max(0, tf.Volume - tdclose)
                pf.Position -= tf.Volume
        _thread.start_new_thread(self.__onRtn, (of, tf))
        # _thread.start_new_thread(self.OnRtnOrder, (of,))
        # _thread.start_new_thread(self.OnRtnTrade, (tf,))

    def __onRtn(self, of, tf):
        self.OnRtnOrder(of)
        self.OnRtnTrade(tf)

    def __OnRspOrder(self,
                     pInputOrder=CThostFtdcInputOrderField,
                     pRspInfo=CThostFtdcRspInfoField,
                     nRequestID=int,
                     bIsLast=bool):
        """"""
        info = InfoField()
        info.ErrorID = pRspInfo.getErrorID()
        info.ErrorMsg = pRspInfo.getErrorMsg()

        id = '{0}|{1}|{2}'.format(self.SessionID, '0',
                                  pInputOrder.getOrderRef())
        of = self.DicOrderField.get(id)
        if not of:
            of = OrderField()
            l = int(pInputOrder.getOrderRef())
            of.Custom = l % 1000000
            of.InstrumentID = pInputOrder.getInstrumentID()
            of.InsertTime = time.strftime('%Y%M%d %H:%M:%S', time.localtime())
            # 对direction需特别处理(具体见ctp_struct)
            of.Direction = DirectType.Buy if DirectionType(
                pInputOrder.getDirection(
                )) == DirectionType.Buy else DirectType.Sell
            ot = OffsetFlagType(ord(pInputOrder.getCombOffsetFlag()[0]))
            of.Offset = OffsetType.Open if ot == OffsetFlagType.Open else (
                OffsetType.CloseToday
                if ot == OffsetFlagType.CloseToday else OffsetType.Close)
            # of.Status = OrderStatus.Normal
            # of.StatusMsg = f.getStatusMsg()
            of.IsLocal = True
            of.LimitPrice = pInputOrder.getLimitPrice()
            of.OrderID = id
            of.Volume = pInputOrder.getVolumeTotalOriginal()
            of.VolumeLeft = of.Volume
            self.DicOrderField[id] = of

        of.Status = OrderStatus.Error
        of.StatusMsg = '{0}:{1}'.format(info.ErrorID, info.ErrorMsg)
        _thread.start_new_thread(self.OnRtnErrOrder, (of, info))

    def __OnErrOrder(self,
                     pInputOrder=CThostFtdcInputOrderField,
                     pRspInfo=CThostFtdcRspInfoField):
        """"""
        id = '{0}|{1}|{2}'.format(self.SessionID, '0',
                                  pInputOrder.getOrderRef())
        of = self.DicOrderField.get(id)

        info = InfoField()
        info.ErrorID = pRspInfo.getErrorID()
        info.ErrorMsg = pRspInfo.getErrorMsg()

        if of and of.IsLocal:
            of.Status = OrderStatus.Error
            of.StatusMsg = '{0}:{1}'.format(pRspInfo.getErrorID(),
                                            pRspInfo.getErrorMsg())
            _thread.start_new_thread(self.OnRtnErrOrder, (of, info))

    def __OnRspOrderAction(self,
                           pInputOrderAction=CThostFtdcInputOrderActionField,
                           pRspInfo=CThostFtdcRspInfoField,
                           nRequestID=int,
                           bIsLast=bool):
        id = "{0}|{1}|{2}".format(pInputOrderAction.getSessionID(),
                                  pInputOrderAction.getFrontID(),
                                  pInputOrderAction.getOrderRef())
        if self.IsLogin and id in self.DicOrderField:
            info = InfoField()
            info.ErrorID = pRspInfo.ErrorID
            info.ErrorMsg = pRspInfo.ErrorMsg
            self.OnErrCancel(self.DicOrderField[id], info)

    def __OnRtnInstrumentStatus(
            self, pInstrumentStatus=CThostFtdcInstrumentStatusField):
        self.DicInstrumentStatus[pInstrumentStatus.getInstrumentID(
        )] = pInstrumentStatus.getInstrumentStatus()
        _thread.start_new_thread(self.OnRtnInstrumentStatus,
                                 (pInstrumentStatus.getInstrumentID(),
                                  pInstrumentStatus.getInstrumentStatus()))

    def __OnRspSettlementInfoConfirm(
            self,
            pSettlementInfoConfirm=CThostFtdcSettlementInfoConfirmField,
            pRspInfo=CThostFtdcRspInfoField,
            nRequestID=int,
            bIsLast=bool):
        pass

    def ReqConnect(self, pAddress=''):
        self.t.CreateApi()
        spi = self.t.CreateSpi()
        self.t.SubscribePrivateTopic(0)  # restart 同步处理order trade
        self.t.SubscribePublicTopic(0)
        self.t.RegisterSpi(spi)

        self.t.OnFrontConnected = self.__OnFrontConnected
        self.t.OnRspUserLogin = self.__OnRspUserLogin
        self.t.OnFrontDisconnected = self.__OnFrontDisconnected
        self.t.OnRspSettlementInfoConfirm = self.__OnRspSettlementInfoConfirm
        self.t.OnRtnOrder = self.__OnRtnOrder
        self.t.OnRtnTrade = self.__OnRtnTrade
        self.t.OnRspOrderInsert = self.__OnRspOrder
        self.t.OnErrRtnOrderInsert = self.__OnErrOrder
        self.t.OnRspOrderAction = self.__OnRspOrderAction

        self.t.OnRtnInstrumentStatus = self.__OnRtnInstrumentStatus

        self.t.OnRspQryInstrument = self.__OnRspQryInstrument
        self.t.OnRspQryTradingAccount = self.__OnRspQryAccount
        self.t.OnRspQryInvestorPosition = self.__OnRspQryPosition

        self.t.RegCB()

        self.t.RegisterFront(pAddress)
        self.t.Init()
        # self.t.Join()

    def ReqUserLogin(self, user, pwd, broker):
        self.t.ReqUserLogin(BrokerID=broker, UserID=user, Password=pwd)

    def ReqOrderInsert(self,
                       pInstrument='',
                       pDirection=DirectType,
                       pOffset=OffsetType,
                       pPrice=0.0,
                       pVolume=1,
                       pType=OrderType.Limit,
                       pCustom=0):
        """"""
        OrderPriceType = OrderPriceTypeType.AnyPrice
        TimeCondition = TimeConditionType.IOC
        LimitPrice = 0.0
        VolumeCondition = VolumeConditionType.AV

        for case in switch(pType):
            if case(OrderType.Market):  # 市价
                OrderPriceType = OrderPriceTypeType.AnyPrice
                TimeCondition = TimeConditionType.IOC
                LimitPrice = 0.0
                VolumeCondition = VolumeConditionType.AV
                break
            if case(OrderType.Limit):  # 限价
                OrderPriceType = OrderPriceTypeType.LimitPrice
                TimeCondition = TimeConditionType.GFD
                LimitPrice = pPrice
                VolumeCondition = VolumeConditionType.AV
                break
            if case(OrderType.FAK):  # FAK
                OrderPriceType = OrderPriceTypeType.LimitPrice
                TimeCondition = TimeConditionType.IOC
                LimitPrice = pPrice
                VolumeCondition = VolumeConditionType.AV
                break
            if case(OrderType.FOK):  # FOK
                OrderPriceType = OrderPriceTypeType.LimitPrice
                TimeCondition = TimeConditionType.IOC
                LimitPrice = pPrice
                VolumeCondition = VolumeConditionType.CV  # 全部数量
                break

        self._req += 1
        self.t.ReqOrderInsert(
            BrokerID=self.BrokerID,
            InvestorID=self.Investor,
            InstrumentID=pInstrument,
            OrderRef="%06d%06d" % (self._req, pCustom % 1000000),
            UserID=self.Investor,
            # 此处ctp_enum与at_struct名称冲突
            Direction=DirectionType.Buy
            if pDirection == DirectType.Buy else DirectionType.Sell,
            CombOffsetFlag=chr(
                OffsetFlagType.Open if pOffset == OffsetType.Open else (
                    OffsetFlagType.CloseToday if pOffset ==
                    OffsetType.CloseToday else OffsetFlagType.Close)),
            CombHedgeFlag=HedgeFlagType.Speculation.__char__(),
            IsAutoSuspend=0,
            ForceCloseReason=ForceCloseReasonType.NotForceClose,
            IsSwapOrder=0,
            ContingentCondition=ContingentConditionType.Immediately,
            VolumeCondition=VolumeCondition,
            MinVolume=1,
            VolumeTotalOriginal=pVolume,
            OrderPriceType=OrderPriceType,
            TimeCondition=TimeCondition,
            LimitPrice=LimitPrice,
        )

    def ReqOrderAction(self, OrderID=''):
        """"""
        of = self.DicOrderField[OrderID]

        if not of:
            return -1
        else:
            pOrderId = of.OrderID
            return self.t.ReqOrderAction(self.BrokerID,
                                         self.Investor,
                                         OrderRef=pOrderId.split('|')[2],
                                         FrontID=int(pOrderId.split('|')[1]),
                                         SessionID=int(pOrderId.split('|')[0]),
                                         InstrumentID=of.InstrumentID,
                                         ActionFlag=ActionFlagType.Delete)

    def Release(self):
        self.t.RegisterSpi(None)
        self.t.Release()

    def OnFrontConnected(self):
        """接口连接"""
        pass

    def OnFrontDisConnected(self, error=0):
        """接口断开"""
        pass

    def OnRspUserLogin(self, info=InfoField):
        """登录响应"""
        pass

    def OnRtnOrder(self, f=OrderField):
        """委托返回"""
        pass

    def OnRtnTrade(self, f=TradeField):
        """成交返回"""
        pass

    def OnRtnCancel(self, f=OrderField):
        """撤单响应"""
        pass

    def OnErrCancel(self, f=OrderField, info=InfoField):
        """撤单失败"""
        pass

    def OnRtnErrOrder(self, f=OrderField, info=InfoField):
        """委托错误响应"""
        print(f)
        print(info)

    def OnRtnInstrumentStatus(self, inst, status):
        pass
Пример #3
0
class Test:
    def __init__(self):
        """初始化 运行的目录下需要创建log目录"""
        """交易前置"""
        self.front_trade = ''
        # 行情前置
        self.front_quote = ''
        self.investor = ''
        self.pwd = ''
        self.broker = ''
        self.TradingDay = ''
        # self.log = open('orders.csv', 'w')
        # self.log.write('')  # 清空内容

        self.stra_instances = []

        self.Session = ''
        self.q = Quote()
        self.t = Trade()
        self.req = 0
        self.ordered = False
        self.needAuth = False

    def q_OnFrontConnected(self):
        print('connected')
        self.q.ReqUserLogin(BrokerID=self.broker,
                            UserID=self.investor,
                            Password=self.pwd)

    def q_OnRspUserLogin(self, rsp, info, req, last):
        print(info)
        self.q.SubscribeMarketData('rb1805')

    def q_OnRspSubMarketData(
            self,
            pSpecificInstrument=CThostFtdcSpecificInstrumentField,
            pRspInfo=CThostFtdcRspInfoField,
            nRequestID=int,
            bIsLast=bool):
        pass

    def q_OnTick(self, tick):
        f = CThostFtdcMarketDataField()
        f = tick

        if not self.ordered:
            print(tick)
            _thread.start_new_thread(self.Order, (f, ))
            self.ordered = True

    def Order(self, f):
        print("报单")
        self.req += 1
        self.t.ReqOrderInsert(
            BrokerID=self.broker,
            InvestorID=self.investor,
            InstrumentID=f.getInstrumentID(),
            OrderRef='{0:>12}'.format(self.req),
            UserID=self.investor,
            OrderPriceType=OrderPriceTypeType.LimitPrice,
            Direction=DirectionType.Buy,
            CombOffsetFlag=OffsetFlagType.Open.__char__(),
            CombHedgeFlag=HedgeFlagType.Speculation.__char__(),
            LimitPrice=f.getLastPrice() - 50,
            VolumeTotalOriginal=1,
            TimeCondition=TimeConditionType.GFD,
            # GTDDate=''
            VolumeCondition=VolumeConditionType.AV,
            MinVolume=1,
            ContingentCondition=ContingentConditionType.Immediately,
            StopPrice=0,
            ForceCloseReason=ForceCloseReasonType.NotForceClose,
            IsAutoSuspend=0,
            IsSwapOrder=0,
            UserForceClose=0)

    def OnFrontConnected(self):
        print('connected')
        if self.needAuth:
            self.t.ReqAuthenticate(self.broker, self.investor, '@haifeng',
                                   '8MTL59FK1QGLKQW2')
        else:
            self.t.ReqUserLogin(BrokerID=self.broker,
                                UserID=self.investor,
                                Password=self.pwd,
                                UserProductInfo='@haifeng')

    def OnRspAuthenticate(self,
                          pRspAuthenticateField=CThostFtdcRspAuthenticateField,
                          pRspInfo=CThostFtdcRspInfoField,
                          nRequestID=int,
                          bIsLast=bool):
        print('auth:{0}:{1}'.format(pRspInfo.getErrorID(),
                                    pRspInfo.getErrorMsg()))
        self.t.ReqUserLogin(BrokerID=self.broker,
                            UserID=self.investor,
                            Password=self.pwd,
                            UserProductInfo='@haifeng')

    def OnRspUserLogin(self, rsp, info, req, last):
        print(info)
        i = CThostFtdcRspInfoField()
        i = info

        if i.getErrorID() == 0:
            self.Session = rsp.getSessionID()
            self.t.ReqSettlementInfoConfirm(BrokerID=self.broker,
                                            InvestorID=self.investor)

    def OnRspSettlementInfoConfirm(
            self,
            pSettlementInfoConfirm=CThostFtdcSettlementInfoConfirmField,
            pRspInfo=CThostFtdcRspInfoField,
            nRequestID=int,
            bIsLast=bool):
        _thread.start_new_thread(self.StartQuote, ())
        _thread.start_new_thread(self.Qry, ())

    def StartQuote(self):
        print('start quote')
        self.q.CreateApi()
        spi = self.q.CreateSpi()
        self.q.RegisterSpi(spi)

        self.q.OnFrontConnected = self.q_OnFrontConnected
        self.q.OnRspUserLogin = self.q_OnRspUserLogin
        self.q.OnRtnDepthMarketData = self.q_OnTick
        self.q.OnRspSubMarketData = self.q_OnRspSubMarketData
        self.q.RegCB()

        self.q.RegisterFront(self.front_quote)
        self.q.Init()
        # self.q.Join()

    def Qry(self):
        sleep(1.1)
        self.t.ReqQryInstrument()
        while True:
            sleep(1.1)
            self.t.ReqQryTradingAccount(self.broker, self.investor)
            sleep(1.1)
            self.t.ReqQryInvestorPosition(self.broker, self.investor)
            return

    def OnRtnInstrumentStatus(self,
                              pInstrumentStatus=CThostFtdcInstrumentStatusField
                              ):
        pass

    def OnRspOrderInsert(self,
                         pInputOrder=CThostFtdcInputOrderField,
                         pRspInfo=CThostFtdcRspInfoField,
                         nRequestID=int,
                         bIsLast=bool):
        print(pRspInfo)
        print(pInputOrder)
        print(pRspInfo.getErrorMsg())

    def OnRtnOrder(self, pOrder=CThostFtdcOrderField):
        # print(pOrder)
        if pOrder.getSessionID() == self.Session and pOrder.getOrderStatus(
        ) == OrderStatusType.NoTradeQueueing:
            print("撤单")
            self.t.ReqOrderAction(self.broker,
                                  self.investor,
                                  InstrumentID=pOrder.getInstrumentID(),
                                  OrderRef=pOrder.getOrderRef(),
                                  FrontID=pOrder.getFrontID(),
                                  SessionID=pOrder.getSessionID(),
                                  ActionFlag=ActionFlagType.Delete)

    def OnRspInstrument(self, instrument, rspinfo, nreq, last):
        pass

    def OnRspPosition(self,
                      pInvestorPosition=CThostFtdcInvestorPositionField,
                      pRspInfo=CThostFtdcRspInfoField,
                      nRequestID=int,
                      bIsLast=bool):
        pass

    def OnRspAccount(self,
                     pTradingAccount=CThostFtdcTradingAccountField,
                     pRspInfo=CThostFtdcRspInfoField,
                     nRequestID=int,
                     bIsLast=bool):
        pass

    def CTPRun(self,
               front_trade='tcp://180.168.146.187:10000',
               front_quote='tcp://180.168.146.187:10010',
               broker='9999',
               investor='008109',
               pwd='1'):
        """"""

        self.front_trade = front_trade
        self.front_quote = front_quote
        self.broker = broker
        self.investor = investor
        self.pwd = pwd

        self.t.CreateApi()
        spi = self.t.CreateSpi()
        self.t.SubscribePrivateTopic(2)
        self.t.SubscribePublicTopic(2)
        self.t.RegisterSpi(spi)

        self.t.OnFrontConnected = self.OnFrontConnected
        self.t.OnRspUserLogin = self.OnRspUserLogin
        self.t.OnRspSettlementInfoConfirm = self.OnRspSettlementInfoConfirm
        self.t.OnRspQryInstrument = self.OnRspInstrument
        self.t.OnRtnInstrumentStatus = self.OnRtnInstrumentStatus
        self.t.OnRtnOrder = self.OnRtnOrder
        self.t.OnRspQryInvestorPosition = self.OnRspPosition
        self.t.OnRspQryTradingAccount = self.OnRspAccount
        # self.t.OnRtnTrade = self.OnRtnTrade
        # self.t.OnRtnCancel = self.OnRtnCancel
        # self.t.OnRtnErrOrder = self.OnRtnErrOrder

        self.t.RegCB()
        self.t.RegisterFront(self.front_trade)
        self.t.Init()
Пример #4
0
class TdApi:
    """
    Demo中的交易API封装
    主动函数包括:
    login 登陆
    getInstrument 查询合约信息
    getAccount 查询账号资金
    getInvestor 查询投资者
    getPosition 查询持仓
    sendOrder 发单
    cancelOrder 撤单
    """

    #----------------------------------------------------------------------
    def __init__(self, eventEngine):
        """API对象的初始化函数"""
        # 事件引擎,所有数据都推送到其中,再由事件引擎进行分发
        self.__eventEngine = eventEngine
        self.t = Trade()

        # 请求编号,由api负责管理
        self.__reqid = 0

        # 报单编号,由api负责管理
        self.__orderref = random.randrange(start=1000,
                                           stop=9000,
                                           step=random.randint(10, 100))
        self.SessionID = None
        self.FrontID = None

        # 以下变量用于实现连接和重连后的自动登陆
        self.__userid = cf.userid
        self.__password = cf.password
        self.__brokerid = cf.brokerid

        api = self.t.CreateApi()
        spi = self.t.CreateSpi()
        self.t.RegisterSpi(spi)
        self.t.OnFrontConnected = self.onFrontConnected  # 交易服务器登陆相应
        self.t.OnRspUserLogin = self.onRspUserLogin  # 用户登陆
        self.t.OnErrRtnOrderInsert = self.onErrRtnOrderInsert
        self.t.OnRspUserLogout = self.OnRspUserLogout
        self.t.OnRtnInstrumentStatus = self.OnRtnInstrumentStatus
        self.t.OnFrontDisconnected = self.onFrontDisconnected
        self.t.OnRspSettlementInfoConfirm = self.onRspSettlementInfoConfirm  # 结算单确认
        self.t.OnRspQryInstrument = self.onRspQryInstrument  # 查询全部交易合约
        self.t.OnRspQryDepthMarketData = self.onRspQryDepthMarketData  # tick截面数据
        self.t.OnRspQryInvestorPosition = self.onRspQryInvestorPosition  #查询持仓
        self.t.OnRspQryTradingAccount = self.onRspQryTradingAccount  #查询账户
        self.t.OnRtnOrder = self.onRtnOrder  #报单
        self.t.OnRtnTrade = self.onRtnTrade  #成交
        self.t.OnRspQryInstrumentMarginRate = self.OnRspQryInstrumentMarginRate  #获取保证金率
        #——————错误事件
        self.t.OnRspOrderInsert = self.onRspOrderInsert
        self.t.OnRspOrderAction = self.onRspOrderAction
        self.t.OnRspError = self.onRspError

        self.t.RegCB()
        self.login_status = False  #登录状态

    def login(self):
        if self.login_status == False:
            self.t.RegisterFront('tcp://180.168.146.187:10000')
            self.t.Init()

    def logout(self):
        if self.login_status == True:
            self.t.ReqUserLogout(self.__brokerid, self.__userid)

    def release(self):
        self.t.Release()
        self.t = None

    def put_log_event(self, log):  # log事件注册
        event = Event(type_=EVENT_LOG)
        event.dict_['log'] = log
        self.__eventEngine.put(event)

    def onFrontConnected(self):
        """服务器连接"""
        lc.loger.info(threading.current_thread())
        self.put_log_event('交易服务器连接成功')
        time.sleep(3)
        self.t.ReqUserLogin(BrokerID=self.__brokerid,
                            UserID=self.__userid,
                            Password=self.__password)

    def OnRtnInstrumentStatus(self, data):
        pass

    def onFrontDisconnected(self, n):
        """服务器断开"""
        lc.loger.info(threading.current_thread())
        self.put_log_event('交易服务器连接断开')
        self.login_status = False
        time.sleep(3)

    def onRspUserLogin(self, data, error, n, last):
        """登陆回报"""
        if error.__dict__['ErrorID'] == 0:
            self.Investor = data.__dict__['UserID']
            self.BrokerID = data.__dict__['BrokerID']
            self.FrontID = data.__dict__['FrontID']
            self.SessionID = data.__dict__['SessionID']
            self.__orderref = int(data.__dict__['MaxOrderRef'])
            lc.loger.info(data.__dict__)
            self.login_status = True
            log = data.__dict__['UserID'] + '交易服务器登陆成功'
            self.t.ReqSettlementInfoConfirm(self.BrokerID,
                                            self.Investor)  # 对账单确认
        else:
            self.login_status = False
            log = '登陆回报,错误代码:' + str(
                error.__dict__['ErrorID']) + ',   错误信息:' + str(
                    error.__dict__['ErrorMsg'])
        self.put_log_event(log)

    def OnRspUserLogout(self, data, error, n, last):
        """登出回报"""
        lc.loger.info(threading.current_thread())
        if error.__dict__['ErrorID'] == 0:
            self.login_status = False
            log = '交易服务器登出成功'
        else:
            self.login_status = True
            log = '登出回报,错误代码:' + str(
                error.__dict__['ErrorID']) + ',   错误信息:' + str(
                    error.__dict__['ErrorMsg'])
        self.put_log_event(log)

    def onRspSettlementInfoConfirm(self, data, error, n, last):
        """确认结算信息回报"""
        log = '结算信息确认完成'
        self.put_log_event(log)
        time.sleep(1)
        self.getInstrument()  # 查询合约资料
        #self.short('rb1801',4422,1)
        #self.sell('rb1801',4431,1)
        #self.getPosition()

    def onRspQryInstrument(self, data, error, n, last):
        """
        合约查询回报
        由于该回报的推送速度极快,因此不适合全部存入队列中处理,
        选择先储存在一个本地字典中,全部收集完毕后再推送到队列中
        (由于耗时过长目前使用其他进程读取)
        """
        if error.__dict__['ErrorID'] == 0:
            event = Event(type_=EVENT_INSTRUMENT)
            event.dict_['data'] = data.__dict__
            event.dict_['last'] = last
            self.__eventEngine.put(event)
            if last == True:
                time.sleep(2)
                self.t.ReqQryDepthMarketData()  # 查询合约截面数据
        else:
            log = '合约投资者回报,错误代码:' + str(
                error.__dict__['ErrorID']) + ',   错误信息:' + str(
                    error.__dict__['ErrorMsg'])
            self.put_log_event(log)

    def onRspQryDepthMarketData(self, data, error, n, last):
        # 常规行情事件
        event = Event(type_=EVENT_MARKETDATA)
        event.dict_['data'] = data.__dict__
        event.dict_['last'] = last
        self.__eventEngine.put(event)

    def getInstrumentMarginRate(self, instrumentID):
        self.t.ReqQryInstrumentMarginRate(
            BrokerID=self.__brokerid,
            InvestorID=self.__userid,
            InstrumentID=instrumentID)  # 查询合约保证金率

    def OnRspQryInstrumentMarginRate(self, data, error, n, last):
        # 合约保证金
        event = Event(type_=EVENT_INSTRUMENT_MAGIN_RATE)
        event.dict_['data'] = data.__dict__
        event.dict_['last'] = last
        self.__eventEngine.put(event)

    def onRspQryInvestorPosition(self, data, error, n, last):
        """持仓查询回报"""
        if error.__dict__['ErrorID'] == 0:
            event = Event(type_=EVENT_POSITION)
            event.dict_['data'] = data.__dict__
            event.dict_['last'] = last
            self.__eventEngine.put(event)
        else:
            log = ('持仓查询回报,错误代码:' + str(error.__dict__['ErrorID']) +
                   ',   错误信息:' + str(error.__dict__['ErrorMsg']))
            self.put_log_event(log)

    # ----------------------------------------------------------------------
    def onRspQryTradingAccount(self, data, error, n, last):
        """资金账户查询回报"""
        if error.__dict__['ErrorID'] == 0:
            event = Event(type_=EVENT_ACCOUNT)
            event.dict_['data'] = data.__dict__
            self.__eventEngine.put(event)
        else:
            log = ('账户查询回报,错误代码:' + str(error.__dict__['ErrorID']) +
                   ',   错误信息:' + str(error.__dict__['ErrorMsg']))
            self.put_log_event(log)

    def onRtnTrade(self, data):
        """成交回报"""
        # 常规成交事件
        event1 = Event(type_=EVENT_TRADE)
        event1.dict_['data'] = data.__dict__
        self.__eventEngine.put(event1)

    def onRtnOrder(self, data):
        """报单回报"""
        # 更新最大报单编号
        newref = data.__dict__['OrderRef']
        self.__orderref = max(self.__orderref, int(newref))
        # 常规报单事件
        event1 = Event(type_=EVENT_ORDER)
        event1.dict_['data'] = data.__dict__
        self.__eventEngine.put(event1)

    def onRspOrderInsert(self, data, error, n, last):
        """发单错误(柜台)"""
        log = data.__dict__['InstrumentID'] + ' 发单错误回报,错误代码:' + str(
            error.__dict__['ErrorID']) + ',   错误信息:' + str(
                error.__dict__['ErrorMsg'])
        # self.put_log_event(log)
        lc.loger_order.info('onRspOrderInsert')
        lc.loger_error.info(log)
        lc.loger_order.info(data.__dict__)

    def onErrRtnOrderInsert(self, data, error):
        """发单错误回报(交易所)"""
        log = data.__dict__['InstrumentID'] + '发单错误回报,错误代码:' + str(
            error.__dict__['ErrorID']) + ',   错误信息:' + str(
                error.__dict__['ErrorMsg'])
        # self.put_log_event(log)
        lc.loger_error.info('onErrRtnOrderInsert')
        lc.loger_error.info(log)
        lc.loger_error.info(data.__dict__)

    def onRspError(self, error, n, last):
        """错误回报"""
        log = '交易错误回报,错误代码:' + str(
            error.__dict__['ErrorID']) + ',   错误信息:' + str(
                error.__dict__['ErrorMsg'])
        # self.put_log_event(log)
        lc.loger_error.info('onRspError')
        lc.loger_error.info(log)
        lc.loger_error.info(error.__dict__)

    # ----------------------------------------------------------------------
    def onRspOrderAction(self, data, error, n, last):
        """撤单错误(柜台)"""
        log = '撤单错误回报,错误代码:' + str(
            error.__dict__['ErrorID']) + ',   错误信息:' + str(
                error.__dict__['ErrorMsg'])
        # self.put_log_event(log)
        lc.loger_error.info('onRspOrderAction')
        lc.loger_error.info(log)
        lc.loger_error.info(data.__dict__)

    # ----------------------------------------------------------------------
    def onErrRtnOrderAction(self, data, error):
        """撤单错误回报(交易所)"""
        event = Event(type_=EVENT_LOG)
        log = data['合约代码'] + '  撤单错误回报,错误代码:' + str(
            error.__dict__['ErrorID']) + ',   错误信息:' + str(
                error.__dict__['ErrorMsg'])
        event.dict_['log'] = log
        # self.__eventEngine.put(event)
        lc.loger_error.info('onErrRtnOrderAction')
        lc.loger_error.info(log)
        lc.loger_error.info(data.__dict__)

    def getInstrument(self):
        """查询合约"""
        self.__reqid = self.__reqid + 1
        self.t.ReqQryInstrument()

    def getAccount(self):
        """查询账户"""
        self.__reqid = self.__reqid + 1
        self.t.ReqQryTradingAccount(self.__brokerid, self.__userid)

    # ----------------------------------------------------------------------
    def getPosition(self):
        """查询持仓"""
        self.__reqid = self.__reqid + 1
        self.t.ReqQryInvestorPosition(self.__brokerid, self.__userid)

    def sendorder(self, instrumentid, price, vol, direction, offset):
        """发单"""
        self.__reqid = self.__reqid + 1
        self.__orderref = self.__orderref + 1
        # 限价
        self.t.ReqOrderInsert(
            BrokerID=self.__brokerid,
            InvestorID=self.__userid,
            InstrumentID=instrumentid,
            OrderRef='{0:>12}'.format(self.__orderref),
            UserID=self.__userid,
            OrderPriceType=OrderPriceTypeType.LimitPrice,
            Direction=direction,
            CombOffsetFlag=offset,
            CombHedgeFlag=HedgeFlagType.Speculation.__char__(),
            LimitPrice=price,
            VolumeTotalOriginal=vol,
            TimeCondition=TimeConditionType.GFD,
            VolumeCondition=VolumeConditionType.AV,
            MinVolume=1,
            ForceCloseReason=ForceCloseReasonType.NotForceClose,
            ContingentCondition=ContingentConditionType.Immediately)
        return self.__orderref
        # 返回订单号,便于某些算法进行动态管理
        # OrderPriceType--LimitPrice 限价单
        # CombHedgeFlag--投机套保标记,默认投机单Speculation
        # TimeConditionType是一个有效期类型类型#当日有效--GFD
        # VolumeConditionType是一个成交量类型类型#任何数量--VolumeConditionType.AV
        # ContingentConditionType是一个触发条件类型,#立即ContingentConditionType.Immediately

    def buy(self, symbol, price, vol):  # 买开多开
        direction = DirectionType.Buy
        offset = OffsetFlagType.Open.__char__()
        self.sendorder(symbol, price, vol, direction, offset)

    def sell(self, symbol, price, vol):  # 多平
        direction = DirectionType.Sell
        offset = OffsetFlagType.Close.__char__()
        self.sendorder(symbol, price, vol, direction, offset)

    def selltoday(self, symbol, price, vol):  # 平今多
        direction = DirectionType.Sell
        offset = OffsetFlagType.CloseToday.__char__()
        self.sendorder(symbol, price, vol, direction, offset)

    def short(self, symbol, price, vol):  # 卖开空开
        direction = DirectionType.Sell
        offset = OffsetFlagType.Open.__char__()
        self.sendorder(symbol, price, vol, direction, offset)

    def cover(self, symbol, price, vol):  # 空平
        direction = DirectionType.Buy
        offset = OffsetFlagType.Close.__char__()
        self.sendorder(symbol, price, vol, direction, offset)

    def covertoday(self, symbol, price, vol):  # 平今空
        direction = DirectionType.Buy
        offset = OffsetFlagType.CloseToday.__char__()
        self.sendorder(symbol, price, vol, direction, offset)

    # ----------------------------------------------------------------------
    # tmp["合约代码"] = var["InstrumentID"]
    # tmp["交易所代码"] = var["ExchangeID"]
    # tmp["报单引用"] = var["OrderRef"]
    # tmp["买卖方向"] = var["Direction"]
    # tmp["组合开平标志"] = var["CombOffsetFlag"]
    # tmp["价格"] = var["LimitPrice"]
    # tmp["数量"] = var["VolumeTotalOriginal"]
    # tmp["请求编号"] = var["RequestID"]
    # tmp["本地报单编号"] = var["OrderLocalID"]
    # tmp["报单编号"] = var["OrderSysID"]
    # tmp["今成交数量"] = var["VolumeTraded"]
    # tmp["剩余数量"] = var["VolumeTotal"]
    # tmp["报单日期"] = var["InsertDate"]
    # tmp["委托时间"] = var["InsertTime"]
    # tmp["前置编号"] = var["FrontID"]
    # tmp["会话编号"] = var["SessionID"]
    # tmp["状态信息"] = var["StatusMsg"]
    # tmp["序号"] = var["SequenceNo"]
    def cancelOrder(self, order):
        """撤单"""
        # lc.loger.info(order)
        self.__reqid = self.__reqid + 1
        self.t.ReqOrderAction(BrokerID=self.__brokerid,
                              InvestorID=self.__userid,
                              OrderRef=order['OrderLocalID'],
                              FrontID=int(order['FrontID']),
                              SessionID=int(order['SessionID']),
                              OrderSysID=order['OrderSysID'],
                              ActionFlag=ActionFlagType.Delete,
                              ExchangeID=order["ExchangeID"],
                              InstrumentID=order['InstrumentID'])