コード例 #1
0
ファイル: ctaEngine.py プロジェクト: myjoying/vnpy
    def subscribeMarketData(self, strategy):
        """订阅行情"""

        for gateway in self.mainEngine.gatewayDict.keys():
            req = VtSubscribeReq()
            req.symbol = strategy.vtSymbol
            self.mainEngine.subscribe(req, gateway)
        '''
コード例 #2
0
ファイル: ctaEngine.py プロジェクト: chongwei111/vnpy
 def subscribeMarketData(self, strategy):
     """订阅行情"""
     # 订阅合约
     contract = self.mainEngine.getContract(strategy.vtSymbol)
     if contract:
         req = VtSubscribeReq()
         req.symbol = contract.symbol
         req.exchange = contract.exchange
         
         # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
         req.currency = strategy.currency
         req.productClass = strategy.productClass
         
         self.mainEngine.subscribe(req, contract.gatewayName)
     else:
         self.writeCtaLog(u'%s的交易合约%s无法找到' %(strategy.name, strategy.vtSymbol))
コード例 #3
0
    def subscribeMarketData(self, vtSymbol):
        """订阅行情"""
        # 订阅合约
        contract = self.mainEngine.getContract(vtSymbol)
        if contract:
            req = VtSubscribeReq()
            req.symbol = contract.symbol
            req.exchange = contract.exchange

            # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
            #req.currency = strategy.currency
            #req.productClass = strategy.productClass

            self.mainEngine.subscribe(req, contract.gatewayName)
        else:
            self.writeCtaLog(u'交易合约%s无法找到' % (vtSymbol))
コード例 #4
0
    def subscribe(self, strategy, symbolList):
        name = strategy.name
        for vtSymbol in symbolList:
            # 保存Tick映射关系
            if vtSymbol in self.tickStrategyDict:
                l = self.tickStrategyDict[vtSymbol]
            else:
                l = []
                self.tickStrategyDict[vtSymbol] = l
            l.append(strategy)

            # 订阅合约
            contract = self.mainEngine.getContract(vtSymbol)
            if contract:
                req = VtSubscribeReq()
                req.symbol = contract.symbol
                req.exchange = contract.exchange

                # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
                req.currency = strategy.currency
                req.productClass = strategy.productClass

                self.mainEngine.subscribe(req, contract.gatewayName)
            else:
                self.writeArbLog(u'%s的交易合约%s无法找到' % (name, vtSymbol))

            self.putStrategyEvent(name)
コード例 #5
0
    def initStrategyBySymbol(self, symbol, setting):

        # 创建策略实例
        # 防止策略重名
        if symbol in self.strategyDict:
            self.writeCtaLog(u'策略实例重名:%s' % name)
            return

        setting["vtSymbol"] = symbol
        strategy = ZzsdStrategy(self, setting)

        self.strategyDict[symbol] = strategy
        strategy.setFixSize(self.FIX_SIZE_AUDO)
        strategy.initDayBar(self.loadAllBar(DAY_DB_NAME, symbol))
        strategy.initDayCurrentBar(
            self.getCurrentBar(self.loadCurrentDayMinBar(symbol)))

        if setting["strategyCycle"] == "60min":
            strategy.initHourBar(self.loadAllBar(MINUTE_60_DB_NAME, symbol))
            strategy.initHourCurrentBar(
                self.getCurrentBar(self.loadMinuteBar(symbol, 60)))
        if setting["strategyCycle"] == "30min":
            strategy.initHourBar(self.loadAllBar(MINUTE_30_DB_NAME, symbol))
            strategy.initHourCurrentBar(
                self.getCurrentBar(self.loadMinuteBar(symbol, 30)))
        if setting["strategyCycle"] == "5min":
            strategy.initHourBar(self.loadAllBar(MINUTE_5_DB_NAME, symbol))
            strategy.initHourCurrentBar(
                self.getCurrentBar(self.loadMinuteBar(symbol, 5)))

        # 创建委托号列表
        self.strategyOrderDict[symbol] = set()

        # 保存Tick映射关系
        if strategy.vtSymbol in self.tickStrategyDict:
            l = self.tickStrategyDict[strategy.vtSymbol]
        else:
            l = []
            self.tickStrategyDict[strategy.vtSymbol] = l
        l.append(strategy)

        # 订阅合约
        contract = self.mainEngine.getContract(strategy.vtSymbol)
        if contract:
            req = VtSubscribeReq()
            req.symbol = contract.symbol
            req.exchange = contract.exchange

            # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
            req.currency = strategy.currency
            req.productClass = strategy.productClass

            self.mainEngine.subscribe(req, contract.gatewayName)
        else:
            self.writeCtaLog(u'%s的交易合约%s无法找到' % (name, strategy.vtSymbol))
コード例 #6
0
ファイル: ctaEngine.py プロジェクト: WongLynn/AutoTrader
 def subscribeMarketData(self, strategy):
     """订阅行情"""
     for vtSymbol in strategy.symbolList:
         contract = self.mainEngine.getContract(vtSymbol)
         if contract:
             req = VtSubscribeReq()
             req.symbol = contract.symbol
             req.vtSymbol = contract.vtSymbol
             req.exchange = contract.exchange
             
             # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
             req.currency = strategy.currency
             req.productClass = strategy.productClass
             
             self.mainEngine.subscribe(req, contract.gatewayName)
         else:
             self.writeCtaLog(u'策略%s的交易合约%s无法找到' %(strategy.name, vtSymbol))
コード例 #7
0
 def loadStrategy(self, setting):
     """载入策略"""
     try:
         name = setting['name']
         className = setting['className']
     except Exception:
         msg = traceback.format_exc()
         self.writeCtaLog(u'载入策略出错:%s' %msg)
         return
     
     # 获取策略类
     strategyClass = STRATEGY_CLASS.get(className, None)
     if not strategyClass:
         self.writeCtaLog(u'找不到策略类:%s' %className)
         return
     
     # 防止策略重名
     if name in self.strategyDict:
         self.writeCtaLog(u'策略实例重名:%s' %name)
     else:
         # 创建策略实例
         strategy = strategyClass(self, setting)  
         self.strategyDict[name] = strategy
         
         # 创建委托号列表
         self.strategyOrderDict[name] = set()
         
         # 保存Tick映射关系
         if strategy.vtSymbol in self.tickStrategyDict:
             l = self.tickStrategyDict[strategy.vtSymbol]
         else:
             l = []
             self.tickStrategyDict[strategy.vtSymbol] = l
         l.append(strategy)
         
         # 订阅合约
         contract = self.mainEngine.getContract(strategy.vtSymbol)
         if contract:
             req = VtSubscribeReq()
             req.symbol = contract.symbol
             req.exchange = contract.exchange
             
             # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
             req.currency = strategy.currency
             req.productClass = strategy.productClass
             
             self.mainEngine.subscribe(req, contract.gatewayName)
         else:
             self.writeCtaLog(u'%s的交易合约%s无法找到' %(name, strategy.vtSymbol))
コード例 #8
0
    def subscribeMarketData(self, strategy):
        """订阅行情"""
        # 订阅合约
        contract = self._mainRoutine.getContract(strategy.vtSymbol)
        if contract:
            req = VtSubscribeReq()
            req.symbol = contract.symbol
            req.exchange = contract.exchange

            # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
            req.currency = strategy.currency
            req.productClass = strategy.productClass

            self._mainRoutine.subscribe(req, contract.gatewayName)
        else:
            self.log(u'%s的交易合约%s无法找到' % (strategy.name, strategy.vtSymbol))
コード例 #9
0
    def updateContract(self, name, strategy):
        """更新策略"""
        for vtSymbol in self.tickStrategyDict:
            if strategy in self.tickStrategyDict[vtSymbol]:
                self.tickStrategyDict[vtSymbol].remove(strategy)

        # 保存Tick映射关系
        if strategy.vtSymbol in self.tickStrategyDict:
            l = self.tickStrategyDict[strategy.vtSymbol]
        else:
            l = []
            # 订阅合约
            contract = self.mainEngine.getContract(strategy.vtSymbol)
            if contract:
                req = VtSubscribeReq()
                req.symbol = contract.symbol
                req.exchange = contract.exchange
                self.mainEngine.subscribe(req, contract.gatewayName)
            else:
                self.writeArbLog(u'%s的交易合约%s无法找到' % (name, strategy.vtSymbol))
            self.tickStrategyDict[strategy.vtSymbol] = l
        l.append(strategy)
        if strategy.vtSymbol1 and strategy.vtSymbol1 in self.tickStrategyDict:
            l = self.tickStrategyDict[strategy.vtSymbol1]
        else:
            l = []
            contract = self.mainEngine.getContract(strategy.vtSymbol1)
            if contract:
                req = VtSubscribeReq()
                req.symbol = contract.symbol
                req.exchange = contract.exchange
                self.mainEngine.subscribe(req, contract.gatewayName)
            else:
                self.writeArbLog(u'%s的交易合约%s无法找到' % (name, strategy.vtSymbol))
            self.tickStrategyDict[strategy.vtSymbol1] = l
        l.append(strategy)
コード例 #10
0
ファイル: ctaEngine.py プロジェクト: wycwywfwa/vnpy
    def subscribe(self, strategy, symbol):
        """订阅合约,不成功时,加入到待订阅列表"""
        contract = self.mainEngine.getContract(symbol)

        if contract:
            # 4.构造订阅请求包
            req = VtSubscribeReq()
            req.symbol = contract.symbol
            req.exchange = contract.exchange

            # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
            req.currency = strategy.currency
            req.productClass = strategy.productClass

            # 5.调用主引擎的订阅接口
            self.mainEngine.subscribe(req, contract.gatewayName)
        else:
            print u'Warning, can not find {0} in contracts'.format(symbol)
            self.writeCtaLog(u'交易合约{}无法找到,添加到待订阅列表'.format(symbol))
            self.pendingSubcribeSymbols[symbol] = strategy
コード例 #11
0
    def loadStrategy(self, setting):
        """载入策略"""
        try:
            name = setting['name']
            className = setting['className']
        except Exception as e:
            self.writeCtaLog(u'载入策略出错:%s' %e)
            return

        # 获取策略类
        strategyClass = STRATEGY_CLASS.get(className, None)
        if not strategyClass:
            self.writeCtaLog(u'找不到策略类:%s' %className)
            return

        # 防止策略重名
        if name in self.strategyDict:
            self.writeCtaLog(u'策略实例重名:%s' %name)

        else:
            # 创建策略实例
            strategy = strategyClass(self, setting)
            self.strategyDict[name] = strategy

            # 创建委托号列表
            self.strategyOrderDict[name] = set()

            # 保存Tick映射关系
            if strategy.vtSymbol in self.tickStrategyDict:
                l = self.tickStrategyDict[strategy.vtSymbol]
            else:
                l = []
                self.tickStrategyDict[strategy.vtSymbol] = l
            l.append(strategy)

            # 订阅合约
            # print(strategy.vtSymbol)
            contract = self.mainEngine.getContract(strategy.vtSymbol)
            # print '222222222222222222222222222222   ctaEngine.py_line471    contract:', contract
            if contract:
                # print(3333333333333333333333333333, 'ctaEngine.py_line473')
                req = VtSubscribeReq()
                req.symbol = contract.symbol
                req.exchange = contract.exchange

                # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
                req.currency = strategy.currency
                req.productClass = strategy.productClass
                # print(req.productClass) #这个的编码待修改
                self.mainEngine.subscribe(req, contract.gatewayName)

            else:
                # # 下面是zls自己添加的,是否保存待确定
                # req = VtSubscribeReq()
                # req.symbol = 'USD.CNH'
                # req.exchange = 'IDEALPRO'
                # # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
                # req.currency = ''
                # req.productClass = ''
                # self.mainEngine.subscribe(req, 'IB')

                self.writeCtaLog(u'%s的交易合约%s无法找到' %(name, strategy.vtSymbol))
コード例 #12
0
    def initStrategyBySymbol(self, symbol, setting):

        # 创建策略实例
        # 防止策略重名
        if (symbol + setting['className']) in self.strategyDict:
            self.writeCtaLog(u'策略实例重名:%s' % name)
            return

        setting["vtSymbol"] = symbol

        className = setting['className']

        # 获取策略类
        strategyClass = STRATEGY_CLASS.get(className, None)
        if not strategyClass:
            self.writeCtaLog(u'找不到策略类:%s' % className)
            return

        strategy = strategyClass(self, setting)

        self.strategyDict[symbol + className] = strategy
        strategy.setFixSize(self.FIX_SIZE_AUDO)

        # 创建委托号列表
        self.strategyOrderDict[symbol + strategy.className] = set()

        # 保存Tick映射关系
        if strategy.vtSymbol in self.tickStrategyDict:
            l = self.tickStrategyDict[strategy.vtSymbol]
        else:
            l = []
            self.tickStrategyDict[strategy.vtSymbol] = l
        l.append(strategy)

        ##读数据库
        traderOrd = TraderOrder()
        traderOrd.symbol = symbol
        traderOrd.strategyName = strategy.className
        traderOrd.offset = OFFSET_OPEN

        t = self.mainEngine.mysqlClient.dbSelect(SQL_TABLENAME_TRADER,
                                                 traderOrd, "one")
        if t:
            traderOrd.orderID = t["orderID"]
            traderOrd.orderUuid = t["orderUuid"]
            traderOrd.direction = t["direction"]
            traderOrd.orderVolume = t["orderVolume"]
            traderOrd.orderPrice = t["orderPrice"]
            traderOrd.tradeVolume = t["tradeVolume"]
            traderOrd.tradePrice = t["tradePrice"]

            if traderOrd.offset == OFFSET_OPEN:
                self.lastOpenTrade[traderOrd.symbol] = traderOrd

            self.traderDict[traderOrd.orderID] = traderOrd

        # 订阅合约
        contract = self.mainEngine.getContract(strategy.vtSymbol)
        if contract:

            strategy.setPriceTick(contract.size, contract.priceTick)

            req = VtSubscribeReq()
            req.symbol = contract.symbol
            req.exchange = contract.exchange

            # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
            req.currency = strategy.currency
            req.productClass = strategy.productClass

            self.mainEngine.subscribe(req, contract.gatewayName)

            self.writeCtaLog("subscribe===%s" % (strategy.vtSymbol))

        else:
            self.writeCtaLog(u'%s的交易合约%s无法找到' % (name, strategy.vtSymbol))
コード例 #13
0
    def loadSetting(self):
        """载入设置"""
        with open(self.settingFileName) as f:
            drSetting = json.load(f)

            # 如果working设为False则不启动行情记录功能
            working = drSetting['working']
            if not working:
                return

            if 'tick' in drSetting:
                l = drSetting['tick']

                for setting in l:
                    symbol = setting[0]
                    vtSymbol = symbol

                    req = VtSubscribeReq()
                    req.symbol = setting[0]

                    # 针对LTS和IB接口,订阅行情需要交易所代码
                    if len(setting) >= 3:
                        req.exchange = setting[2]
                        vtSymbol = '.'.join([symbol, req.exchange])

                    # 针对IB接口,订阅行情需要货币和产品类型
                    if len(setting) >= 5:
                        req.currency = setting[3]
                        req.productClass = setting[4]

                    self.mainEngine.subscribe(req, setting[1])

                    drTick = DrTickData()  # 该tick实例可以用于缓存部分数据(目前未使用)
                    self.tickDict[vtSymbol] = drTick

            if 'bar' in drSetting:
                l = drSetting['bar']

                for setting in l:
                    symbol = setting[0]
                    vtSymbol = symbol

                    req = VtSubscribeReq()
                    req.symbol = symbol

                    if len(setting) >= 3:
                        req.exchange = setting[2]
                        vtSymbol = '.'.join([symbol, req.exchange])

                    if len(setting) >= 5:
                        req.currency = setting[3]
                        req.productClass = setting[4]

                    self.mainEngine.subscribe(req, setting[1])

                    bar = DrBarData()
                    self.barDict[vtSymbol] = bar

            if 'active' in drSetting:
                d = drSetting['active']

                # 注意这里的vtSymbol对于IB和LTS接口,应该后缀.交易所
                for activeSymbol, vtSymbol in d.items():
                    self.activeSymbolDict[vtSymbol] = activeSymbol

            # 启动数据插入线程
            self.start()

            # 注册事件监听
            self.registerEvent()
コード例 #14
0
ファイル: mmkEngine.py プロジェクト: huning2009/deanTrading
    def loadStrategy(self, setting):
        """载入策略"""
        try:
            name = setting['name']
            className = setting['className']
        except Exception:
            msg = traceback.format_exc()
            self.writeMmkLog(u'载入策略出错:%s' % msg)
            return

        # 获取策略类
        strategyClass = STRATEGY_CLASS.get(className, None)
        if not strategyClass:
            self.writeMmkLog(u'找不到策略类:%s' % className)
            return

        # 防止策略重名
        if name in self.strategyDict:
            self.writeMmkLog(u'策略实例重名:%s' % name)
        else:
            # 创建策略实例
            strategy = strategyClass(self, setting)
            self.strategyDict[name] = strategy
            # 创建委托号列表
            self.strategyOrderDict[name] = set()

            # 保存Tick映射关系
            # if strategy.vtSymbol in self.tickStrategyDict:
            #     l = self.tickStrategyDict[strategy.vtSymbol]
            # else:
            #     l = []
            #     self.tickStrategyDict[strategy.vtSymbol] = l
            # l.append(strategy)
            for vtsym in strategy.vtSymbol:
                # 初始化posStrategyNameDict
                for sym in [vtsym.split('.')[0][:3], vtsym.split('.')[0][3:]]:
                    if sym not in self.posStrategyNameDict:
                        self.posStrategyNameDict[sym] = [strategy.name]
                    elif sym in self.posStrategyNameDict:
                        if self.posStrategyNameDict[sym][0] != strategy.name:
                            self.posStrategyNameDict[sym].append(strategy.name)

                if vtsym in self.tickStrategyDict:
                    l = self.tickStrategyDict[vtsym]
                else:
                    l = []
                    self.tickStrategyDict[vtsym] = l
                l.append(strategy)

                # 订阅合约
                contract = self.mainEngine.getContract(vtsym)
                if contract:
                    req = VtSubscribeReq()
                    req.symbol = contract.symbol
                    req.exchange = contract.exchange

                    # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
                    req.currency = strategy.currency
                    req.productClass = strategy.productClass

                    self.mainEngine.subscribe(req, contract.gatewayName)
                else:
                    self.writeMmkLog(u'%s的交易合约%s无法找到' % (name, vtsym))
コード例 #15
0
ファイル: drEngine.py プロジェクト: uniwin/vnpydjv
    def loadSetting(self):
        """载入设置"""
        with open(self.settingFilePath) as f:
            drSetting = json.load(f)
            
            # 如果working设为False则不启动行情记录功能
            working = drSetting['working']
            if not working:
                return
            
            if 'tick' in drSetting:
                l = drSetting['tick']
                
                for setting in l:
                    symbol = setting[0]
                    vtSymbol = symbol

                    req = VtSubscribeReq()
                    req.symbol = setting[0]
                    
                    # 针对LTS和IB接口,订阅行情需要交易所代码
                    if len(setting)>=3:
                        req.exchange = setting[2]
                        vtSymbol = '.'.join([symbol, req.exchange])
                    
                    # 针对IB接口,订阅行情需要货币和产品类型
                    if len(setting)>=5:
                        req.currency = setting[3]
                        req.productClass = setting[4]
                    
                    self.mainEngine.subscribe(req, setting[1])
                    
                    drTick = DrTickData()           # 该tick实例可以用于缓存部分数据(目前未使用)
                    self.tickDict[vtSymbol] = drTick
                    
            if 'bar' in drSetting:
                l = drSetting['bar']
                
                for setting in l:
                    symbol = setting[0]
                    vtSymbol = symbol
                    
                    req = VtSubscribeReq()
                    req.symbol = symbol                    

                    if len(setting)>=3:
                        req.exchange = setting[2]
                        vtSymbol = '.'.join([symbol, req.exchange])

                    if len(setting)>=5:
                        req.currency = setting[3]
                        req.productClass = setting[4]                    
                    
                    self.mainEngine.subscribe(req, setting[1])  
                    
                    bar = DrBarData() 
                    self.barDict[vtSymbol] = bar
                    
            if 'active' in drSetting:
                d = drSetting['active']
                
                # 注意这里的vtSymbol对于IB和LTS接口,应该后缀.交易所
                for activeSymbol, vtSymbol in d.items():
                    self.activeSymbolDict[vtSymbol] = activeSymbol

            # 启动数据插入线程
            self.start()

            # 注册事件监听
            self.registerEvent()
コード例 #16
0
class CtaEngine(object):
    """CTA策略引擎"""
    settingFileName = 'CTA_setting.json'
    settingfilePath = getJsonPath(settingFileName, __file__)

    STATUS_FINISHED = set(
        [STATUS_REJECTED, STATUS_CANCELLED, STATUS_ALLTRADED])

    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine):
        """Constructor"""
        self.mainEngine = mainEngine
        self.eventEngine = eventEngine

        # 当前日期
        self.today = todayDate()

        # 保存策略实例的字典
        # key为策略名称,value为策略实例,注意策略名称不允许重复
        self.strategyDict = {}

        # 保存vtSymbol和策略实例映射的字典(用于推送tick数据)
        # 由于可能多个strategy交易同一个vtSymbol,因此key为vtSymbol
        # value为包含所有相关strategy对象的list
        self.tickStrategyDict = {}

        # 保存vtOrderID和strategy对象映射的字典(用于推送order和trade数据)
        # key为vtOrderID,value为strategy对象
        self.orderStrategyDict = {}

        # 本地停止单编号计数
        self.stopOrderCount = 0
        # stopOrderID = STOPORDERPREFIX + str(stopOrderCount)

        # 本地停止单字典
        # key为stopOrderID,value为stopOrder对象
        self.stopOrderDict = {}  # 停止单撤销后不会从本字典中删除
        self.workingStopOrderDict = {}  # 停止单撤销后会从本字典中删除

        # 保存策略名称和委托号列表的字典
        # key为name,value为保存orderID(限价+本地停止)的集合
        self.strategyOrderDict = {}

        # 成交号集合,用来过滤已经收到过的成交推送
        self.tradeSet = set()

        # 引擎类型为实盘
        self.engineType = ENGINETYPE_TRADING

        # 注册日式事件类型
        self.mainEngine.registerLogEvent(EVENT_CTA_LOG)

        # 注册事件监听
        self.registerEvent()

    #----------------------------------------------------------------------
    def sendOrder(self, vtSymbol, orderType, price, volume, strategy):
        """发单"""
        contract = self.mainEngine.getContract(vtSymbol)

        req = VtOrderReq()
        req.symbol = contract.symbol
        req.exchange = contract.exchange
        req.vtSymbol = contract.vtSymbol
        req.price = self.roundToPriceTick(contract.priceTick, price)
        req.volume = volume

        req.productClass = strategy.productClass
        req.currency = strategy.currency

        # 设计为CTA引擎发出的委托只允许使用限价单
        req.priceType = PRICETYPE_LIMITPRICE

        # CTA委托类型映射
        if orderType == CTAORDER_BUY:
            req.direction = DIRECTION_LONG
            req.offset = OFFSET_OPEN

        elif orderType == CTAORDER_SELL:
            req.direction = DIRECTION_SHORT
            req.offset = OFFSET_CLOSE

        elif orderType == CTAORDER_SHORT:
            req.direction = DIRECTION_SHORT
            req.offset = OFFSET_OPEN

        elif orderType == CTAORDER_COVER:
            req.direction = DIRECTION_LONG
            req.offset = OFFSET_CLOSE

        # 委托转换
        reqList = self.mainEngine.convertOrderReq(req)
        vtOrderIDList = []

        if not reqList:
            return vtOrderIDList

        for convertedReq in reqList:
            vtOrderID = self.mainEngine.sendOrder(convertedReq,
                                                  contract.gatewayName)  # 发单
            self.orderStrategyDict[vtOrderID] = strategy  # 保存vtOrderID和策略的映射关系
            self.strategyOrderDict[strategy.name].add(vtOrderID)  # 添加到策略委托号集合中
            vtOrderIDList.append(vtOrderID)

        self.writeCtaLog(
            u'策略%s发送委托,%s,%s,%s@%s' %
            (strategy.name, vtSymbol, req.direction, volume, price))

        return vtOrderIDList

    #----------------------------------------------------------------------
    def cancelOrder(self, vtOrderID):
        """撤单"""
        # 查询报单对象
        order = self.mainEngine.getOrder(vtOrderID)

        # 如果查询成功
        if order:
            # 检查是否报单还有效,只有有效时才发出撤单指令
            orderFinished = (order.status == STATUS_ALLTRADED
                             or order.status == STATUS_CANCELLED)
            if not orderFinished:
                req = VtCancelOrderReq()
                req.symbol = order.symbol
                req.exchange = order.exchange
                req.frontID = order.frontID
                req.sessionID = order.sessionID
                req.orderID = order.orderID
                self.mainEngine.cancelOrder(req, order.gatewayName)

    #----------------------------------------------------------------------
    def sendStopOrder(self, vtSymbol, orderType, price, volume, strategy):
        """发停止单(本地实现)"""
        self.stopOrderCount += 1
        stopOrderID = STOPORDERPREFIX + str(self.stopOrderCount)

        so = StopOrder()
        so.vtSymbol = vtSymbol
        so.orderType = orderType
        so.price = price
        so.volume = volume
        so.strategy = strategy
        so.stopOrderID = stopOrderID
        so.status = STOPORDER_WAITING

        if orderType == CTAORDER_BUY:
            so.direction = DIRECTION_LONG
            so.offset = OFFSET_OPEN
        elif orderType == CTAORDER_SELL:
            so.direction = DIRECTION_SHORT
            so.offset = OFFSET_CLOSE
        elif orderType == CTAORDER_SHORT:
            so.direction = DIRECTION_SHORT
            so.offset = OFFSET_OPEN
        elif orderType == CTAORDER_COVER:
            so.direction = DIRECTION_LONG
            so.offset = OFFSET_CLOSE

        # 保存stopOrder对象到字典中
        self.stopOrderDict[stopOrderID] = so
        self.workingStopOrderDict[stopOrderID] = so

        # 保存stopOrderID到策略委托号集合中
        self.strategyOrderDict[strategy.name].add(stopOrderID)

        # 推送停止单状态
        strategy.onStopOrder(so)

        return [stopOrderID]

    #----------------------------------------------------------------------
    def cancelStopOrder(self, stopOrderID):
        """撤销停止单"""
        # 检查停止单是否存在
        if stopOrderID in self.workingStopOrderDict:
            so = self.workingStopOrderDict[stopOrderID]
            strategy = so.strategy

            # 更改停止单状态为已撤销
            so.status = STOPORDER_CANCELLED

            # 从活动停止单字典中移除
            del self.workingStopOrderDict[stopOrderID]

            # 从策略委托号集合中移除
            s = self.strategyOrderDict[strategy.name]
            if stopOrderID in s:
                s.remove(stopOrderID)

            # 通知策略
            strategy.onStopOrder(so)

    #----------------------------------------------------------------------
    def processStopOrder(self, tick):
        """收到行情后处理本地停止单(检查是否要立即发出)"""
        vtSymbol = tick.vtSymbol

        # 首先检查是否有策略交易该合约
        if vtSymbol in self.tickStrategyDict:
            # 遍历等待中的停止单,检查是否会被触发
            for so in self.workingStopOrderDict.values():
                if so.vtSymbol == vtSymbol:
                    longTriggered = so.direction == DIRECTION_LONG and tick.lastPrice >= so.price  # 多头停止单被触发
                    shortTriggered = so.direction == DIRECTION_SHORT and tick.lastPrice <= so.price  # 空头停止单被触发

                    if longTriggered or shortTriggered:
                        # 买入和卖出分别以涨停跌停价发单(模拟市价单)
                        if so.direction == DIRECTION_LONG:
                            price = tick.upperLimit
                        else:
                            price = tick.lowerLimit

                        # 发出市价委托
                        self.sendOrder(so.vtSymbol, so.orderType, price,
                                       so.volume, so.strategy)

                        # 从活动停止单字典中移除该停止单
                        del self.workingStopOrderDict[so.stopOrderID]

                        # 从策略委托号集合中移除
                        s = self.strategyOrderDict[so.strategy.name]
                        if so.stopOrderID in s:
                            s.remove(so.stopOrderID)

                        # 更新停止单状态,并通知策略
                        so.status = STOPORDER_TRIGGERED
                        so.strategy.onStopOrder(so)

    #----------------------------------------------------------------------
    def processTickEvent(self, event):
        """处理行情推送"""
        tick = event.dict_['data']
        # 收到tick行情后,先处理本地停止单(检查是否要立即发出)
        self.processStopOrder(tick)

        # 推送tick到对应的策略实例进行处理
        if tick.vtSymbol in self.tickStrategyDict:
            # tick时间可能出现异常数据,使用try...except实现捕捉和过滤
            try:
                # 添加datetime字段
                if not tick.datetime:
                    tick.datetime = datetime.strptime(
                        ' '.join([tick.date, tick.time]), '%Y%m%d %H:%M:%S.%f')
            except ValueError:
                self.writeCtaLog(traceback.format_exc())
                return

            # 逐个推送到策略实例中
            l = self.tickStrategyDict[tick.vtSymbol]
            for strategy in l:
                self.callStrategyFunc(strategy, strategy.onTick, tick)

    #----------------------------------------------------------------------
    def processOrderEvent(self, event):
        """处理委托推送"""
        order = event.dict_['data']

        vtOrderID = order.vtOrderID

        if vtOrderID in self.orderStrategyDict:
            strategy = self.orderStrategyDict[vtOrderID]

            # 如果委托已经完成(拒单、撤销、全成),则从活动委托集合中移除
            if order.status in self.STATUS_FINISHED:
                s = self.strategyOrderDict[strategy.name]
                if vtOrderID in s:
                    s.remove(vtOrderID)

            self.callStrategyFunc(strategy, strategy.onOrder, order)

    #----------------------------------------------------------------------
    def processTradeEvent(self, event):
        """处理成交推送"""
        trade = event.dict_['data']

        # 过滤已经收到过的成交回报
        if trade.vtTradeID in self.tradeSet:
            return
        self.tradeSet.add(trade.vtTradeID)

        # 将成交推送到策略对象中
        if trade.vtOrderID in self.orderStrategyDict:
            strategy = self.orderStrategyDict[trade.vtOrderID]

            # 计算策略持仓
            if trade.direction == DIRECTION_LONG:
                strategy.pos += trade.volume
            else:
                strategy.pos -= trade.volume

            self.callStrategyFunc(strategy, strategy.onTrade, trade)

            # 保存策略持仓到数据库
            self.savePosition(strategy)

    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.eventEngine.register(EVENT_TICK, self.processTickEvent)
        self.eventEngine.register(EVENT_ORDER, self.processOrderEvent)
        self.eventEngine.register(EVENT_TRADE, self.processTradeEvent)

    #----------------------------------------------------------------------
    def insertData(self, dbName, collectionName, data):
        """插入数据到数据库(这里的data可以是VtTickData或者VtBarData)"""
        self.mainEngine.dbInsert(dbName, collectionName, data.__dict__)

    #----------------------------------------------------------------------
    def loadBar(self, dbName, collectionName, days):
        """从数据库中读取Bar数据,startDate是datetime对象"""
        startDate = self.today - timedelta(days)

        d = {'datetime': {'$gte': startDate}}
        barData = self.mainEngine.dbQuery(dbName, collectionName, d,
                                          'datetime')

        l = []
        for d in barData:
            bar = VtBarData()
            bar.__dict__ = d
            l.append(bar)
        return l

    #----------------------------------------------------------------------
    def loadTick(self, dbName, collectionName, days):
        """从数据库中读取Tick数据,startDate是datetime对象"""
        startDate = self.today - timedelta(days)

        d = {'datetime': {'$gte': startDate}}
        tickData = self.mainEngine.dbQuery(dbName, collectionName, d,
                                           'datetime')

        l = []
        for d in tickData:
            tick = VtTickData()
            tick.__dict__ = d
            l.append(tick)
        return l

    #----------------------------------------------------------------------
    def writeCtaLog(self, content):
        """快速发出CTA模块日志事件"""
        log = VtLogData()
        log.logContent = content
        log.gatewayName = 'CTA_STRATEGY'
        event = Event(type_=EVENT_CTA_LOG)
        event.dict_['data'] = log
        self.eventEngine.put(event)

    #----------------------------------------------------------------------
    def loadStrategy(self, setting):
        """载入策略"""
        try:
            name = setting['name']
            className = setting['className']
        except Exception, e:
            self.writeCtaLog(u'载入策略出错:%s' % e)
            return

        # 获取策略类
        strategyClass = STRATEGY_CLASS.get(className, None)
        if not strategyClass:
            self.writeCtaLog(u'找不到策略类:%s' % className)
            return

        # 防止策略重名
        if name in self.strategyDict:
            self.writeCtaLog(u'策略实例重名:%s' % name)
        else:
            # 创建策略实例
            strategy = strategyClass(self, setting)
            self.strategyDict[name] = strategy

            # 创建委托号列表
            self.strategyOrderDict[name] = set()

            # 保存Tick映射关系
            if strategy.vtSymbol in self.tickStrategyDict:
                l = self.tickStrategyDict[strategy.vtSymbol]
            else:
                l = []
                self.tickStrategyDict[strategy.vtSymbol] = l
            l.append(strategy)

            # 订阅合约
            contract = self.mainEngine.getContract(strategy.vtSymbol)
            if contract:
                req = VtSubscribeReq()
                req.symbol = contract.symbol
                req.exchange = contract.exchange

                # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
                req.currency = strategy.currency
                req.productClass = strategy.productClass

                self.mainEngine.subscribe(req, contract.gatewayName)
            else:
                self.writeCtaLog(u'%s的交易合约%s无法找到' % (name, strategy.vtSymbol))
コード例 #17
0
ファイル: ctaEngine.py プロジェクト: zmyer/vnpy
class CtaEngine(object):
    """CTA策略引擎"""
    settingFileName = 'CTA_setting.json'
    path = os.path.abspath(os.path.dirname(__file__))
    settingFileName = os.path.join(path, settingFileName)      

    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine):
        """Constructor"""
        self.mainEngine = mainEngine
        self.eventEngine = eventEngine
        
        # 当前日期
        self.today = todayDate()
        
        # 保存策略实例的字典
        # key为策略名称,value为策略实例,注意策略名称不允许重复
        self.strategyDict = {}
        
        # 保存vtSymbol和策略实例映射的字典(用于推送tick数据)
        # 由于可能多个strategy交易同一个vtSymbol,因此key为vtSymbol
        # value为包含所有相关strategy对象的list
        self.tickStrategyDict = {}
        
        # 保存vtOrderID和strategy对象映射的字典(用于推送order和trade数据)
        # key为vtOrderID,value为strategy对象
        self.orderStrategyDict = {}     
        
        # 本地停止单编号计数
        self.stopOrderCount = 0
        # stopOrderID = STOPORDERPREFIX + str(stopOrderCount)
        
        # 本地停止单字典
        # key为stopOrderID,value为stopOrder对象
        self.stopOrderDict = {}             # 停止单撤销后不会从本字典中删除
        self.workingStopOrderDict = {}      # 停止单撤销后会从本字典中删除
        
        # 持仓缓存字典
        # key为vtSymbol,value为PositionBuffer对象
        self.posBufferDict = {}
        
        # 成交号集合,用来过滤已经收到过的成交推送
        self.tradeSet = set()
        
        # 引擎类型为实盘
        self.engineType = ENGINETYPE_TRADING
        
        # 注册事件监听
        self.registerEvent()
 
    #----------------------------------------------------------------------
    def sendOrder(self, vtSymbol, orderType, price, volume, strategy):
        """发单"""
        contract = self.mainEngine.getContract(vtSymbol)
        
        req = VtOrderReq()
        req.symbol = contract.symbol
        req.exchange = contract.exchange
        req.price = self.roundToPriceTick(contract.priceTick, price)
        req.volume = volume
        
        req.productClass = strategy.productClass
        req.currency = strategy.currency        
        
        # 设计为CTA引擎发出的委托只允许使用限价单
        req.priceType = PRICETYPE_LIMITPRICE    
        
        # CTA委托类型映射
        if orderType == CTAORDER_BUY:
            req.direction = DIRECTION_LONG
            req.offset = OFFSET_OPEN
            
        elif orderType == CTAORDER_SELL:
            req.direction = DIRECTION_SHORT
            
            # 只有上期所才要考虑平今平昨
            if contract.exchange != EXCHANGE_SHFE:
                req.offset = OFFSET_CLOSE
            else:
                # 获取持仓缓存数据
                posBuffer = self.posBufferDict.get(vtSymbol, None)
                # 如果获取持仓缓存失败,则默认平昨
                if not posBuffer:
                    req.offset = OFFSET_CLOSE
                # 否则如果有多头今仓,则使用平今
                elif posBuffer.longToday:
                    req.offset= OFFSET_CLOSETODAY
                # 其他情况使用平昨
                else:
                    req.offset = OFFSET_CLOSE
                
        elif orderType == CTAORDER_SHORT:
            req.direction = DIRECTION_SHORT
            req.offset = OFFSET_OPEN
            
        elif orderType == CTAORDER_COVER:
            req.direction = DIRECTION_LONG
            
            # 只有上期所才要考虑平今平昨
            if contract.exchange != EXCHANGE_SHFE:
                req.offset = OFFSET_CLOSE
            else:
                # 获取持仓缓存数据
                posBuffer = self.posBufferDict.get(vtSymbol, None)
                # 如果获取持仓缓存失败,则默认平昨
                if not posBuffer:
                    req.offset = OFFSET_CLOSE
                # 否则如果有空头今仓,则使用平今
                elif posBuffer.shortToday:
                    req.offset= OFFSET_CLOSETODAY
                # 其他情况使用平昨
                else:
                    req.offset = OFFSET_CLOSE
        
        vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName)    # 发单
        self.orderStrategyDict[vtOrderID] = strategy        # 保存vtOrderID和策略的映射关系

        self.writeCtaLog(u'策略%s发送委托,%s,%s,%s@%s' 
                         %(strategy.name, vtSymbol, req.direction, volume, price))
        
        return vtOrderID
    
    #----------------------------------------------------------------------
    def cancelOrder(self, vtOrderID):
        """撤单"""
        # 查询报单对象
        order = self.mainEngine.getOrder(vtOrderID)
        
        # 如果查询成功
        if order:
            # 检查是否报单还有效,只有有效时才发出撤单指令
            orderFinished = (order.status==STATUS_ALLTRADED or order.status==STATUS_CANCELLED)
            if not orderFinished:
                req = VtCancelOrderReq()
                req.symbol = order.symbol
                req.exchange = order.exchange
                req.frontID = order.frontID
                req.sessionID = order.sessionID
                req.orderID = order.orderID
                self.mainEngine.cancelOrder(req, order.gatewayName)    

    #----------------------------------------------------------------------
    def sendStopOrder(self, vtSymbol, orderType, price, volume, strategy):
        """发停止单(本地实现)"""
        self.stopOrderCount += 1
        stopOrderID = STOPORDERPREFIX + str(self.stopOrderCount)
        
        so = StopOrder()
        so.vtSymbol = vtSymbol
        so.orderType = orderType
        so.price = price
        so.volume = volume
        so.strategy = strategy
        so.stopOrderID = stopOrderID
        so.status = STOPORDER_WAITING
        
        if orderType == CTAORDER_BUY:
            so.direction = DIRECTION_LONG
            so.offset = OFFSET_OPEN
        elif orderType == CTAORDER_SELL:
            so.direction = DIRECTION_SHORT
            so.offset = OFFSET_CLOSE
        elif orderType == CTAORDER_SHORT:
            so.direction = DIRECTION_SHORT
            so.offset = OFFSET_OPEN
        elif orderType == CTAORDER_COVER:
            so.direction = DIRECTION_LONG
            so.offset = OFFSET_CLOSE           
        
        # 保存stopOrder对象到字典中
        self.stopOrderDict[stopOrderID] = so
        self.workingStopOrderDict[stopOrderID] = so
        
        return stopOrderID
    
    #----------------------------------------------------------------------
    def cancelStopOrder(self, stopOrderID):
        """撤销停止单"""
        # 检查停止单是否存在
        if stopOrderID in self.workingStopOrderDict:
            so = self.workingStopOrderDict[stopOrderID]
            so.status = STOPORDER_CANCELLED
            del self.workingStopOrderDict[stopOrderID]

    #----------------------------------------------------------------------
    def processStopOrder(self, tick):
        """收到行情后处理本地停止单(检查是否要立即发出)"""
        vtSymbol = tick.vtSymbol
        
        # 首先检查是否有策略交易该合约
        if vtSymbol in self.tickStrategyDict:
            # 遍历等待中的停止单,检查是否会被触发
            for so in self.workingStopOrderDict.values():
                if so.vtSymbol == vtSymbol:
                    longTriggered = so.direction==DIRECTION_LONG and tick.lastPrice>=so.price        # 多头停止单被触发
                    shortTriggered = so.direction==DIRECTION_SHORT and tick.lastPrice<=so.price     # 空头停止单被触发
                    
                    if longTriggered or shortTriggered:
                        # 买入和卖出分别以涨停跌停价发单(模拟市价单)
                        if so.direction==DIRECTION_LONG:
                            price = tick.upperLimit
                        else:
                            price = tick.lowerLimit
                        
                        so.status = STOPORDER_TRIGGERED
                        self.sendOrder(so.vtSymbol, so.orderType, price, so.volume, so.strategy)
                        del self.workingStopOrderDict[so.stopOrderID]

    #----------------------------------------------------------------------
    def processTickEvent(self, event):
        """处理行情推送"""
        tick = event.dict_['data']
        # 收到tick行情后,先处理本地停止单(检查是否要立即发出)
        self.processStopOrder(tick)
        
        # 推送tick到对应的策略实例进行处理
        if tick.vtSymbol in self.tickStrategyDict:
            # 添加datetime字段
            if not tick.datetime:
                tick.datetime = datetime.strptime(' '.join([tick.date, tick.time]), '%Y%m%d %H:%M:%S.%f')
            
            # 逐个推送到策略实例中
            l = self.tickStrategyDict[tick.vtSymbol]
            for strategy in l:
                self.callStrategyFunc(strategy, strategy.onTick, tick)
    
    #----------------------------------------------------------------------
    def processOrderEvent(self, event):
        """处理委托推送"""
        order = event.dict_['data']
        
        if order.vtOrderID in self.orderStrategyDict:
            strategy = self.orderStrategyDict[order.vtOrderID]            
            self.callStrategyFunc(strategy, strategy.onOrder, order)
    
    #----------------------------------------------------------------------
    def processTradeEvent(self, event):
        """处理成交推送"""
        trade = event.dict_['data']
        
        # 过滤已经收到过的成交回报
        if trade.vtTradeID in self.tradeSet:
            return
        self.tradeSet.add(trade.vtTradeID)
        
        # 将成交推送到策略对象中
        if trade.vtOrderID in self.orderStrategyDict:
            strategy = self.orderStrategyDict[trade.vtOrderID]
            
            # 计算策略持仓
            if trade.direction == DIRECTION_LONG:
                strategy.pos += trade.volume
            else:
                strategy.pos -= trade.volume
            
            self.callStrategyFunc(strategy, strategy.onTrade, trade)
            
        # 更新持仓缓存数据
        if trade.vtSymbol in self.tickStrategyDict:
            posBuffer = self.posBufferDict.get(trade.vtSymbol, None)
            if not posBuffer:
                posBuffer = PositionBuffer()
                posBuffer.vtSymbol = trade.vtSymbol
                self.posBufferDict[trade.vtSymbol] = posBuffer
            posBuffer.updateTradeData(trade)            
            
    #----------------------------------------------------------------------
    def processPositionEvent(self, event):
        """处理持仓推送"""
        pos = event.dict_['data']
        
        # 更新持仓缓存数据
        if pos.vtSymbol in self.tickStrategyDict:
            posBuffer = self.posBufferDict.get(pos.vtSymbol, None)
            if not posBuffer:
                posBuffer = PositionBuffer()
                posBuffer.vtSymbol = pos.vtSymbol
                self.posBufferDict[pos.vtSymbol] = posBuffer
            posBuffer.updatePositionData(pos)
    
    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.eventEngine.register(EVENT_TICK, self.processTickEvent)
        self.eventEngine.register(EVENT_ORDER, self.processOrderEvent)
        self.eventEngine.register(EVENT_TRADE, self.processTradeEvent)
        self.eventEngine.register(EVENT_POSITION, self.processPositionEvent)
 
    #----------------------------------------------------------------------
    def insertData(self, dbName, collectionName, data):
        """插入数据到数据库(这里的data可以是VtTickData或者VtBarData)"""
        self.mainEngine.dbInsert(dbName, collectionName, data.__dict__)
    
    #----------------------------------------------------------------------
    def loadBar(self, dbName, collectionName, days):
        """从数据库中读取Bar数据,startDate是datetime对象"""
        startDate = self.today - timedelta(days)
        
        d = {'datetime':{'$gte':startDate}}
        barData = self.mainEngine.dbQuery(dbName, collectionName, d)
        
        l = []
        for d in barData:
            bar = VtBarData()
            bar.__dict__ = d
            l.append(bar)
        return l
    
    #----------------------------------------------------------------------
    def loadTick(self, dbName, collectionName, days):
        """从数据库中读取Tick数据,startDate是datetime对象"""
        startDate = self.today - timedelta(days)
        
        d = {'datetime':{'$gte':startDate}}
        tickData = self.mainEngine.dbQuery(dbName, collectionName, d)
        
        l = []
        for d in tickData:
            tick = VtTickData()
            tick.__dict__ = d
            l.append(tick)
        return l    
    
    #----------------------------------------------------------------------
    def writeCtaLog(self, content):
        """快速发出CTA模块日志事件"""
        log = VtLogData()
        log.logContent = content
        event = Event(type_=EVENT_CTA_LOG)
        event.dict_['data'] = log
        self.eventEngine.put(event)   
    
    #----------------------------------------------------------------------
    def loadStrategy(self, setting):
        """载入策略"""
        try:
            name = setting['name']
            className = setting['className']
        except Exception, e:
            self.writeCtaLog(u'载入策略出错:%s' %e)
            return
        
        # 获取策略类
        strategyClass = STRATEGY_CLASS.get(className, None)
        if not strategyClass:
            self.writeCtaLog(u'找不到策略类:%s' %className)
            return
        
        # 防止策略重名
        if name in self.strategyDict:
            self.writeCtaLog(u'策略实例重名:%s' %name)
        else:
            # 创建策略实例
            strategy = strategyClass(self, setting)  
            self.strategyDict[name] = strategy
            
            # 保存Tick映射关系
            if strategy.vtSymbol in self.tickStrategyDict:
                l = self.tickStrategyDict[strategy.vtSymbol]
            else:
                l = []
                self.tickStrategyDict[strategy.vtSymbol] = l
            l.append(strategy)
            
            # 订阅合约
            contract = self.mainEngine.getContract(strategy.vtSymbol)
            if contract:
                req = VtSubscribeReq()
                req.symbol = contract.symbol
                req.exchange = contract.exchange
                
                # 对于IB接口订阅行情时所需的货币和产品类型,从策略属性中获取
                req.currency = strategy.currency
                req.productClass = strategy.productClass
                
                self.mainEngine.subscribe(req, contract.gatewayName)
            else:
                self.writeCtaLog(u'%s的交易合约%s无法找到' %(name, strategy.vtSymbol))
コード例 #18
0
    def loadSetting(self):
        """载入设置"""
        with open(self.settingFilePath) as f:
            drSetting = json.load(f)

            # 如果working设为False则不启动行情记录功能
            working = drSetting['working']
            if not working:
                return

            if 'tick' in drSetting:
                l = drSetting['tick']

                for setting in l:
                    symbol = setting[0]
                    vtSymbol = symbol

                    req = VtSubscribeReq()
                    req.symbol = setting[0]

                    # 针对LTS和IB接口,订阅行情需要交易所代码
                    if len(setting) >= 3:
                        req.exchange = setting[2]
                        vtSymbol = '.'.join([symbol, req.exchange])

                    # 针对IB接口,订阅行情需要货币和产品类型
                    if len(setting) >= 5:
                        req.currency = setting[3]
                        req.productClass = setting[4]

                    self.mainEngine.subscribe(req, setting[1])

                    drTick = DrTickData()  # 该tick实例可以用于缓存部分数据(目前未使用)
                    self.tickDict[vtSymbol] = drTick

            if 'bar' in drSetting:
                l = drSetting['bar']

                for setting in l:
                    symbol = setting[0]
                    vtSymbol = symbol

                    req = VtSubscribeReq()
                    req.symbol = symbol

                    if len(setting) >= 3:
                        req.exchange = setting[2]
                        vtSymbol = '.'.join([symbol, req.exchange])

                    if len(setting) >= 5:
                        req.currency = setting[3]
                        req.productClass = setting[4]

                    self.mainEngine.subscribe(req, setting[1])

                    bar = DrBarData()
                    self.barDict[vtSymbol] = bar

            if 'renko' in drSetting:
                l = drSetting.get('renko')
                req_set = set()
                for setting in l:
                    # 获取合约,合约短号,renko的高度(多少个跳)
                    vtSymbol = setting.get('vtSymbol', None)
                    if vtSymbol is None:
                        continue
                    short_symbol = getShortSymbol(vtSymbol).upper()
                    height = setting.get('height', 5)
                    minDiff = setting.get('minDiff', 1)

                    # 获取vtSymbol的多个renkobar列表,添加新的CtaRenkoBar
                    renko_list = self.renkoDict.get(vtSymbol, [])

                    bar_setting = {
                        'name': '{}_{}'.format(vtSymbol, height),
                        'shortSymbol': short_symbol,
                        'vtSymbol': vtSymbol,
                        'minDiff': minDiff,
                        'height': minDiff * height
                    }
                    renko_bar = CtaRenkoBar(strategy=None,
                                            onBarFunc=self.onRenkoBar,
                                            setting=bar_setting)
                    renko_list.append(renko_bar)
                    self.renkoDict.update({vtSymbol: renko_list})

                    req = VtSubscribeReq()
                    req.symbol = vtSymbol
                    req_set.add((req, setting.get('gateway', None)))
                # 更新合约的历史数据
                self.add_gap_ticks()

                # 订阅行情
                for req, gw in req_set:
                    self.mainEngine.subscribe(req, gw)

            if 'active' in drSetting:
                d = drSetting['active']

                # 注意这里的vtSymbol对于IB和LTS接口,应该后缀.交易所
                for activeSymbol, vtSymbol in d.items():
                    self.activeSymbolDict[vtSymbol] = activeSymbol

            # 启动数据插入线程
            self.start()

            # 注册事件监听
            self.registerEvent()