def generateBarDict(self,
                        onBar,
                        xmin=0,
                        onXminBar=None,
                        size=100,
                        alignment='sharp',
                        marketClose=(23, 59)):
        if xmin:
            variable = "bg%sDict" % xmin
            variable2 = "am%sDict" % xmin
        else:
            variable = "bgDict"
            variable2 = "amDict"
        bgDict = {
            sym: BarGenerator(onBar,
                              xmin,
                              onXminBar,
                              alignment=alignment,
                              marketClose=marketClose)
            for sym in self.symbolList
        }

        amDict = {sym: ArrayManager(size) for sym in self.symbolList}

        setattr(self, variable, bgDict)
        setattr(self, variable2, amDict)
示例#2
0
    def __init__(self, omEngine, eventEngine):
        self.omEngine = omEngine
        self.mainEngine = omEngine.mainEngine
        self.strategyEngine = omEngine.strategyEngine
        self.eventEngine = eventEngine
        self.portfolio = omEngine.portfolio

        self.bg = BarGenerator(self.onVixBar)

        self.active = False
        self.queue = Queue()
        self.thread = Thread(target=self.run)

        self.vixDict = OrderedDict()
        self.timerDict = dict()

        for chain in self.portfolio.chainDict.values():
            self.vixDict[chain.symbol] = OmVixCalculator(chain)

        self.registerEvent()
        self.start()
示例#3
0
    def onInit(self):
        self.symbol = self.symbolList[0]

        self.generateBarDict(self.onBar,size = self.size)
        # self.generateBarDict(self.onBar,3,self.on3MinBar,size =self.size)
        # self.generateBarDict(self.onBar,5,self.on5MinBar,size =self.size)
        # self.generateBarDict(self.onBar,30,self.on30MinBar,size =self.size)
        self.generateBarDict(self.onBar,60,self.on60MinBar,size =self.size)
        self.bgDayDict= BarGenerator(self.onCandle,marketClose =(14,59))
        self.bgWeekDict = BarGenerator(self.onWCandle)
        self.bgMonDict = BarGenerator(self.onMCandle)
        self.amweekDict = ArrayManager(25)
        self.ammonDict = ArrayManager(6)
        for s in self.symbolList:
            kline = self.loadHistoryBar(s,'1min', since = '20180410')
            for index, bar in enumerate(kline):
                self.onBar(bar)
