Example #1
0
class Quoter:
    def __init__(self, address, broker, investor, passwd):
        self.Session = ''
        dllpath = os.path.join(
            os.path.split(os.path.realpath(__file__))[0], '..', 'dll')
        self.q = Quote(
            os.path.join(
                dllpath, 'ctp_quote.' +
                ('dll' if 'Windows' in platform.system() else 'so')))
        self.address = address
        self.broker = broker
        self.investor = investor
        self.pwd = passwd

    def q_OnFrontConnected(self):
        print('connected', "---------enter q_OnFrontConnected-----------")
        # 行情-用户登陆请求
        self.q.ReqUserLogin(BrokerID=self.broker,
                            UserID=self.investor,
                            Password=self.pwd)

    def q_OnRspUserLogin(self, rsp: ctp.CThostFtdcRspUserLoginField,
                         info: ctp.CThostFtdcRspInfoField, req: int,
                         last: bool):
        print(info, "------enter q_OnRspUserLogin--------")
        for temp_future in OrderDict.keys():
            self.q.SubscribeMarketData(temp_future)

    def q_OnTick(self, tick: ctp.CThostFtdcMarketDataField):
        print("----enter q_OnTick---------", tick.getUpdateTime(),
              tick.getInstrumentID(), tick.getLastPrice())
        instrustmentId = tick.getInstrumentID()
        OrderDict[instrustmentId].lastPrice = tick.getLastPrice()
        OrderDict[instrustmentId].attr = tick
        print(OrderDict[instrustmentId].lastPrice)

    def StartQuote(self):
        print("----------enter StartQuote-----------")
        # 初始化行情线程,new api,new spi,spi注册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.address)
        # 连接运行
        self.q.Init()
Example #2
0
class Test:
    def __init__(self):
        self.Session = ''
        dllpath = os.path.join(
            os.path.split(os.path.realpath(__file__))[0], '..', 'dll')
        self.q = Quote(
            os.path.join(
                dllpath, 'ctp_quote.' +
                ('dll' if 'Windows' in platform.system() else 'so')))
        self.t = Trade(
            os.path.join(
                dllpath, 'ctp_trade.' +
                ('dll' if 'Windows' in platform.system() else 'so')))
        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: ctp.CThostFtdcRspUserLoginField,
                         info: ctp.CThostFtdcRspInfoField, req: int,
                         last: bool):
        print(info)
        self.q.SubscribeMarketData('rb1812')

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

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

    def Order(self, f: ctp.CThostFtdcMarketDataField):
        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=ctp.OrderPriceTypeType.LimitPrice,
            Direction=ctp.DirectionType.Buy,
            CombOffsetFlag=ctp.OffsetFlagType.Open.__char__(),
            CombHedgeFlag=ctp.HedgeFlagType.Speculation.__char__(),
            LimitPrice=f.getLastPrice() - 50,
            VolumeTotalOriginal=1,
            TimeCondition=ctp.TimeConditionType.GFD,
            # GTDDate=''
            VolumeCondition=ctp.VolumeConditionType.AV,
            MinVolume=1,
            ContingentCondition=ctp.ContingentConditionType.Immediately,
            StopPrice=0,
            ForceCloseReason=ctp.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 OnFrontDisconnected(self, reason: int):
        print(reason)

    def OnRspAuthenticate(
            self, pRspAuthenticateField: ctp.CThostFtdcRspAuthenticateField,
            pRspInfo: ctp.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: ctp.CThostFtdcRspUserLoginField,
                       info: ctp.CThostFtdcRspInfoField, req: int, last: bool):
        print(info.getErrorMsg())

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

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

    def StartQuote(self):
        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: ctp.CThostFtdcInstrumentStatusField):
        print(pInstrumentStatus.getInstrumentStatus())

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

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

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

        self.t.OnFrontConnected = self.OnFrontConnected
        self.t.OnFrontDisconnected = self.OnFrontDisconnected
        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 = '008107'
        self.pwd = '1'
        self.t.RegisterFront(self.frontAddr.split(',')[0])
        self.t.SubscribePrivateTopic(nResumeType=2)  # quick
        self.t.SubscribePrivateTopic(nResumeType=2)
        self.t.Init()
