예제 #1
0
class ZeroStrategy(CtaTemplate):
    """基于布林通道的交易策略"""
    className = 'ZeroStrategy'
    author = u'用Python的交易员'

    initDays = 4  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'initDays', 'fixedSize'
    ]

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

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

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(ZeroStrategy, self).__init__(ctaEngine, setting)

        self.bg = BarGenerator(self.onBar, 30, self.on30minBar)  # 创建K线合成器对象
        self.am = ArrayManager()

        #最小价差变动
        self.tickadd = 1

        #有无夜盘和 相关的时间
        self.yepan = True
        self.yepanhour = 23
        self.yepanminute = 00
        self.stopcount = 0
        #断网变量相关
        self.lastbardatetime = None
        self.didinited = False

        #仓位相关
        self.posdetail = None

        #订单相关
        self.shortOrder = None
        self.buyOrder = None
        self.sellOrder = None
        self.coverOrder = None

        #撤单后跟单相关
        self.genOrder = None

        #tick策略相关全局函数
        #交易那一分钟
        self.tradeMinute = False
        #order那一分钟
        self.orderMinute = False

    #----------------------------------------------------------------------
    def on30minBar(self, bar):
        """"""

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略初始化' % self.name)
        self.getPosDetail()

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)
        self.didinited = True
        self.putEvent()

    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略启动' % self.name)
        self.putEvent()

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'%s策略停止' % self.name)
        self.putEvent()

    def cancelVtOrder(self, order, yuanyin, fangxiang, price=None):
        self.writeCtaLog(yuanyin + 'cancle')
        self.cancelOrder(order)
        if fangxiang == 'buy':
            self.buyOrder = None
        elif fangxiang == 'short':
            self.shortOrder = None
        elif fangxiang == 'sell':
            self.sellOrder == None
        elif fangxiang == 'cover':
            self.coverOrder = None
        else:
            self.writeCtaLog('ohmyghoa')
        if price is not None:
            self.genOrder = price

    #----------------------------------------------------------------------
    def buyTickCelve(self, tick):
        am = self.am
        fangxiang = None
        price = None
        if tick.datetime.second > 51:
            if am.diff > 0 and am.macd < 0 and am.lastmacd > 0:
                fangxiang = duo
                price = tick.bidPrice1

            elif am.macd > 0 and am.lastmacd < 0:
                fangxiang = duoping
                price = tick.askPrice1
            self.chulikaipingcang(fangxiang, price)
            # 处理错误开仓(但市场方向正确的仓),在收阳时平掉

            if self.posdetail.longPos > 0 and am.macd > 0 and am.lastmacd > 0 and self.bg.bar.open > tick.lastPrice and not self.tradeMinute:
                fangxiang = duoping
                price = tick.askPrice1
                self.chulikaipingcang(fangxiang, price)

    #----------------------------------------------------------------------
    def shortTickCelve(self, tick):
        am = self.am
        fangxiang = None
        price = None
        if tick.datetime.second > 51:
            if am.diff < 0 and am.macd > 0 and am.lastmacd < 0:

                fangxiang = kong
                price = tick.askPrice1

            elif am.macd < 0 and am.lastmacd > 0:
                fangxiang = kongping
                price = tick.bidPrice1
            self.chulikaipingcang(fangxiang, price)
        #处理错误开仓(但市场方向正确的仓),在收阳时平掉
        if self.posdetail.shortPos > 0 and am.macd < 0 and am.lastmacd < 0 and self.bg.bar.open < tick.lastPrice and not self.tradeMinute:
            fangxiang = kongping
            price = tick.bidPrice1
            self.chulikaipingcang(fangxiang, price)

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

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

        if not self.stopcount:
            self.buyTickCelve(tick)
            self.shortTickCelve(tick)
            if tick.datetime.second == 59:
                self.checkFalseSignal(tick)

    def checkPingcang(self, bar):
        if self.didinited:
            am = self.am
            fangxiang = None
            price = None
            if self.posdetail.longPos > 0 and self.sellOrder is not None and am.lastmacd > 0 and am.mj < 0:
                price = am.tick.bidPrice1

                self.cancelVtOrder(self.sellOrder, u'必须平多', 'sell', price)
            elif self.posdetail.shortPos > 0 and self.coverOrder is not None and am.lastmacd < 0 and am.mj > 0:
                price = am.tick.askPrice1
                self.cancelVtOrder(self.coverOrder, u'必须平空', 'cover', price)
        #----------------------------------------------------------------------
    def getPosDetail(self):
        self.posdetail = self.ctaEngine.mainEngine.getPositionDetail(
            self.vtSymbol)

    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""

        #检查是否有效的交易时间
        if self.notintradingTime(bar):
            print('not')
            runDataCleaning()
            return
        detail = self.posdetail
        # if  not self.didinited:
        # posdetial = self.posdetail
        #print( detail.longPos,'long and short ',detail.shortPos )

        if not self.lastbardatetime == bar.datetime:
            self.bg.updateBar(bar)
            self.am.updateBar(bar)

        am = self.am

        self.barCelve(bar)

        #tick策略数据还原
        self.tradeMinute = False
        self.orderMinute = False

        print('zhibiao', 'macd', am.macd, 'diff', am.diff, 'mj', am.mj, 'time',
              bar.datetime, 'end')
        #检查是否断网

        self.lastbardatetime = bar.datetime

        self.am.endBar()

    #----------------------------------------------------------------------
    def barCelve(self, bar):
        self.checkCancelOrder()
        self.checkIfConnecting(bar)
        self.checkPingcang(bar)

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""

        #orderminute
        self.orderMinute = True

        #对相应订单编号进行管理
        if order.status == STATUS_NOTTRADED:
            self.reactOrder(order, order.vtOrderID)
        elif order.status == STATUS_ALLTRADED or order.status == STATUS_CANCELLED:
            self.reactOrder(order, None)
        elif order.status == STATUS_REJECTED:
            self.writeCtaLog(STATUS_REJECTED + order.offset + order.direction)
            print('time', self.am.tick.datetime, order.orderTime, order.price,
                  self.genOrder)

        #检查需不需要跟单
        if order.status == STATUS_CANCELLED and self.genOrder is not None:
            self.writeCtaLog('ongendan' + order.offset + order.direction)
            print(self.genOrder)
            if order.offset == OFFSET_OPEN and order.direction == DIRECTION_LONG:
                self.orderBuy(self.genOrder)
                self.genOrder = None
            elif order.offset == OFFSET_OPEN and order.direction == DIRECTION_SHORT:
                self.orderShort(self.genOrder)
                self.genOrder = None
            elif (order.offset == OFFSET_CLOSE or order.offset
                  == OFFSET_CLOSETODAY or order.offset == OFFSET_CLOSEYESTERDAY
                  ) and order.direction == DIRECTION_LONG:
                self.orderCover(self.genOrder)
                self.genOrder = None
            elif (order.offset == OFFSET_CLOSE or order.offset
                  == OFFSET_CLOSETODAY or order.offset == OFFSET_CLOSEYESTERDAY
                  ) and order.direction == DIRECTION_SHORT:
                self.orderSell(self.genOrder)
                self.genOrder = None
        print 'order', order.price, order.direction, order.offset, order.status, order.vtOrderID, order.orderTime, self.pos, self.am.tick.datetime

    #----------------------------------------------------------------------
    def reactOrder(self, order, vtOrderID):
        print 'react', order.direction, order.offset

        if (order.direction == DIRECTION_LONG and order.offset == OFFSET_OPEN):
            print 'enterlong'
            self.buyOrder = vtOrderID
        elif (
                order.direction == DIRECTION_SHORT and
            (order.offset == OFFSET_CLOSE or order.offset == OFFSET_CLOSETODAY
             or order.offset == OFFSET_CLOSEYESTERDAY)):
            print('entersell')
            self.sellOrder = vtOrderID
        elif (order.direction == DIRECTION_SHORT
              and order.offset == OFFSET_OPEN):
            print 'entershort'
            self.shortOrder = vtOrderID
        elif (
                order.direction == DIRECTION_LONG and
            (order.offset == OFFSET_CLOSE or order.offset == OFFSET_CLOSETODAY
             or order.offset == OFFSET_CLOSEYESTERDAY)):
            print('enter coveer')
            self.coverOrder = vtOrderID
        else:
            print('enteranother')

    def onTrade(self, trade):
        # 发出状态更新事件
        self.reactOrder(trade, None)

        #处理tick策略
        self.tradeMinute = True

        print 'trade', trade.price, trade.direction, trade.offset, trade.tradeTime

        self.putEvent()

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass

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

    '''仓位函数'''
    def chulikaipingcang(self, fangxiang, price):
        if self.didinited:
            if fangxiang == duo:
                if self.posdetail.longPos == 0:
                    print 'buybuy'
                    self.orderBuy(price, 1)

            elif fangxiang == kong:
                if self.posdetail.shortPos == 0:
                    self.orderShort(price, 1)

            elif fangxiang == duoping:
                if self.posdetail.longPos > 0:
                    self.orderSell(price, 1)
                if self.buyOrder is not None:
                    self.cancelVtOrder(self.buyOrder, u'平多时候', 'buy')

            elif fangxiang == kongping:
                if self.posdetail.shortPos > 0:
                    self.orderCover(price, 1)
                if self.shortOrder is not None:
                    self.cancelVtOrder(self.shortOrder, u'平空时候', 'short')

        #-------------------------------------------------------
        '''订单管理类'''

    def orderBuy(self, price, volume=1, stop=False):
        if self.buyOrder is None:
            print 'buyorder'
            self.buyOrder = 0
            self.buy(price, volume, stop)

    def orderSell(self, price, volume=1, stop=False):
        if self.sellOrder is None:
            self.sellOrder = 0
            self.sell(price, volume, stop)

    def orderShort(self, price, volume=1, stop=False):
        if self.shortOrder is None:
            self.shortOrder = 0
            self.short(price, volume, stop)

    def orderCover(self, price, volume=1, stop=False):
        if self.coverOrder is None:
            self.coverOrder = 0
            self.cover(price, volume, stop)

    # ----------------------------------------------------------------------
    '''断网判断及处理函数'''
    '''目前的逻辑是根据两个bar的时间间隔来判断是否断网,一个可能的风险当市场上两笔交易的间隔长于两分钟时,会错认为也是断网了,这个在不活跃品种也较容易出现。不过一般出现这种情况较少。'''

    def closeAllPosistion(self, price):
        '''出意外如断网时平仓'''
        self.cancelAll()
        print('--closeallpos--')
        if self.pos > 0:
            self.short(price - self.tickadd, abs(self.pos))
        elif self.pos < 0:
            self.cover(price + self.tickadd, abs(self.pos))

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

    # ----------------------------------------------------------------------
    def iscontinueTime(self, firstdatetime, seconddatetime):
        '''判断是否为连续的时间'''
        if (firstdatetime.hour == seconddatetime.hour and firstdatetime.minute + 1 == seconddatetime.minute) \
                or (
                firstdatetime.hour == seconddatetime.hour - 1 and firstdatetime.minute == 59 and seconddatetime.minute == 0):
            return True

    # ----------------------------------------------------------------------
    def isTradeContinueTime(self, firstdatetime, seconddatetime):
        '''判断是否为连续的交易时间'''
        if self.iscontinueTime(firstdatetime, seconddatetime):
            return True
        elif firstdatetime.hour == 10 and (
                firstdatetime.minute == 15 or firstdatetime.minute == 14
        ) and seconddatetime.hour == 10 and (seconddatetime.minute == 30
                                             or seconddatetime.minute == 31):
            return True
        elif firstdatetime.hour == 11 and (
                firstdatetime.minute == 29 or firstdatetime.minute == 30
        ) and seconddatetime.hour == 13 and (seconddatetime.minute == 30
                                             or seconddatetime.minute == 31
                                             or seconddatetime.minute == 29):
            return True
        elif self.yepan and (seconddatetime.hour == 9 or
                             (seconddatetime.hour == 8
                              and seconddatetime.minute == 59)) and (
                                  firstdatetime.hour == self.yepanhour or
                                  (firstdatetime.hour == self.yepanhour - 1
                                   and firstdatetime.minute == 59)):
            return True
        elif (firstdatetime.hour == 15 or
              (firstdatetime.hour == 14 and firstdatetime.minute == 59)) and (
                  (seconddatetime.hour == 9 and seconddatetime.minute == 0) or
                  (seconddatetime.hour == 8 and seconddatetime.minute == 59)):
            return True
        elif ((firstdatetime.hour == 14 and firstdatetime.minute == 59)
              or firstdatetime.hour == 15) and (
                  seconddatetime.hour == 21 or
                  (seconddatetime.hour == 20 and seconddatetime.minute == 59)):
            return True
        elif ((firstdatetime.hour == 23 and firstdatetime.minute == 59) and
              (seconddatetime.hour == 0 and seconddatetime.minute == 0)) or (
                  (firstdatetime.hour == 0 and firstdatetime.minute == 59) and
                  ((seconddatetime.hour == 9 and seconddatetime.minute == 0))):
            return True

        else:
            print('dus conne', firstdatetime, seconddatetime)
            return False

    # ----------------------------------------------------------------------
    def handleDisConnected(self, price):
        print('DISCONNECTED', self.lastbardatetime, self.am.datetime)
        self.reSetOrder()
        self.stopcount = 15

    def notintradingTime(self, bar):
        dt = bar.datetime.time()
        if ((MORNING_START <= dt < MORNING_REST)
                or (MORNING_RESTART <= dt < MORNING_END)
                or (AFTERNOON_START <= dt < AFTERNOON_END)
                or (dt >= NIGHT_START) or (dt < NIGHT_END)):
            return False
        else:
            return True

    def checkIfConnecting(self, bar):
        if self.lastbardatetime is None:
            self.lastbardatetime = bar.datetime
        elif self.lastbardatetime == bar.datetime:
            pass
        else:
            if not self.isTradeContinueTime(self.lastbardatetime,
                                            bar.datetime):
                # 断网了,需要处理断网状态
                self.handleDisConnected(bar.close)
            # 没有断网
            else:
                if self.stopcount > 0:
                    self.stopcount -= 1

    def checkCancelOrder(self):
        if self.orderMinute:
            print('orderminute', self.buyOrder, self.shortOrder,
                  self.sellOrder, self.coverOrder)
            if self.buyOrder:
                if self.am.macd > 0:
                    self.cancelVtOrder(self.buyOrder, u"没进入绿浪", 'buy')
            if self.shortOrder:
                if self.am.macd < 0:
                    self.cancelVtOrder(self.shortOrder, u"没进入红狼", 'short')
            if self.sellOrder:
                if self.am.macd < 0:
                    self.cancelVtOrder(self.sellOrder, u'没进入红浪', 'sell')
            if self.coverOrder:
                if self.am.macd > 0:
                    self.cancelVtOrder(self.coverOrder, u'没进入绿琅', 'cover')

    def checkFalseSignal(self, tick):
        if self.tradeMinute:
            if self.posdetail.longPos > 0:
                if self.am.macd > 0:
                    self.sellFok(tick.askPrice1, 1)
            elif self.posdetail.shortPos > 0:
                if self.am.macd < 0:
                    self.coverFok(tick.bidPrice1, 1)