示例#4
0
class BarStrategy(CtaTemplate):
    # 策略参数
    size = 800
    transactionPrice = {}
    tradable = False
    # 参数列表,保存了参数的名称
    paramList = ['className']

    # 变量列表,保存了变量的名称
    varList = ['inited',
               'trading',
               'posDict',
               'transactionPrice']

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['posDict','eveningDict']
    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        super(BarStrategy, self).__init__(ctaEngine, setting)
        self.lots = setting['lots']
    #----------------------------------------------------------------------
    def onInit(self):
        self.symbol = self.symbolList[0]

        self.generateBarDict(self.onBar,size = self.size)
        # self.generateBarDict(self.onBar,3,self.on3MinBar,size =self.size)
        # self.generateBarDict(self.onBar,5,self.on5MinBar,size =self.size)
        # self.generateBarDict(self.onBar,30,self.on30MinBar,size =self.size)
        self.generateBarDict(self.onBar,60,self.on60MinBar,size =self.size)
        self.bgDayDict= BarGenerator(self.onCandle,marketClose =(14,59))
        self.bgWeekDict = BarGenerator(self.onWCandle)
        self.bgMonDict = BarGenerator(self.onMCandle)
        self.amweekDict = ArrayManager(25)
        self.ammonDict = ArrayManager(6)
        for s in self.symbolList:
            kline = self.loadHistoryBar(s,'1min', since = '20180410')
            for index, bar in enumerate(kline):
                self.onBar(bar)

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
    def onStop(self):
        self.putEvent()
    def onRestore(self):
        """恢复策略(必须由用户继承实现)"""
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bgDict[tick.vtSymbol].updateTick(tick)
    # ---------------------------------------------------------------------
    def onBar(self, bar):
        # self.bg3Dict[self.symbol].updateBar(bar)
        # self.bg5Dict[self.symbol].updateBar(bar)
        # self.bg30Dict[self.symbol].updateBar(bar)
        self.bg60Dict[self.symbol].updateBar(bar)
        self.bgDayDict.updateCandle(bar)
        # self.writeCtaLog('onBar: %s '%bar.__dict__)
    #----------------------------------------------------------------------
    # def on3MinBar(self, bar):
    #     # self.writeCtaLog('on----------6666666666666666------------Bar: %s '%bar.datetime)
    #     self.am3Dict[self.symbol].updateBar(bar)
    # def on5MinBar(self, bar):
    #     # self.writeCtaLog('on----------6666666666666666------------Bar: %s '%bar.datetime)
    #     self.am5Dict[self.symbol].updateBar(bar)
    # def on30MinBar(self, bar):
    #     # self.writeCtaLog('on----------6666666666666666------------Bar: %s '%bar.datetime)
    #     self.am30Dict[self.symbol].updateBar(bar)
    def on60MinBar(self, bar):
        # self.writeCtaLog('on----------6666666666666666------------Bar: %s '%bar.datetime)
        self.am60Dict[self.symbol].updateBar(bar)
    #----------------------------------------------------------------------
    def onCandle(self,Candle):
        """Daily Candles"""
        # self.writeCtaLog('on----------dayyyyyyyyyyy------------Bar: %s '%bar.datetime)
        self.bgWeekDict.updateWCandle(Candle)
        self.bgMonDict.updateMCandle(Candle)
    def onWCandle(self,Candle):
        """Week Candles"""
        self.amweekDict.updateBar(Candle)
        # if self.amweekDict.inited:
        #     print(self.amweekDict.DataFrame())
        # self.writeCtaLog('on----------xxxxxxxxxxxxxxxxxxx------------Bar: %s '%Candle.datetime)
    def onMCandle(self,Candle):
        """Month Candles"""
        self.ammonDict.updateBar(Candle)
        if self.ammonDict.inited:
            print(self.ammonDict.DataFrame())
        self.writeCtaLog('on----------MMMMMMMMMMMMMMMMMMM------------Bar: %s '%Candle.datetime)

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        pass
    #----------------------------------------------------------------------
    def onTrade(self, trade):
        """收到成交推送(必须由用户继承实现)"""
        pass
    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass
 def generateHFBar(self, xSecond, size=60):
     self.hfDict = {
         sym: BarGenerator(self.onHFBar, xSecond=xSecond)
         for sym in self.symbolList
     }
     self.amhfDict = {sym: ArrayManager(size) for sym in self.symbolList}