class MdApi:
    def __init__(self, userid, password, brokerid, RegisterFront):
        # 登陆的账户与密码
        self.userid = userid
        self.password = password
        self.brokerid = brokerid
        self.address = RegisterFront
        # 创建Quote对象
        self.q = Quote()
        api = self.q.CreateApi()
        spi = self.q.CreateSpi()
        self.q.RegisterSpi(spi)
        self.q.OnFrontConnected = self.onFrontConnected  # 交易服务器登陆相应
        self.q.OnFrontDisconnected = self.onFrontDisconnected
        self.q.OnRspUserLogin = self.onRspUserLogin  # 用户登陆
        self.q.OnRspUserLogout = self.onRspUserLogout  # 用户登出
        self.q.OnRspError = self.onRspError
        self.q.OnRspSubMarketData = self.onRspSubMarketData
        self.q.OnRtnDepthMarketData = self.onRtnDepthMarketData
        self.q.RegCB()
        self.q.RegisterFront(self.address)
        self.q.Init()

    def onFrontConnected(self):
        """服务器连接"""
        self.q.ReqUserLogin(BrokerID=self.brokerid,
                            UserID=self.userid,
                            Password=self.password)

    def onFrontDisconnected(self, n):
        """服务器断开"""
        downLogProgram('行情服务器连接断开')

    def onRspUserLogin(self, data, error, n, last):
        """登陆回报"""
        if error.getErrorID() == 0:
            downLogProgram('行情服务器登陆成功,订阅主力合约')
            for instrument in listInstrument:
                goodsCode = getGoodsCode(instrument)
                if goodsCode in setTheGoodsCode:  # 如果在交易的品种上,则可以订阅该合约
                    self.q.SubscribeMarketData(instrument)
        else:
            log = '行情服务器登陆回报,错误代码:' + str(error.getErrorID()) + \
                  ', 错误信息:' + str(error.getErrorMsg())
            downLogProgram(log)

    def onRspUserLogout(self, data, error, n, last):
        if error.getErrorID() == 0:
            log = '行情服务器登出成功'
        else:
            log = '行情服务器登出回报,错误代码:' + str(error.getErrorID()) + \
                  ',   错误信息:' + str(error.getErrorMsg())
        downLogProgram(log)

    def onRspError(self, error, n, last):
        """错误回报"""
        log = '行情错误回报,错误代码:' + str(error.getErrorID()) \
              + '错误信息:' + + str(error.getErrorMsg())
        downLogProgram(log)

    def onRspSubMarketData(self, data, info, n, last):
        pass

    def onRtnDepthMarketData(self, data):
        """行情推送"""
        event = Event(type_=EVENT_TICK)
        event.dict_['InstrumentID'] = data.getInstrumentID()
        event.dict_['LastPrice'] = data.getLastPrice()
        event.dict_['TradingDay'] = data.getTradingDay()
        event.dict_['UpdateTime'] = data.getUpdateTime()
        event.dict_['UpdateMillisec'] = data.getUpdateMillisec()
        event.dict_['AskPrice1'] = data.getAskPrice1()
        event.dict_['BidPrice1'] = data.getBidPrice1()
        ee.put(event)
