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
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
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