#回测用

    def barkaicang(self, bar):
        am = self.am
        if not self.stopcount:
            fangxiang = None
            price = bar.close
            if am.diff > 0 and am.macd < 0 and am.lastmacd > 0:
                fangxiang = duo
            elif am.macd > 0 and am.lastmacd < 0:
                fangxiang = duoping
            elif am.diff < 0 and am.macd > 0 and am.lastmacd < 0:
                fangxiang = kong
            elif am.macd < 0 and am.lastmacd > 0:
                fangxiang = kongping
            self.chulikaipingcang(fangxiang, price)

    def reSetOrder(self):
        print '---------------------reset--------------'
        self.shortOrder = None
        self.coverOrder = None
        self.buyOrder = None
        self.sellOrder = None
예제 #2
0
class tempStrategy(CtaTemplate):
    """双指数均线策略Demo"""
    className = 'DoubleMaStrategy'
    author = u'用Python的交易员'

    # 策略参数
    fastWindow = 12  # 快速均线参数
    slowWindow = 26  # 慢速均线参数
    initDays = 0  # 初始化数据所用的天数

    # 策略变量
    fastMa0 = EMPTY_FLOAT  # 当前最新的快速EMA
    fastMa1 = EMPTY_FLOAT  # 上一根的快速EMA

    slowMa0 = EMPTY_FLOAT
    slowMa1 = EMPTY_FLOAT
    huice = False
    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'fastWindow', 'slowWindow'
    ]

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'fastMa0', 'fastMa1', 'slowMa0', 'slowMa1'
    ]

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

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(tempStrategy, self).__init__(ctaEngine, setting)
        self.bg = BarGenerator(self.onBar)
        self.am = ArrayManager()
        self.lastzhibiao = zhibiao(0, 0, 0)
        self.celve0 = zerocelve()
        # self.celve1 = ceshi()
        self.tickCelvezu = [self.celve0]
        self.barCelvezu = [self.celve0]

        self.tickadd = 1

        #断网恢复变量
        self.stopcount = None

        #交易时间和监控联网状态变量
        self.yepan = False
        self.yepanhour = None
        self.yepanminute = None
        self.lastbardatetime = None

        self.tradetime = None

        #控制开仓和平仓稳定变量
        self.tradecount = 0

        self.tradingcelve = [self.celve0]

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

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'双EMA演示策略初始化')

        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)
        self.am.inited = True
        self.putEvent()

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

    #----------------------------------------------------------------------
    def closeAllPosistion(self, price):
        print('--closeallpos--')
        if self.pos > 0:
            self.short(price - self.tickadd, abs(self.pos))
        elif self.pos < 0:
            self.cover(price + self.tickadd, abs(self.pos))

        # ----------------------------------------------------------------------
    def datetimePlusMinute(self, datelatime, minute):
        newdatetime = datetime.now()
        if datelatime.minute + minute < 60:
            newdatetime.minute = datelatime.minute + minute
        else:
            newdatetime.hour = datelatime.hour + 1
            newdatetime.minute = datelatime.minute + minute - 60
        return newdatetime

    # ----------------------------------------------------------------------
    def iscontinueTime(self, firstdatetime, seconddatetime):
        if (firstdatetime.hour == seconddatetime.hour and firstdatetime.minute + 1 == seconddatetime.minute) \
                or (
                firstdatetime.hour == seconddatetime.hour - 1 and firstdatetime.minute == 59 and seconddatetime.minute == 0):
            return True

    # ----------------------------------------------------------------------
    def isTradeContinueTime(self, firstdatetime, seconddatetime):
        if self.iscontinueTime(firstdatetime, seconddatetime):
            return True
        elif firstdatetime.hour == 10 and (
                firstdatetime.minute == 15 or firstdatetime.minute == 14
        ) and seconddatetime.hour == 10 and seconddatetime.minute == 30:
            return True
        elif firstdatetime.hour == 11 and (
                firstdatetime.minute == 29 or firstdatetime.minute == 30
        ) and seconddatetime.hour == 13 and seconddatetime.minute == 30:
            return True
        elif self.yepan:
            if firstdatetime.hour == self.yepanhour and (
                    firstdatetime.minute == self.yepanminute
                    or firstdatetime.minute == self.yepanminute - 1
            ) and seconddatetime.hour == 9 and seconddatetime.miute == 0:
                return True
        else:
            return False

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

    def tickcelve(self, zhibiao, price, tick):
        for celve in self.tickCelvezu:
            xinhao = celve.celveOntick(zhibiao, self.lastzhibiao)
            if xinhao == 100:
                print(price, 'kaicangduo', tick.datetime)
            if xinhao == 50:
                print(price, 'pingcang', tick.datetime)
            if xinhao == 200:
                print(price, 'kongcang', tick.datetime)
            if xinhao == 250:
                print(price, 'pingkongcang', tick.datetime)
            self.chulikaipingcang(xinhao, price)
            # ----------------------------------------------------------------------

    def barcelve(self, zhibiao, price):
        for celve in self.barCelvezu:
            xinhao = celve.celveOnbar(zhibiao, self.lastzhibiao)
            if xinhao == 100:
                print('kaicangduo,bar')
            if xinhao == 50:
                print('pingcang,bar')
            self.chulikaipingcang(xinhao, price)

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

    def chulikaipingcang(self, celve, price):
        # if celve == 100:
        #     self.buy(price,1)
        selfpos = 0
        if celve != 0 and celve is not None:
            print('nowposis', self.pos, 'celveis', celve, 'andpriceis', price)
        if self.pos == 0 and celve == 100:
            if self.pos == 0:
                # self.weituopos = 1
                self.buy(price + 100, 1)
                # 如果有空头持仓,则先平空,再做多
            elif self.pos < selfpos:
                # self.weituopos = 1
                self.cover(price, 1)
                self.buy(price, 1)
        elif self.pos == 1 and celve == 50:
            if self.pos > selfpos:
                # self.weituopos = 0
                self.sell(price - 1, 1)
        elif self.pos == 0 and celve == 200:
            if self.pos == selfpos:
                # self.weituopos = -1
                print('iamkonging')
                self.short(price - 1, 1)
            elif self.pos > selfpos:
                self.sell(price, 1)
                self.short(price, 1)
                # self.weituopos = -1
        elif self.pos == -1 and celve == 250:
            # self.weituopos += 1
            self.cover(price + 100, 1)
        # ----------------------------------------------------------------------

    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'双EMA演示策略停止')
        self.putEvent()

    #----------------------------------------------------------------------
    def onTick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bg.updateTick(tick)
        zhibiao = self.am.updateTick(tick)
        if not self.tradecount:
            self.tickcelve(zhibiao, tick.lastPrice, tick)
        elif tick.datetime.second > 55:
            print('in tradecount', tick.datetime)
            self.tickcelve(zhibiao, tick.lastPrice, tick)

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        if bar.datetime.hour == 14 and bar.datetime.minute == 59:
            self.closeAllPosistion(bar.close)
        bartime = bar.datetime

        # 处理bar上的刚开仓
        self.handleTradeCount()

        if self.lastbardatetime is None:
            self.lastbardatetime = bar.datetime
        else:
            if not self.isTradeContinueTime(self.lastbardatetime,
                                            bar.datetime):
                #断网了,需要处理断网状态
                self.handleDisConnected(bar.close)
            #没有断网
            else:
                if self.stopcount > 0:
                    self.stopcount -= 1

        am = self.am
        am.updateBar(bar)
        self.bg.updateBar(bar)
        # if not am.inited:
        #     print('retr')
        # return
        # 计算快慢均线
        self.celve0.nowtime = bar.datetime
        diff, dea, macd = am.diff, am.dea, am.macd
        jisuan = zhibiao(diff, dea, macd)
        self.barcelve(jisuan, bar.close)

        # 金叉和死叉的条件是互斥
        # 所有的委托均以K线收盘价委托(这里有一个实盘中无法成交的风险,考虑添加对模拟市价单类型的支持)

        self.lastzhibiao = am.endBar()
        # print self.lastzhibiao.diff,self.lastzhibiao.dea
        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def handleTradeCount(self):
        if self.tradecount > 0:
            self.tradecount -= 1

    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        # 对于无需做细粒度委托控制的策略,可以忽略onOrder
        print 'order', order.price, order.direction, order.offset, order.orderTime
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        """收到成交推送(必须由用户继承实现)"""
        # 对于无需做细粒度委托控制的策略,可以忽略onOrder\
        if trade.direction == u'多' and trade.offset == u'开仓':
            #self.sell(trade.price - 4, 1, stop=True)
            self.tradecount = 5
            print('kaiduo')
        if trade.direction == u'空' and trade.offset == u'开仓':
            #self.cover(trade.price + 4, 1, stop=True)
            self.tradecount = 5
            print('kaikong')

        if trade.direction == u'多' and trade.offset != u'开仓':
            self.cancelAll()
            self.celve0.cangwei += trade.volume
            print('pingkong')
        if trade.direction == u'空' and trade.offset != u'开仓':
            self.cancelAll()
            self.celve0.cangwei -= trade.volume
            print('pingduo')

        print 'trade', trade.price, trade.direction, trade.offset, trade.tradeTime
        pass

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass

    def handleDisConnected(self, price):
        print('DISCONNECTED')
        self.closeAllPosistion(price)
        self.stopcount = 15