示例#6
0
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(NewMacdStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()
示例#7
0
class NewMacdStrategy(CtaTemplate):
    """New MACD策略Demo"""
    className = 'NewMacdStrategy'
    author = u'liu_hao'

    # 策略参数
    initDays = 10  # 初始化数据所用的天数
    barIndex = 0
    MacdList = []
    barDataList = []
    ema12 = EMPTY_FLOAT
    ema26 = EMPTY_FLOAT
    diff = EMPTY_FLOAT
    dea9 = EMPTY_FLOAT
    macd = EMPTY_FLOAT
    beforeMacd = EMPTY_FLOAT
    newMacd = EMPTY_FLOAT

    # 策略变量

    lowBand = -0.0009
    upBand = 0.0011
    fixprice = 0.6
    ontrade = 0
    adjustNum = 2700

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'initDays', 'barIndex',
        'MacdList', 'barDataList', 'ema12', 'ema26', 'diff', 'dea9', 'macd',
        'beforeMacd', 'newMacd'
    ]

    # 变量列表,保存了变量的名称
    varList = ['lowBand', 'upBand', 'fixprice', 'adjustNum']

    # 同步列表,保存了需要保存到数据库的变量名称
    syncList = ['pos']

    # ----------------------------------------------------------------------

    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(NewMacdStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()

        # 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建,
        # 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险,
        # 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读
        # 策略时方便(更多是个编程习惯的选择)

    # ----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'new MACD演示策略初始化')
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)
        self.putEvent()

    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'new MACD演示策略启动')
        self.putEvent()

    def onStop(self):
        """停止策略(必须由用户继承实现)"""

        self.writeCtaLog(u'new MACD演示策略停止')
        self.putEvent()

    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)

    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        am = self.am
        am.updateBar(bar)
        if not am.inited:
            return
        if self.barIndex == 0:
            self.ema12 = bar.close
            self.ema26 = bar.close
            self.diff = 0
            self.dea9 = 0
        else:
            self.ema12 = self.ema(self.ema12, bar.close, 12)
            self.ema26 = self.ema(self.ema26, bar.close, 26)
            self.diff = self.ema12 - self.ema26
            self.dea9 = self.ema(self.dea9, self.diff, 9)
        self.macd = self.diff - self.dea9
        if self.barIndex < 34:
            self.newMacd = 0
        else:
            self.newMacd = self.macd / am.closeArray[-35]

        self.MacdList.append(self.beforeMacd)
        # 做多买入
        crossLowpBand = (self.beforeMacd < self.lowBand) and (self.newMacd >
                                                              self.lowBand)

        # 做多止损
        crossLimitLowBand = self.newMacd <= 1.2 * self.lowBand

        # 做空买入
        crossUpBand = (self.beforeMacd > self.upBand) and (self.newMacd <
                                                           self.upBand)

        # 做空止损
        crossLimitUpBand = self.newMacd >= 1.2 * self.upBand

        if bar.datetime.time() < datetime.time(14, 55):
            if self.pos == 0:
                if crossLowpBand:
                    self.buy(bar.close + self.fixprice, 1)
                    self.log('buy   : ' + str(bar.datetime) + " " +
                             str(bar.close))
                elif crossUpBand:
                    self.short(bar.close - self.fixprice, 1)
                    self.log('short : ' + str(bar.datetime) + " " +
                             str(bar.close))

            elif self.pos > 0:
                if self.newMacd >= 0:
                    self.log('sell  : ' + str(bar.datetime) + " " +
                             str(bar.close) + "  +")
                    self.sell(bar.close - self.fixprice, 1)
                elif crossLimitLowBand:
                    self.sell(bar.close - self.fixprice, 1)
                    self.log('sell  : ' + str(bar.datetime) + " " +
                             str(bar.close) + "  -")
            else:
                if self.newMacd <= 0:
                    self.log('cover : ' + str(bar.datetime) + " " +
                             str(bar.close) + "  +")
                    self.cover(bar.close + self.fixprice, 1)

                elif crossLimitUpBand:
                    self.log('cover : ' + str(bar.datetime) + " " +
                             str(bar.close) + "  -")
                    self.cover(bar.close + self.fixprice, 1)
        else:
            if self.pos > 0:
                self.log('sell  : ' + str(bar.datetime) + " " + str(bar.close))
                self.sell(bar.close - self.fixprice, 1)

            elif self.pos < 0:
                self.log('cover : ' + str(bar.datetime) + " " + str(bar.close))
                self.cover(bar.close + self.fixprice, 1)

        if self.barIndex < 35:
            self.barIndex = self.barIndex + 1
        self.beforeMacd = self.newMacd
        self.adjustParameter()

        # 发出状态更新事件
        self.putEvent()

    def onOrder(self, order):
        pass

    def onTrade(self, trade):
        self.ontrade = 0

    def onStopOrder(self, so):
        pass

    def ema(self, beforeValue, newData, days):
        temp = ((days - 1) * beforeValue + 2 * newData) / (days + 1)
        return temp

    def log(self, message):
        if True:
            print message

    def adjustParameter(self):
        if len(self.MacdList) < self.adjustNum:
            return
        else:
            tempList = self.MacdList[(-1 * self.adjustNum):]
            max_10_list = heapq.nlargest(500, tempList)
            min_10_list = heapq.nsmallest(500, tempList)
            self.upBand = sum(max_10_list) / len(max_10_list)
            self.lowBand = sum(min_10_list) / len(min_10_list)
示例#8
0
    def loadSetting(self):
        """加载配置"""
        with open(self.settingFilePath) as f:
            drSetting = json.load(f)

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

            # 加载收盘时间
            if 'marketCloseTime' in drSetting:
                timestamp = drSetting['marketCloseTime']
                self.marketCloseTime = datetime.strptime(
                    timestamp, '%H:%M:%S').time()

            # Tick记录配置
            if 'tick' in drSetting:
                l = drSetting['tick']

                for setting in l:
                    symbol = setting[0]
                    gateway = setting[1]
                    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, gateway)

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

                    # 保存到配置字典中
                    if vtSymbol not in self.settingDict:
                        d = {
                            'symbol': symbol,
                            'gateway': gateway,
                            'tick': True
                        }
                        self.settingDict[vtSymbol] = d
                    else:
                        d = self.settingDict[vtSymbol]
                        d['tick'] = True

            # 分钟线记录配置
            if 'bar' in drSetting:
                l = drSetting['bar']

                for setting in l:
                    symbol = setting[0]
                    gateway = setting[1]
                    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, gateway)

                    # 保存到配置字典中
                    if vtSymbol not in self.settingDict:
                        d = {'symbol': symbol, 'gateway': gateway, 'bar': True}
                        self.settingDict[vtSymbol] = d
                    else:
                        d = self.settingDict[vtSymbol]
                        d['bar'] = True

                    # 创建BarManager对象
                    self.bgDict[vtSymbol] = BarGenerator(self.onBar)

            # 主力合约记录配置
            if 'active' in drSetting:
                d = drSetting['active']
                self.activeSymbolDict = {
                    vtSymbol: activeSymbol
                    for activeSymbol, vtSymbol in d.items()
                }