Example #4
0
class CtpQuote(object):
    """"""
    def __init__(self, dll_relative_path: str = 'dll'):
        self.q = Quote(
            os.path.join(
                os.getcwd(), dll_relative_path, 'ctp_quote.' +
                ('dll' if 'Windows' in platform.system() else 'so')))
        self.inst_tick = {}
        self.logined = False

    def ReqConnect(self, pAddress: str):
        """
        连接行情前置
            :param self: 
            :param pAddress:str: 
        """
        self.q.CreateApi()
        spi = self.q.CreateSpi()
        self.q.RegisterSpi(spi)

        self.q.OnFrontConnected = self._OnFrontConnected
        self.q.OnFrontDisconnected = self._OnFrontDisConnected
        self.q.OnRspUserLogin = self._OnRspUserLogin
        self.q.OnRtnDepthMarketData = self._OnRtnDepthMarketData
        self.q.OnRspSubMarketData = self._OnRspSubMarketData

        self.q.RegCB()

        self.q.RegisterFront(pAddress)
        self.q.Init()

    def ReqUserLogin(self, user: str, pwd: str, broker: str):
        """
        登录
            :param self: 
            :param user:str: 
            :param pwd:str: 
            :param broker:str: 
        """
        self.q.ReqUserLogin(BrokerID=broker, UserID=user, Password=pwd)

    def ReqSubscribeMarketData(self, pInstrument: str):
        """
        订阅合约行情
            :param self:
            :param pInstrument:str:
        """
        self.q.SubscribeMarketData(pInstrument)

    def ReqUserLogout(self):
        """
        退出接口
            :param self: 
        """
        self.q.Release()
        _thread.start_new_thread(self.OnDisConnected, (self, 0))

    def _OnFrontConnected(self):
        """"""
        _thread.start_new_thread(self.OnConnected, (self, ))

    def _OnFrontDisConnected(self, reason: int):
        """"""
        # 确保隔夜或重新登录时的第1个tick不被发送到客户端
        self.inst_tick.clear()
        _thread.start_new_thread(self.OnDisConnected, (self, reason))

    def _OnRspUserLogin(self, pRspUserLogin: CThostFtdcRspUserLoginField,
                        pRspInfo: CThostFtdcRspInfoField, nRequestID: int,
                        bIsLast: bool):
        """"""
        info = InfoField()
        info.ErrorID = pRspInfo.getErrorID()
        info.ErrorMsg = pRspInfo.getErrorMsg()
        self.logined = True
        _thread.start_new_thread(self.OnUserLogin, (self, info))

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

    def _OnRtnDepthMarketData(
            self, pDepthMarketData: CThostFtdcDepthMarketDataField):
        """"""
        tick: Tick = None
        # 这个逻辑交由应用端处理更合理 ==> 第一个tick不送给客户端(以处理隔夜早盘时收到夜盘的数据的问题)
        inst = pDepthMarketData.getInstrumentID()
        if inst not in self.inst_tick:
            tick = Tick()
            self.inst_tick[inst] = tick
        else:
            tick = self.inst_tick[inst]

        tick.AskPrice = pDepthMarketData.getAskPrice1()
        tick.AskVolume = pDepthMarketData.getAskVolume1()
        tick.AveragePrice = pDepthMarketData.getAveragePrice()
        tick.BidPrice = pDepthMarketData.getBidPrice1()
        tick.BidVolume = pDepthMarketData.getBidVolume1()
        tick.Instrument = pDepthMarketData.getInstrumentID()
        tick.LastPrice = pDepthMarketData.getLastPrice()
        tick.OpenInterest = pDepthMarketData.getOpenInterest()
        tick.Volume = pDepthMarketData.getVolume()

        # 用tradingday替代Actionday不可取
        # day = pDepthMarketData.getTradingDay()
        # str = day + ' ' + pDepthMarketData.getUpdateTime()
        # if day is None or day == ' ':
        #     str = time.strftime('%Y%m%d %H:%M:%S', time.localtime())
        # tick.UpdateTime = str  # time.strptime(str, '%Y%m%d %H:%M:%S')

        tick.UpdateTime = pDepthMarketData.getUpdateTime()
        tick.UpdateMillisec = pDepthMarketData.getUpdateMillisec()

        # 用线程会导入多数据入库时报错
        # _thread.start_new_thread(self.OnTick, (self, tick))
        self.OnTick(self, tick)

    def OnDisConnected(self, obj, error: int):
        """"""
        print('disconnected: ' + str(error))

    def OnConnected(self, obj):
        """"""
        print('connected')

    def OnUserLogin(self, obj, info: InfoField):
        """"""
        print(info)

    def OnTick(self, obj, f: Tick):
        """"""
        print(f.__dict__)