예제 #3
0
class DoubleMaStrategy(CtaTemplate):
    """双指数均线策略Demo"""
    className = 'DoubleMaStrategy'
    author = u'用Python的交易员'

    # 策略参数
    fastWindow = 12  # 快速均线参数
    slowWindow = 26  # 慢速均线参数
    initDays = 10  # 初始化数据所用的天数

    # 策略变量
    fastMa0 = EMPTY_FLOAT  # 当前最新的快速EMA
    fastMa1 = EMPTY_FLOAT  # 上一根的快速EMA

    slowMa0 = EMPTY_FLOAT
    slowMa1 = EMPTY_FLOAT

    # 参数列表,保存了参数的名称
    paramList = [
        'name', 'className', 'author', 'vtSymbol', 'fastWindow', 'slowWindow'
    ]

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'fastMa0', 'fastMa1', 'slowMa0', 'slowMa1'
    ]

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

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(DoubleMaStrategy, self).__init__(ctaEngine, setting)

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

    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略(必须由用户继承实现)"""
        self.writeCtaLog(u'双EMA演示策略初始化')

        initData = self.loadBar(self.initDays)
        for bar in initData:
            self.onBar(bar)

        self.putEvent()

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

    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略(必须由用户继承实现)"""
        self.writeCtaLog(u'双EMA演示策略停止')
        self.putEvent()

    #----------------------------------------------------------------------
    def tickcelve(self, zhibiao):
        for celve in self.tickCelvezu:
            self.chulikaipingcang(celve.celveOntick(zhibiao, self.lastzhibiao),
                                  tick)

    def barcelve(self, zhibiao):
        for celve in self.barCelvezu:
            self.chulikaipingcang(celve.celveOnbar(zhibiao, self.lastzhibiao),
                                  None, bar)

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

    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        am = self.am
        am.updateBar(bar)
        if not am.inited:
            return
        print 'neverinited'
        # 计算快慢均线
        zhibiao = zhibiao(am.MACD(12, 26, 9))
        self.barcelve(zhibiao)

        # 金叉和死叉的条件是互斥
        # 所有的委托均以K线收盘价委托(这里有一个实盘中无法成交的风险,考虑添加对模拟市价单类型的支持)

        self.lastzhibiao = am.endBar()
        # 发出状态更新事件
        self.putEvent()

    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        # 对于无需做细粒度委托控制的策略,可以忽略onOrder
        pass

    #----------------------------------------------------------------------
    def onTrade(self, trade):
        """收到成交推送(必须由用户继承实现)"""
        # 对于无需做细粒度委托控制的策略,可以忽略onOrder
        pass

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        pass