示例#9
0
class OmVixEngine(object):
    """波动率计算引擎"""
    def __init__(self, omEngine, eventEngine):
        self.omEngine = omEngine
        self.mainEngine = omEngine.mainEngine
        self.strategyEngine = omEngine.strategyEngine
        self.eventEngine = eventEngine
        self.portfolio = omEngine.portfolio

        self.bg = BarGenerator(self.onVixBar)

        self.active = False
        self.queue = Queue()
        self.thread = Thread(target=self.run)

        self.vixDict = OrderedDict()
        self.timerDict = dict()

        for chain in self.portfolio.chainDict.values():
            self.vixDict[chain.symbol] = OmVixCalculator(chain)

        self.registerEvent()
        self.start()

    def start(self):
        """启动"""
        self.active = True
        self.thread.start()

    def stop(self):
        """关闭"""
        if self.active:
            self.active = False
            self.thread.join()

    def run(self):
        """运行入库的线程"""
        while self.active:
            try:
                dbName, collectionName, d = self.queue.get(block=True,
                                                           timeout=1)
                try:
                    self.mainEngine.dbInsert(dbName, collectionName, d)
                except DuplicateKeyError:
                    pass
            except Empty:
                pass

    def registerEvent(self):
        """注册事件回调函数"""
        self.eventEngine.register(EVENT_TIMER, self.processTimerEvent)
        self.eventEngine.register(EVENT_OM_VIX, self.processOmVixEvent)

    def processTimerEvent(self, event):
        """处理定时事件"""
        for calculator in self.vixDict.values():
            self.calcVix(calculator)

    def processOmVixEvent(self, event):
        """处理波动率数据事件"""
        vix = event.dict_['data']
        self.onVixTick(vix)

        if self.bg:
            self.bg.updateTick(vix)

        print(vix.vtSymbol, vix.datetime.strftime('%Y%m%d %H:%M:%S.%f'),
              vix.lastPrice)

    def onVixTick(self, vix):
        """波动率tick更新"""
        self.insertData(TICK_DB_NAME, vix.vtSymbol, vix)

    def onVixBar(self, bar):
        """波动率bar更新"""
        self.insertData(MINUTE_DB_NAME, bar.vtSymbol, bar)

    def insertData(self, dbName, collectionName, data):
        """把数据放入入库队列"""
        self.queue.put((dbName, collectionName, data.__dict__))

    def calcVix(self, calculator):
        """计算波指"""
        if self.active:
            tName = 'vixT.' + calculator.chain.symbol
            fIdxName = 'vixFIdx.' + calculator.chain.symbol
            vixName = 'vix.' + calculator.chain.symbol

            option = calculator.chain.optionDict.values()[0]
            if not calculator.t:
                self.timer(tName, 1, calculator.calcT, option)
            else:
                self.timer(tName, 60, calculator.calcT, option)

            if not calculator.fIdx:
                self.timer(fIdxName, 1, calculator.calcFIdx)
            else:
                self.timer(fIdxName, 12, calculator.calcFIdx)

            vix = self.timer(vixName, 0, calculator.calcVix)
            if vix:
                event = Event(type_=EVENT_OM_VIX)
                event.dict_['data'] = vix
                self.eventEngine.put(event)

    def timer(self, name, interval, func, *args, **kwargs):
        """自定义定时器"""
        if self.timerDict.get(name) is None:
            self.timerDict[name] = 0

        if self.timerDict[name] > interval:
            res = func(*args, **kwargs)
            self.timerDict[name] = 0
            return res

        self.timerDict[name] += 1