class MyBollingDayStrategy(CtaTemplate): """基于布林通道的交易策略""" className = 'MyBollingDayStrategy' author = 'yuanhui' # 策略参数 #bollWindow = 26 # 通道窗口数 entryDev = 2 # 开仓偏差 bollWindow5min = 26 # 通道窗口数 entryDev5min = 2 # 开仓偏差 bollWindow15min = 26 # 通道窗口数 entryDev15min = 2 # 开仓偏差 bollWindow30min = 52 # 通道窗口数 entryDev30min = 2 # 开仓偏差 bollWindowDay = 26 # 通道窗口数 entryDevDay = 2 # 开仓偏差 #exitDev = 1.2 # 平仓偏差 #trailingPrcnt = 0.4 # 移动止损百分比 #maWindow = 10 # 过滤用均线窗口 initDays = 33 # 初始化数据所用的天数 fixedSize = 1 # 每次交易的数量 priceTick = 0.2 # 价格最小变动 DayTrendStatus='panzhen' #DuoTou, KongTou,Panzheng FifteenMinTrendStatus='panzhen' FiveMinTrendStatus='panzhen' ThirtyMinTrendStatus='panzhen' # 5Min策略变量 bollMid = 0 # 布林带中轨 BeforebollMid=0 #上一根K线的布林线中轨 #bollStd = 0 # 布林带宽度 bollUp = 0 # 开仓上轨 Beforebollup=0 #上一根K线的布林线上轨 bollDown = 0 # 平仓下轨 beforebolldown=0 #上一根K线的布林线下轨 # 15Min策略变量 bollMid15 = 0 # 布林带中轨 BeforebollMid15=0 #上一根K线的布林线中轨 #bollStd15 = 0 # 布林带宽度 bollUp15 = 0 # 开仓上轨 Beforebollup15=0 #上一根K线的布林线上轨 bollDown15 = 0 # 平仓下轨 beforebolldown15=0 #上一根K线的布林线下轨 # 30Min策略变量 bollMid30 = 0 # 布林带中轨 BeforebollMid30=0 #上一根K线的布林线中轨 #bollStd30 = 0 # 布林带宽度 bollUp30 = 0 # 开仓上轨 Beforebollup30=0 #上一根K线的布林线上轨 bollDown30 = 0 # 平仓下轨 beforebolldown30=0 #上一根K线的布林线下轨 # 日线策略变量 bollMidDay = 0 # 布林带中轨 BeforebollMidDay=0 #上一根K线的布林线中轨 #bollStd30 = 0 # 布林带宽度 bollUpDay = 0 # 开仓上轨 BeforebollupDay=0 #上一根K线的布林线上轨 bollDownDay= 0 # 平仓下轨 beforebolldownDay=0 #上一根K线的布林线下轨 #maFilter = 0 # 均线过滤 #maFilter1 = 0 # 上一期均线 intraTradeHigh = 0 # 持仓期内的最高点 longEntry = 0 #多头开仓位置 longExit = 0 #多头平仓位置 shortEntry=0 #空头开仓位置 shortExit=0 #空头平仓位置 #上一个交易单子保本否 lastTrade_baoben=False deal=0 # 多头平仓为正,空头平仓为 dealopen=0 # 多头开仓正,空头开仓负 orderList = [] # 保存委托代码的列表 tradedata=[] posdata=[] #仓位信息,每次开仓成功后把trade信息加入List,平仓后删除 tradedata_boll=[] #所有的需要在布林线止损的交易单 tradedata_baoben=[] #所有的已经过了保本线的交易单 tradedata_day=[] #日线级别交易单 zhishunpercent=0.005 #每笔止损百分比 # 参数列表,保存了参数的名称 parameters = [ 'bollWindowDay', 'entryDevDay', 'fixedSize', 'DayTrendStatus' ] # 变量列表,保存了变量的名称 variables = ['inited', 'trading', 'pos', 'bollUp', 'bollDown', 'bollUp15', 'bollDown15', 'bollUp30', 'bollDown30', 'FifteenMinTrendStatus', 'FiveMinTrendStatus', 'ThirtyMinTrendStatus' ] # 同步列表 syncList = ['pos', 'intraTradeHigh'] #---------------------------------------------------------------------- def __init__(self, ctaEngine, strategy_name, vt_symbol, setting): """Constructor""" #super(MyBollingerBotStrategy, self).__init__(ctaEngine, setting) super().__init__(ctaEngine, strategy_name, vt_symbol, setting) self.bm5 = BarGenerator(self.on_bar, 5, self.on_5Min_bar) self.am5 = ArrayManager(80) self.bm15 = BarGenerator(self.on_bar, 15, self.on_15Min_bar) self.am15 = ArrayManager(80) self.bm30 = BarGenerator(self.on_bar, 30, self.on_30Min_bar) self.am30 = ArrayManager(80) #self.bmDay = BarGenerator(self.on_bar, 6, self.onDayBar,Interval.HOUR) self.bmDay = BarGenerator(self.on_bar, 1, self.onDayBar,Interval.DAILY) self.amDay = ArrayManager(30) head=["datetime","BollStatus","open","close","high","low","pos","pDown","pMiddle","pUp","dealOpen"] current_path =os.getcwd()# os.path.abspath(__file__) write_csv_file(current_path+"\\datasig5.csv",head,None,"w") write_csv_file(current_path+"\\datasig15.csv",head,None,"w") write_csv_file(current_path+"\\datasig30.csv",head,None,"w") write_csv_file(current_path+"\\datasigDay.csv",head,None,"w") head=["datetime","orderid","tradeid","direction","offset","price","volume"] write_csv_file(current_path+"\\datasigTrade.csv",head,None,"w") head=["datetime","orderid","tradeid","direction","offset","price","volume","baoben"] write_csv_file(current_path+"\\datasigPos.csv",head,None,"w") print("self.cta_engine.capital %d",self.cta_engine.capital) #---------------------------------------------------------------------- def caculate_pos(self,zhishun:float): pos=0 pos=int(self.cta_engine.capital*self.zhishunpercent//zhishun) return pos def on_init(self): """初始化策略(必须由用户继承实现)""" self.write_log(u'%s策略初始化' %self.className) # 载入历史数据,并采用回放计算的方式初始化策略数值 initData = self.load_bar(self.initDays) #for bar in initData: # self.onBar(bar) #self.put_event() #---------------------------------------------------------------------- def on_start(self): """启动策略(必须由用户继承实现)""" self.write_log(u'%s策略启动' %self.className) self.put_event() #---------------------------------------------------------------------- def on_stop(self): """停止策略(必须由用户继承实现)""" self.write_log(u'%s策略停止' %self.className) self.put_event() #---------------------------------------------------------------------- def on_tick(self, tick): """收到行情TICK推送(必须由用户继承实现)""" self.bm5.updateTick(tick) #---------------------------------------------------------------------- def on_bar(self, bar: BarData): """收到Bar推送(必须由用户继承实现)""" #早盘开盘前一分钟收到的多余的tick的清除 if "09:29:00" in bar.datetime.strftime("%Y-%m-%d %H:%M:%S") and "IF" in bar.symbol: return if "08:59:00" in bar.datetime.strftime("%Y-%m-%d %H:%M:%S"): return #s基于日线判断趋势过滤,因此先更新 self.bmDay.update_bar(bar) #s基于30分钟更新 self.bm30.update_bar(bar) # 基于15分钟更新 self.bm15.update_bar(bar) # 基于5分钟更新 self.bm5.update_bar(bar) ''' if self.amDay.inited: self.onDayBar(bar) return else: self.amDay.update_bar(bar) return ''' #判断当前5Min布林线趋势状态 if not self.am5.inited or not self.am15.inited or not self.am30.inited or not self.amDay.inited: return if self.bm5.window_bar !=None: if self.bm5.window_bar.high_price > self.bollUp and self.bm5.window_bar.low_price > self.bollMid: self.FiveMinTrendStatus='duotou' elif self.bm5.window_bar.low_price < self.bollDown and self.bm5.window_bar.high_price < self.bollMid: self.FiveMinTrendStatus='kongtou' elif self.bm5.window_bar.low_price < self.bollMid and self.FiveMinTrendStatus=='duotou': self.FiveMinTrendStatus='panzhen' elif self.bm5.window_bar.high_price > self.bollMid and self.FiveMinTrendStatus=='kongtou': self.FiveMinTrendStatus='panzhen' #判断当前15Min布林线趋势状态 if self.bm15.window_bar!=None: if self.bm15.window_bar.high_price > self.bollUp15 and self.bm15.window_bar.low_price > self.bollMid15: self.FifteenMinTrendStatus='duotou' elif self.bm15.window_bar.low_price < self.bollDown15 and self.bm15.window_bar.high_price < self.bollMid15: self.FifteenMinTrendStatus='kongtou' elif self.bm15.window_bar.low_price < self.bollMid15 and self.FifteenMinTrendStatus=='duotou': self.FifteenMinTrendStatus='panzhen' elif self.bm15.window_bar.high_price > self.bollMid15 and self.FifteenMinTrendStatus=='kongtou': self.FifteenMinTrendStatus='panzhen' #判断当前30Min布林线趋势状态 if self.bm30.window_bar!=None: if self.bm30.window_bar.high_price > self.bollUp30 and self.bm30.window_bar.low_price > self.bollMid30: self.ThirtyMinTrendStatus='duotou' elif self.bm30.window_bar.low_price < self.bollDown30 and self.bm30.window_bar.high_price < self.bollMid30: self.ThirtyMinTrendStatus='kongtou' elif self.bm30.window_bar.low_price < self.bollMid30 and self.ThirtyMinTrendStatus=='duotou': self.ThirtyMinTrendStatus='panzhen' elif self.bm30.window_bar.high_price > self.bollMid30 and self.ThirtyMinTrendStatus=='kongtou': self.ThirtyMinTrendStatus='panzhen' #判断当前日线布林线趋势状态 if self.bmDay.window_bar!=None: if self.bmDay.window_bar.high_price > self.bollUpDay and self.bmDay.window_bar.low_price > self.bollMidDay: self.DayTrendStatus='duotou' elif self.bmDay.window_bar.low_price < self.bollDownDay and self.bmDay.window_bar.high_price < self.bollMidDay: self.DayTrendStatus='kongtou' elif self.bmDay.window_bar.low_price < self.bollMidDay and self.DayTrendStatus=='duotou': self.DayTrendStatus='panzhen' elif self.bmDay.window_bar.high_price > self.bollMidDay and self.DayTrendStatus=='kongtou': self.DayTrendStatus='panzhen' ''' if self.pos == 0: #self.intraTradeHigh = bar.high orderList=[] if self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='duotou' and self.FiveMinTrendStatus=='duotou': #self.longEntry = bar.close self.cancelAll() orderList=self.buy(bar.close+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,1分钟收盘价开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='kongtou' and self.FiveMinTrendStatus=='kongtou': #self.shortEntry = bar.close self.cancelAll() orderList=self.short( bar.close-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,1分钟收盘价开仓"%self.__dict__["name"]) ''' #print (u'策略:',self.__dict__["name"]) #print (u"策略:%s,时间:%s,1分钟刷新,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s"%(self.__dict__["name"],bar.datetime,self.FiveMinTrendStatus,self.FifteenMinTrendStatus,self.ThirtyMinTrendStatus,self.DayTrendStatus)) self.put_event() #---------------------------------------------------------------------- def on_5Min_bar(self, bar: BarData): """收到5分钟K线""" if not self.am5.inited or not self.am15.inited or not self.am30.inited or not self.amDay.inited: self.am5.update_bar(bar) return #计算上一个k线的布林中轨,上轨,下轨 self.BeforebollMid=self.am5.sma(self.bollWindow5min) self.Beforebollup,self.beforebolldown=self.am5.boll(self.bollWindow5min,self.entryDev5min) # 保存K线数据 self.am5.update_bar(bar) # 撤销之前发出的尚未成交的委托(包括限价单和停止单) #self.cancel_all() orderList=[] # 计算指标数值 self.bollMid = self.am5.sma(self.bollWindow5min) self.bollUp,self.bollDown = self.am5.boll(self.bollWindow5min,self.entryDev5min) #判断当前5Min布林线趋势状态 if bar.high_price > self.Beforebollup and bar.low_price > self.BeforebollMid: self.FiveMinTrendStatus='duotou' elif bar.low_price < self.beforebolldown and bar.high_price < self.BeforebollMid: self.FiveMinTrendStatus='kongtou' elif bar.low_price < self.BeforebollMid and self.FiveMinTrendStatus=='duotou': self.FiveMinTrendStatus='panzhen' elif bar.high_price > self.BeforebollMid and self.FiveMinTrendStatus=='kongtou': self.FiveMinTrendStatus='panzhen' ''' if bar.high > self.bollMid15 and self.FifteenMinTrendStatus == 'kongtou': self.FifteenMinTrendStatus=='panzhen' if bar.low < self.bollMid15 and self.FifteenMinTrendStatus == 'duotou': self.FifteenMinTrendStatus=='panzhen' ''' # 判断是否要进行交易 #print (u"策略:%s,5分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s"%(self.className,self.FiveMinTrendStatus,self.FifteenMinTrendStatus,self.ThirtyMinTrendStatus,self.DayTrendStatus)) # 当前无仓位,发送OCO开仓委托 ''' if self.pos == 0: #self.intraTradeHigh = bar.high #多头处理 if self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus!='duotou' : orderList=self.buy(self.bollUp15+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,15分钟上轨开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus=="panzhen" : orderList=self.buy(self.bollUp30+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,30分钟上轨开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='duotou' and self.FiveMinTrendStatus=='duotou': self.longEntry = bar.close orderList=self.buy(self.longEntry+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,5分钟收盘价开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='duotou' and self.FiveMinTrendStatus!='duotou': self.longEntry=self.bollUp orderList=self.buy(self.longEntry+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,5分钟上轨开仓"%self.__dict__["name"]) #空头处理 elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus!='kongtou' : orderList=self.short(self.bollDown15-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,15分钟下轨开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus=="panzhen" : orderList=self.short(self.bollDown30-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,30分钟下轨开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='kongtou' and self.FiveMinTrendStatus=='kongtou': self.shortEntry = bar.close orderList=self.short(self.shortEntry-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,5分钟收盘价开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='kongtou' and self.FiveMinTrendStatus!='kongtou': self.shortEntry=self.bollDown orderList=self.short(self.shortEntry-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,5分钟下轨开仓"%self.__dict__["name"]) # 持有多头仓位 elif self.pos > 0: orderList=self.sell(self.bollDown-self.priceTick, abs(self.pos), True) print (u"策略:%s,委托止损单,5分钟下轨平仓"%self.__dict__["name"]) # 持有空头仓位 elif self.pos < 0: orderList=self.cover(self.bollUp+self.priceTick, abs(self.pos), True) print (u"策略:%s,委托止损单,5分钟上轨平仓"%self.__dict__["name"]) with open("datasig5.csv","ab+",) as csvfile: writer = csv.writer(csvfile) writer.writerow([bar.datetime,bar.open, bar.close, bar.high, bar.low,bar.openInterest,bar.volume,self.deal,self.bollDown,self.bollUp,self.dealopen]) self.deal=0 self.dealopen=0 if orderList: print (u"策略:%s,委托单成功,单号%s"%(self.__dict__["name"],orderList[-1])) #else: # print u"策略:%s,委托单失败"%self.__dict__["name"] # 发出状态更新事件 ''' self.put_event() def on_15Min_bar(self, bar: BarData): """15分钟K线推送""" if not self.am15.inited or not self.am30.inited or not self.amDay.inited: self.am15.update_bar(bar) return #计算上一个k线的布林中轨,上轨,下轨 self.BeforebollMid15=self.am15.sma(self.bollWindow15min) self.Beforebollup15,self.beforebolldown15=self.am15.boll(self.bollWindow15min,self.entryDev15min) self.am15.update_bar(bar) # 计算指标数值 self.bollMid15 = self.am15.sma(self.bollWindow15min) self.bollUp15,self.bollDown15 = self.am15.boll(self.bollWindow15min,self.entryDev15min) #判断当前15Min布林线趋势状态 if bar.high_price > self.Beforebollup15 and bar.low_price > self.BeforebollMid15: self.FifteenMinTrendStatus='duotou' elif bar.low_price < self.beforebolldown15 and bar.high_price < self.BeforebollMid15: self.FifteenMinTrendStatus='kongtou' elif bar.low_price < self.BeforebollMid15 and self.FifteenMinTrendStatus=='duotou': self.FifteenMinTrendStatus='panzhen' elif bar.high_price > self.BeforebollMid15 and self.FifteenMinTrendStatus=='kongtou': self.FifteenMinTrendStatus='panzhen' #with open("datasig15.csv","ab+",) as csvfile: # writer = csv.writer(csvfile) #writer.writerow([bar.datetime,bar.open_price, bar.close_price, bar.high_price, bar.low_price,bar.open_interest,bar.volume,self.deal,self.bollDown15,self.bollUp15,self.dealopen]) #print (u"策略:%s,15分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s"%(self.className,self.FiveMinTrendStatus,self.FifteenMinTrendStatus,self.ThirtyMinTrendStatus,self.DayTrendStatus)) #print u"15分钟收盘价",self.am15.closeArray[75:] # 当前无仓位,发送OCO开仓委托 ''' if self.pos == 0: self.intraTradeHigh = bar.high if self.FifteenMinTrendStatus=='panzhen': self.longEntry = self.bollUp15 self.shortEntry=self.booldown15 self.buy(self.longEntry, self.fixedSize, True) self.short(self.shortEntry,self.fixedSize,True) ''' # 发出状态更新事件 self.put_event() def on_30Min_bar(self, bar: BarData): """30分钟K线推送""" if not self.am30.inited or not self.amDay.inited: self.am30.update_bar(bar) return #计算上一个k线的布林中轨,上轨,下轨 self.BeforebollMid30=self.am30.sma(self.bollWindow30min) self.Beforebollup30,self.beforebolldown30=self.am30.boll(self.bollWindow30min,self.entryDev30min) self.am30.update_bar(bar) # 计算指标数值 self.bollMid30 = self.am30.sma(self.bollWindow30min) self.bollUp30,self.bollDown30 = self.am30.boll(self.bollWindow30min,self.entryDev30min) #判断当前30Min布林线趋势状态 if bar.high_price > self.Beforebollup30 and bar.low_price > self.BeforebollMid30: self.ThirtyMinTrendStatus='duotou' elif bar.low_price < self.beforebolldown30 and bar.high_price < self.BeforebollMid30: self.ThirtyMinTrendStatus='kongtou' elif bar.low_price < self.BeforebollMid30 and self.ThirtyMinTrendStatus=='duotou': self.ThirtyMinTrendStatus='panzhen' elif bar.high_price > self.BeforebollMid30 and self.ThirtyMinTrendStatus=='kongtou': self.ThirtyMinTrendStatus='panzhen' ''' self.cancel_all() #开平仓位置 self.intraTradeHigh = bar.high_price self.longEntry = self.bollUp30+self.priceTick self.longExit=self.bollDown30-self.priceTick self.shortEntry=self.bollDown30-self.priceTick self.shortExit=self.bollUp30+self.priceTick zhishun=self.bollUp30-self.bollDown30 volume=self.caculate_pos(zhishun) #volume=self.fixedSize #pos=self.posdata[-1] if (self.pos==0 and len(self.posdata)>0) or (not self.pos==0 and len(self.posdata)==0): print(u"仓位self.pos和仓位列表self.posdata不匹配") import sys sys.exit(1) if self.pos==0: #无仓位 if self.ThirtyMinTrendStatus=='panzhen' and self.DayTrendStatus=='duotou': self.buy(self.longEntry, volume, True) elif self.ThirtyMinTrendStatus=='panzhen' and self.DayTrendStatus=='kongtou': self.short(self.shortEntry,volume,True) else: #有仓位 #最后一个单子为开仓单,判断是否保本了 trade=self.tradedata[-1] if trade.offset==Offset.OPEN: if ( self.bollDown30 >trade.price and trade.direction==Direction.LONG) or (self.bollUp30 <trade.price and trade.direction==Direction.SHORT): self.lastTrade_baoben=True self.posdata[-1].baoben=True if trade.offset==Offset.CLOSE or self.lastTrade_baoben==True: #最后一个交易为平仓单,发送开仓单在布林线上下轨 if self.ThirtyMinTrendStatus=='panzhen' and self.DayTrendStatus=='duotou': self.buy(self.longEntry, volume, True) elif self.ThirtyMinTrendStatus=='panzhen' and self.DayTrendStatus=='kongtou': self.short(self.shortEntry,volume,True) #需要在布林线上下轨止损的单子,重新发出止损单子 # 最后一笔交易为多头仓位,没有保本,在下轨止损 elif trade.offset==Offset.OPEN and (trade.direction==Direction.LONG and self.posdata[-1].baoben==False): orderList=self.sell(max(self.longExit,self.bollMidDay), trade.volume, True) #print (u"策略:%s,委托止损单,30分钟下轨平仓"%self.className) # 最后一笔交易为空头仓位,没有保本,在上轨止损 elif trade.offset==Offset.OPEN and (trade.direction==Direction.SHORT and self.posdata[-1].baoben==False): orderList=self.cover(min(self.bollMidDay,self.shortExit), trade.volume, True) #print (u"策略:%s,委托止损单,30分钟上轨平仓"%self.className) #需要在保本位置设置止损的交易单,重新发出止损单子 #if self.lastTrade_baoben==True: i=0 while i <len(self.posdata): volume=self.posdata[i].volume if self.posdata[i].baoben==True: if self.posdata[i].direction==Direction.LONG: orderList=self.sell(max(self.posdata[i].price,self.bollMidDay), volume, True) #print (u"策略:%s,委托止损单,保本价格平仓"%self.className) elif self.posdata[i].direction==Direction.SHORT: orderList=self.cover(min(self.posdata[i].price,self.bollMidDay), volume, True) #print (u"策略:%s,委托止损单,保本价格平仓"%self.className) i=i+1 #需要在日线中轨止损的单子,需要在新的日线中轨处发出止损单 current_path =os.getcwd()# os.path.abspath(__file__) bardata=[bar.datetime,self.ThirtyMinTrendStatus,bar.open_price, bar.close_price, bar.high_price, bar.low_price,bar.open_interest,bar.volume,self.pos,self.bollDown30,self.bollUp30,self.dealopen] write_csv_file(current_path+"\\datasig30.csv",None,bardata,"a+") #print(u"时间:",bar.datetime) #print (u"策略:%s,30分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s"%(self.className,self.FiveMinTrendStatus,self.FifteenMinTrendStatus,self.ThirtyMinTrendStatus,self.DayTrendStatus)) #print (u"30分钟收盘价",self.am30.close_array[60:]) ''' # 发出状态更新事件 self.put_event() def onDayBar(self, bar: BarData): """日K线推送""" t1=str(bar.datetime) t2=str(datetime(2016,1,28,21,0,0)) if t2 in t1: i=0 if not self.amDay.inited: self.amDay.update_bar(bar) return #计算上一个k线的布林中轨,上轨,下轨 self.BeforebollMidDay=self.amDay.sma(self.bollWindowDay) self.BeforebollupDay,self.beforebolldownDay=self.amDay.boll(self.bollWindowDay,self.entryDevDay) self.amDay.update_bar(bar) # 计算指标数值 self.bollMidDay = self.amDay.sma(self.bollWindowDay) self.bollUpDay,self.bollDownDay = self.amDay.boll(self.bollWindowDay,self.entryDevDay) #判断当前日线布林线趋势状态 if bar.high_price > self.BeforebollupDay and bar.low_price > self.BeforebollMidDay: self.DayTrendStatus='duotou' elif bar.low_price < self.beforebolldownDay and bar.high_price < self.BeforebollMidDay: self.DayTrendStatus='kongtou' elif bar.low_price < self.BeforebollMidDay and self.DayTrendStatus=='duotou': self.DayTrendStatus='panzhen' elif bar.high_price > self.BeforebollMidDay and self.DayTrendStatus=='kongtou': self.DayTrendStatus='panzhen' ''' if (self.pos==0 and len(self.tradedata_day)>0) or ( self.pos!=0 and len(self.tradedata_day)==0): print(u"仓位self.pos和仓位列表self.tradedata_day") import sys sys.exit(1) ''' self.intraTradeHigh = bar.high_price self.longEntry = self.bollUpDay+self.priceTick self.longExit=self.bollMidDay-self.priceTick self.shortEntry=self.bollDownDay-self.priceTick self.shortExit=self.bollMidDay+self.priceTick #需要在日线中轨止损的单子,需要在新的日线中轨处发出止损单 self.cancel_all() #if len(self.tradedata_day)>0: if self.pos!=0: if self.pos>0: orderList=self.sell(self.longExit, self.pos, True) print (u"策略:%s,委托止损单,日线中轨平仓"%self.className) else: orderList=self.cover(self.shortExit, abs(self.pos), True) print (u"策略:%s,委托止损单,日线中轨平仓"%self.className) ''' i=0 volume=0 while i <len(self.tradedata_day): volume=self.tradedata_day[i].volume if self.tradedata_day[i].direction==Direction.LONG: orderList=self.sell(self.longExit, volume, True) print (u"策略:%s,委托止损单,日线中轨平仓"%self.className) elif self.tradedata_day[i].direction==Direction.SHORT: orderList=self.cover(self.shortExit, volume, True) print (u"策略:%s,委托止损单,日线中轨平仓"%self.className) i=i+1 ''' zhishun=(self.bollUpDay-self.bollDownDay)/2 volume=self.caculate_pos(zhishun) #日线盘整,上下轨开仓 if self.DayTrendStatus=="panzhen" and self.pos==0 and volume!=0:#len(self.tradedata_day)==0: self.cancel_all() orderList=[] orderList=self.buy(self.bollUpDay+self.priceTick, volume, True) print (u"策略:%s,委托多单,日线上轨开仓"%self.className) if orderList: print (u"策略:%s,委托单成功,单号%s"%(self.className,orderList[-1])) else: print (u"策略:%s,委托单失败"%self.className) orderList=[] orderList=self.short(self.bollDownDay-self.priceTick, volume, True) print (u"策略:%s,委托空单,日线下轨开仓"%self.className) if orderList: print (u"策略:%s,委托单成功,单号%s"%(self.className,orderList[-1])) else: print (u"策略:%s,委托单失败"%self.className ) bardata=[bar.datetime,self.DayTrendStatus,bar.open_price, bar.close_price, bar.high_price, bar.low_price,self.pos,int(self.bollDownDay),int(self.bollMidDay),int(self.bollUpDay),self.dealopen] write_csv_file(os.getcwd()+"\\datasigDay.csv",None,bardata,"a+") print(u"日线刷新---------------") print(u"时间(日线刷新):",bar.datetime) print (u"策略:%s,日线刷新,趋势状态,日线趋势%s,15分钟趋势%s,30分钟趋势%s,5分钟趋势%s"%(self.className,self.DayTrendStatus,self.FifteenMinTrendStatus,self.ThirtyMinTrendStatus,self.FiveMinTrendStatus)) #print (u"日线开盘价",self.amDay.open_array[1:]) #print (u"日线收盘价",self.amDay.close_array[1:]) #print(u"日线刷新---------------") # 发出状态更新事件 self.put_event() #---------------------------------------------------------------------- def on_order(self, order): """收到委托变化推送(必须由用户继承实现)""" if order.offset==Offset.CLOSE: print("new order") pass #---------------------------------------------------------------------- def on_trade(self, trade): #打印信息 print(u"成交单刷新---------------") print(u"时间(日线刷新):",trade.datetime) print ("策略:%s,趋势状态,日线趋势%s,15分钟趋势%s,30分钟趋势%s,5分钟趋势%s"%(self.className,self.DayTrendStatus,self.FifteenMinTrendStatus,self.ThirtyMinTrendStatus,self.FiveMinTrendStatus)) print (u"策略:%s, 委托单成交"%self.className) print (trade.direction) print (trade.offset) #print "15min:",self.FifteenMinTrendStatus #print "5min:",self.FiveMinTrendStatus current_path =os.getcwd()# os.path.abspath(__file__) #head=["datetime","orderid","tradeid","direction","offset","price","volume"] #所有交易单保存下来 self.tradedata.append(trade) #开仓成功加入仓位list,平仓成功,删除最后加仓的仓位 self.cancel_all() if trade.offset==Offset.OPEN: self.tradedata_day.append(trade) self.tradedata_day[-1].baoben==False self.lastTrade_baoben=False if trade.offset==Offset.CLOSE: #self.cancel_all() if len(self.tradedata_day)>0: self.tradedata_day.pop() if len(self.posdata)>=1: #这一单平仓后,仓位list中还有仓位,说明上一个仓位是已经保本的仓位i self.lastTrade_baoben=True else: #清空 head=["datetime","orderid","tradeid","direction","offset","price","volume","baoben"] write_csv_file(current_path+"\\datasigPos.csv",head,None,"w") ''' #成交单是保本的平仓单需要,判断标准一,这次和上次都是平仓单 if self.tradedata[-1].offset==Offset.CLOSE and self.tradedata[-2].offset==offset.CLOSE: self.tradedata_baoben.pop #成交单是保本的平仓单,判断标准二,这次是平仓单,上次是开仓单,同时保本表示为True if (self.tradedata[-1].offset==Offset.CLOSE and self.tradedata[-2].offset==offset.OPEN) and self.lastTrade_baoben==True: self.tradedata_baoben.pop ''' #保存到文件 tradedata=[trade.datetime,trade.orderid,trade.tradeid,trade.direction,trade.offset,trade.price,trade.volume] write_csv_file(current_path+"\\datasigTrade.csv",None,tradedata,"a+") #写入仓位保存文件 head=["datetime","orderid","tradeid","direction","offset","price","volume","baoben"] # write_csv_file(current_path+"datasigPos.csv",head,None,"w") i=0 while i <len(self.posdata): posdata=[self.posdata[i].datetime,self.posdata[i].orderid,self.posdata[i].tradeid,self.posdata[i].direction,self.posdata[i].offset,self.posdata[i].price,self.posdata[i].volume,self.posdata[i].baoben] if i==0: write_csv_file(current_path+"\\datasigPos.csv",head,None,"w") #开仓成功后先取消掉还有的挂单,主要针对的是日线的双向挂单 write_csv_file(current_path+"\\datasigPos.csv",None,posdata,"a+") i=i+1 #if self.pos!=0: # self.cancel_all() # 发出状态更新事件 orderList=[] if trade.offset==Offset.OPEN and trade.direction==Direction.LONG: #多头成交,设置止损单 orderList=self.sell(self.bollMidDay-self.priceTick, trade.volume, True) print (u"委托止损单,日线中轨平仓") if orderList: print( u"委托单成功单号",orderList) else : print (u"委托单失败") elif trade.offset==Offset.OPEN and trade.direction==Direction.SHORT: #空头成交,设置止损单 orderList=self.cover(self.bollMidDay+self.priceTick, trade.volume, True) print (u"委托止损单,日线中轨平仓") if orderList: print( u"委托单成功单号",orderList) else : print (u"委托单失败") elif trade.offset==Offset.CLOSE: zhishun=(self.bollUpDay-self.bollDownDay)/2 volume=self.caculate_pos(zhishun) #日线盘整,上下轨开仓 if self.pos==0 and volume!=0:#len(self.tradedata_day)==0: self.cancel_all() orderList=[] orderList=self.buy(self.bollUpDay+self.priceTick, volume, True) print (u"策略:%s,委托多单,日线上轨开仓"%self.className) if orderList: print (u"策略:%s,委托单成功,单号%s"%(self.className,orderList[-1])) else: print (u"策略:%s,委托单失败"%self.className) orderList=[] orderList=self.short(self.bollDownDay-self.priceTick, volume, True) print (u"策略:%s,委托空单,日线下轨开仓"%self.className) if orderList: print (u"策略:%s,委托单成功,单号%s"%(self.className,orderList[-1])) else: print (u"策略:%s,委托单失败"%self.className ) #更新周期状态 if trade.offset==Offset.OPEN: if trade.direction==Direction.LONG: self.dealopen=1 self.DayTrendStatus="duotou" self.FifteenMinTrendStatus='duotou' self.FiveMinTrendStatus='duotou' self.ThirtyMinTrendStatus='duotou' else: self.dealopen=-1 self.DayTrendStatus="kongtou" self.FifteenMinTrendStatus='kongtou' self.FiveMinTrendStatus='kongtou' self.ThirtyMinTrendStatus='kongtou' if trade.offset==Offset.CLOSE: if trade.direction==Direction.LONG: self.ThirtyMinTrendStatus='kongtou' self.DayTrendStatus="panzhen" self.deal=1 else: self.deal=-1 self.put_event() #---------------------------------------------------------------------- def on_stop_order(self, so): """停止单推送""" pass
class MyBollingStrategy(CtaTemplate): """基于布林通道的交易策略""" className = 'MyBollingerBotStrategy' author = 'yuanhui' # 策略参数 #bollWindow = 26 # 通道窗口数 entryDev = 2 # 开仓偏差 bollWindow5min = 26 # 通道窗口数 entryDev5min = 2 # 开仓偏差 bollWindow15min = 26 # 通道窗口数 entryDev15min = 2 # 开仓偏差 bollWindow30min = 52 # 通道窗口数 entryDev30min = 2 # 开仓偏差 bollWindowDay = 26 # 通道窗口数 entryDevDay = 2 # 开仓偏差 #exitDev = 1.2 # 平仓偏差 #trailingPrcnt = 0.4 # 移动止损百分比 #maWindow = 10 # 过滤用均线窗口 initDays = 15 # 初始化数据所用的天数 fixedSize = 1 # 每次交易的数量 priceTick = 0.2 # 价格最小变动 DayTrendStatus = 'panzhen' #DuoTou, KongTou,Panzheng FifteenMinTrendStatus = 'panzhen' FiveMinTrendStatus = 'panzhen' ThirtyMinTrendStatus = 'panzhen' # 5Min策略变量 bollMid = 0 # 布林带中轨 BeforebollMid = 0 #上一根K线的布林线中轨 #bollStd = 0 # 布林带宽度 bollUp = 0 # 开仓上轨 Beforebollup = 0 #上一根K线的布林线上轨 bollDown = 0 # 平仓下轨 beforebolldown = 0 #上一根K线的布林线下轨 # 15Min策略变量 bollMid15 = 0 # 布林带中轨 BeforebollMid15 = 0 #上一根K线的布林线中轨 #bollStd15 = 0 # 布林带宽度 bollUp15 = 0 # 开仓上轨 Beforebollup15 = 0 #上一根K线的布林线上轨 bollDown15 = 0 # 平仓下轨 beforebolldown15 = 0 #上一根K线的布林线下轨 # 30Min策略变量 bollMid30 = 0 # 布林带中轨 BeforebollMid30 = 0 #上一根K线的布林线中轨 #bollStd30 = 0 # 布林带宽度 bollUp30 = 0 # 开仓上轨 Beforebollup30 = 0 #上一根K线的布林线上轨 bollDown30 = 0 # 平仓下轨 beforebolldown30 = 0 #上一根K线的布林线下轨 # 日线策略变量 bollMidDay = 0 # 布林带中轨 BeforebollMidDay = 0 #上一根K线的布林线中轨 #bollStd30 = 0 # 布林带宽度 bollUpDay = 0 # 开仓上轨 BeforebollupDay = 0 #上一根K线的布林线上轨 bollDownDay = 0 # 平仓下轨 beforebolldownDay = 0 #上一根K线的布林线下轨 #maFilter = 0 # 均线过滤 #maFilter1 = 0 # 上一期均线 intraTradeHigh = 0 # 持仓期内的最高点 longEntry = 0 #多头开仓位置 longExit = 0 #多头平仓位置 shortEntry = 0 #空头开仓位置 shortExit = 0 #空头平仓位置 #上一个交易单子保本否 lastTrade_baoben = False deal = 0 # 多头平仓为正,空头平仓为 dealopen = 0 # 多头开仓正,空头开仓负 orderList = [] # 保存委托代码的列表 tradedata = [] tradedata_boll = [] #所有的需要在布林线止损的交易单 tradedata_baoben = [] #所有的已经过了保本线的交易单 tradedata_day = [] #所有的需要在日线布林中轨止损的交易单 # 参数列表,保存了参数的名称 parameters = [ 'bollWindow5min', 'bollWindow15min', 'bollWindow30min', 'entryDev', 'initDays', 'fixedSize', 'DayTrendStatus' ] # 变量列表,保存了变量的名称 variables = [ 'inited', 'trading', 'pos', 'bollUp', 'bollDown', 'bollUp15', 'bollDown15', 'bollUp30', 'bollDown30', 'FifteenMinTrendStatus', 'FiveMinTrendStatus', 'ThirtyMinTrendStatus' ] # 同步列表 syncList = ['pos', 'intraTradeHigh'] #---------------------------------------------------------------------- def __init__(self, ctaEngine, strategy_name, vt_symbol, setting): """Constructor""" #super(MyBollingerBotStrategy, self).__init__(ctaEngine, setting) super().__init__(ctaEngine, strategy_name, vt_symbol, setting) self.bm5 = BarGenerator(self.on_bar, 5, self.on_5Min_bar) self.am5 = ArrayManager(80) self.bm15 = BarGenerator(self.on_bar, 15, self.on_15Min_bar) self.am15 = ArrayManager(80) self.bm30 = BarGenerator(self.on_bar, 30, self.on_30Min_bar) self.am30 = ArrayManager(80) self.bmDay = BarGenerator(self.on_bar, 9, self.onDayBar, Interval.HOUR) self.amDay = ArrayManager(30) head = [ "datetime", "BollStatus", "open", "close", "high", "low", "openInterest", "volume", "deal", "pDown", "pUp", "dealOpen" ] write_csv_file("datasig5.csv", head, None, "w") write_csv_file("datasig15.csv", head, None, "w") write_csv_file("datasig30.csv", head, None, "w") write_csv_file("datasigDay.csv", head, None, "w") head = [ "datetime", "orderid", "tradeid", "direction", "offset", "price", "volume" ] write_csv_file("datasigTrade.csv", head, None, "w") #---------------------------------------------------------------------- def on_init(self): """初始化策略(必须由用户继承实现)""" self.write_log(u'%s策略初始化' % self.className) # 载入历史数据,并采用回放计算的方式初始化策略数值 initData = self.load_bar(self.initDays) #for bar in initData: # self.onBar(bar) #self.put_event() #---------------------------------------------------------------------- def on_start(self): """启动策略(必须由用户继承实现)""" self.write_log(u'%s策略启动' % self.className) self.put_event() #---------------------------------------------------------------------- def on_stop(self): """停止策略(必须由用户继承实现)""" self.write_log(u'%s策略停止' % self.className) self.put_event() #---------------------------------------------------------------------- def on_tick(self, tick): """收到行情TICK推送(必须由用户继承实现)""" self.bm5.updateTick(tick) #---------------------------------------------------------------------- def on_bar(self, bar: BarData): """收到Bar推送(必须由用户继承实现)""" #早盘开盘前一分钟收到的多余的tick的清除 if "09:29:00" in bar.datetime.strftime( "%Y-%m-%d %H:%M:%S") and "IF" in bar.symbol: return if "08:59:00" in bar.datetime.strftime("%Y-%m-%d %H:%M:%S"): return #s基于日线判断趋势过滤,因此先更新 self.bmDay.update_bar(bar) #s基于30分钟更新 self.bm30.update_bar(bar) # 基于15分钟更新 self.bm15.update_bar(bar) # 基于5分钟更新 self.bm5.update_bar(bar) #判断当前5Min布林线趋势状态 if not self.am5.inited or not self.am15.inited or not self.am30.inited or not self.amDay.inited: return if self.bm5.window_bar != None: if self.bm5.window_bar.high_price > self.bollUp and self.bm5.window_bar.low_price > self.bollMid: self.FiveMinTrendStatus = 'duotou' elif self.bm5.window_bar.low_price < self.bollDown and self.bm5.window_bar.high_price < self.bollMid: self.FiveMinTrendStatus = 'kongtou' elif self.bm5.window_bar.low_price < self.bollMid and self.FiveMinTrendStatus == 'duotou': self.FiveMinTrendStatus = 'panzhen' elif self.bm5.window_bar.high_price > self.bollMid and self.FiveMinTrendStatus == 'kongtou': self.FiveMinTrendStatus = 'panzhen' #判断当前15Min布林线趋势状态 if self.bm15.window_bar != None: if self.bm15.window_bar.high_price > self.bollUp15 and self.bm15.window_bar.low_price > self.bollMid15: self.FifteenMinTrendStatus = 'duotou' elif self.bm15.window_bar.low_price < self.bollDown15 and self.bm15.window_bar.high_price < self.bollMid15: self.FifteenMinTrendStatus = 'kongtou' elif self.bm15.window_bar.low_price < self.bollMid15 and self.FifteenMinTrendStatus == 'duotou': self.FifteenMinTrendStatus = 'panzhen' elif self.bm15.window_bar.high_price > self.bollMid15 and self.FifteenMinTrendStatus == 'kongtou': self.FifteenMinTrendStatus = 'panzhen' #判断当前30Min布林线趋势状态 if self.bm30.window_bar != None: if self.bm30.window_bar.high_price > self.bollUp30 and self.bm30.window_bar.low_price > self.bollMid30: self.ThirtyMinTrendStatus = 'duotou' elif self.bm30.window_bar.low_price < self.bollDown30 and self.bm30.window_bar.high_price < self.bollMid30: self.ThirtyMinTrendStatus = 'kongtou' elif self.bm30.window_bar.low_price < self.bollMid30 and self.ThirtyMinTrendStatus == 'duotou': self.ThirtyMinTrendStatus = 'panzhen' elif self.bm30.window_bar.high_price > self.bollMid30 and self.ThirtyMinTrendStatus == 'kongtou': self.ThirtyMinTrendStatus = 'panzhen' #判断当前日线布林线趋势状态 if self.bmDay.window_bar != None: if self.bmDay.window_bar.high_price > self.bollUpDay and self.bmDay.window_bar.low_price > self.bollMidDay: self.DayTrendStatus = 'duotou' elif self.bmDay.window_bar.low_price < self.bollDownDay and self.bmDay.window_bar.high_price < self.bollMidDay: self.DayTrendStatus = 'kongtou' elif self.bmDay.window_bar.low_price < self.bollMidDay and self.DayTrendStatus == 'duotou': self.DayTrendStatus = 'panzhen' elif self.bmDay.window_bar.high_price > self.bollMidDay and self.DayTrendStatus == 'kongtou': self.DayTrendStatus = 'panzhen' ''' if self.pos == 0: #self.intraTradeHigh = bar.high orderList=[] if self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='duotou' and self.FiveMinTrendStatus=='duotou': #self.longEntry = bar.close self.cancelAll() orderList=self.buy(bar.close+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,1分钟收盘价开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='kongtou' and self.FiveMinTrendStatus=='kongtou': #self.shortEntry = bar.close self.cancelAll() orderList=self.short( bar.close-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,1分钟收盘价开仓"%self.__dict__["name"]) ''' #print (u'策略:',self.__dict__["name"]) #print (u"策略:%s,时间:%s,1分钟刷新,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s"%(self.__dict__["name"],bar.datetime,self.FiveMinTrendStatus,self.FifteenMinTrendStatus,self.ThirtyMinTrendStatus,self.DayTrendStatus)) self.put_event() #---------------------------------------------------------------------- def on_5Min_bar(self, bar: BarData): """收到5分钟K线""" if not self.am5.inited or not self.am15.inited or not self.am30.inited or not self.amDay.inited: self.am5.update_bar(bar) return #计算上一个k线的布林中轨,上轨,下轨 self.BeforebollMid = self.am5.sma(self.bollWindow5min) self.Beforebollup, self.beforebolldown = self.am5.boll( self.bollWindow5min, self.entryDev5min) # 保存K线数据 self.am5.update_bar(bar) # 撤销之前发出的尚未成交的委托(包括限价单和停止单) #self.cancel_all() orderList = [] # 计算指标数值 self.bollMid = self.am5.sma(self.bollWindow5min) self.bollUp, self.bollDown = self.am5.boll(self.bollWindow5min, self.entryDev5min) #判断当前5Min布林线趋势状态 if bar.high_price > self.Beforebollup and bar.low_price > self.BeforebollMid: self.FiveMinTrendStatus = 'duotou' elif bar.low_price < self.beforebolldown and bar.high_price < self.BeforebollMid: self.FiveMinTrendStatus = 'kongtou' elif bar.low_price < self.BeforebollMid and self.FiveMinTrendStatus == 'duotou': self.FiveMinTrendStatus = 'panzhen' elif bar.high_price > self.BeforebollMid and self.FiveMinTrendStatus == 'kongtou': self.FiveMinTrendStatus = 'panzhen' ''' if bar.high > self.bollMid15 and self.FifteenMinTrendStatus == 'kongtou': self.FifteenMinTrendStatus=='panzhen' if bar.low < self.bollMid15 and self.FifteenMinTrendStatus == 'duotou': self.FifteenMinTrendStatus=='panzhen' ''' # 判断是否要进行交易 print(u"策略:%s,5分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s" % (self.className, self.FiveMinTrendStatus, self.FifteenMinTrendStatus, self.ThirtyMinTrendStatus, self.DayTrendStatus)) # 当前无仓位,发送OCO开仓委托 ''' if self.pos == 0: #self.intraTradeHigh = bar.high #多头处理 if self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus!='duotou' : orderList=self.buy(self.bollUp15+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,15分钟上轨开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus=="panzhen" : orderList=self.buy(self.bollUp30+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,30分钟上轨开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='duotou' and self.FiveMinTrendStatus=='duotou': self.longEntry = bar.close orderList=self.buy(self.longEntry+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,5分钟收盘价开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='duotou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='duotou' and self.FiveMinTrendStatus!='duotou': self.longEntry=self.bollUp orderList=self.buy(self.longEntry+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,5分钟上轨开仓"%self.__dict__["name"]) #空头处理 elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus!='kongtou' : orderList=self.short(self.bollDown15-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,15分钟下轨开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus=="panzhen" : orderList=self.short(self.bollDown30-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,30分钟下轨开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='kongtou' and self.FiveMinTrendStatus=='kongtou': self.shortEntry = bar.close orderList=self.short(self.shortEntry-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,5分钟收盘价开仓"%self.__dict__["name"]) elif self.DayTrendStatus=='kongtou' and self.ThirtyMinTrendStatus!="panzhen" and self.FifteenMinTrendStatus=='kongtou' and self.FiveMinTrendStatus!='kongtou': self.shortEntry=self.bollDown orderList=self.short(self.shortEntry-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,5分钟下轨开仓"%self.__dict__["name"]) # 持有多头仓位 elif self.pos > 0: orderList=self.sell(self.bollDown-self.priceTick, abs(self.pos), True) print (u"策略:%s,委托止损单,5分钟下轨平仓"%self.__dict__["name"]) # 持有空头仓位 elif self.pos < 0: orderList=self.cover(self.bollUp+self.priceTick, abs(self.pos), True) print (u"策略:%s,委托止损单,5分钟上轨平仓"%self.__dict__["name"]) with open("datasig5.csv","ab+",) as csvfile: writer = csv.writer(csvfile) writer.writerow([bar.datetime,bar.open, bar.close, bar.high, bar.low,bar.openInterest,bar.volume,self.deal,self.bollDown,self.bollUp,self.dealopen]) self.deal=0 self.dealopen=0 if orderList: print (u"策略:%s,委托单成功,单号%s"%(self.__dict__["name"],orderList[-1])) #else: # print u"策略:%s,委托单失败"%self.__dict__["name"] # 发出状态更新事件 ''' self.put_event() def on_15Min_bar(self, bar: BarData): """15分钟K线推送""" if not self.am15.inited or not self.am30.inited or not self.amDay.inited: self.am15.update_bar(bar) return #计算上一个k线的布林中轨,上轨,下轨 self.BeforebollMid15 = self.am15.sma(self.bollWindow15min) self.Beforebollup15, self.beforebolldown15 = self.am15.boll( self.bollWindow15min, self.entryDev15min) self.am15.update_bar(bar) # 计算指标数值 self.bollMid15 = self.am15.sma(self.bollWindow15min) self.bollUp15, self.bollDown15 = self.am15.boll( self.bollWindow15min, self.entryDev15min) #判断当前15Min布林线趋势状态 if bar.high_price > self.Beforebollup15 and bar.low_price > self.BeforebollMid15: self.FifteenMinTrendStatus = 'duotou' elif bar.low_price < self.beforebolldown15 and bar.high_price < self.BeforebollMid15: self.FifteenMinTrendStatus = 'kongtou' elif bar.low_price < self.BeforebollMid15 and self.FifteenMinTrendStatus == 'duotou': self.FifteenMinTrendStatus = 'panzhen' elif bar.high_price > self.BeforebollMid15 and self.FifteenMinTrendStatus == 'kongtou': self.FifteenMinTrendStatus = 'panzhen' with open( "datasig15.csv", "ab+", ) as csvfile: writer = csv.writer(csvfile) #writer.writerow([bar.datetime,bar.open_price, bar.close_price, bar.high_price, bar.low_price,bar.open_interest,bar.volume,self.deal,self.bollDown15,self.bollUp15,self.dealopen]) print(u"策略:%s,15分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s" % (self.className, self.FiveMinTrendStatus, self.FifteenMinTrendStatus, self.ThirtyMinTrendStatus, self.DayTrendStatus)) #print u"15分钟收盘价",self.am15.closeArray[75:] # 当前无仓位,发送OCO开仓委托 ''' if self.pos == 0: self.intraTradeHigh = bar.high if self.FifteenMinTrendStatus=='panzhen': self.longEntry = self.bollUp15 self.shortEntry=self.booldown15 self.buy(self.longEntry, self.fixedSize, True) self.short(self.shortEntry,self.fixedSize,True) ''' # 发出状态更新事件 self.put_event() def on_30Min_bar(self, bar: BarData): """30分钟K线推送""" t1 = str(bar.datetime) t2 = str(datetime(2016, 2, 3, 21, 0, 0)) if t2 in t1: i = 0 if not self.am30.inited: # or not self.amDay.inited: self.am30.update_bar(bar) return #计算上一个k线的布林中轨,上轨,下轨 self.BeforebollMid30 = self.am30.sma(self.bollWindow30min) self.Beforebollup30, self.beforebolldown30 = self.am30.boll( self.bollWindow30min, self.entryDev30min) self.am30.update_bar(bar) # 计算指标数值 self.bollMid30 = self.am30.sma(self.bollWindow30min) self.bollUp30, self.bollDown30 = self.am30.boll( self.bollWindow30min, self.entryDev30min) #判断当前30Min布林线趋势状态 if bar.high_price > self.Beforebollup30 and bar.low_price > self.BeforebollMid30: self.ThirtyMinTrendStatus = 'duotou' elif bar.low_price < self.beforebolldown30 and bar.high_price < self.BeforebollMid30: self.ThirtyMinTrendStatus = 'kongtou' elif bar.low_price < self.BeforebollMid30 and self.ThirtyMinTrendStatus == 'duotou': self.ThirtyMinTrendStatus = 'panzhen' elif bar.high_price > self.BeforebollMid30 and self.ThirtyMinTrendStatus == 'kongtou': self.ThirtyMinTrendStatus = 'panzhen' self.cancel_all() #开平仓位置 self.intraTradeHigh = bar.high_price self.longEntry = self.bollUp30 + self.priceTick self.longExit = self.bollDown30 - self.priceTick self.shortEntry = self.bollDown30 - self.priceTick self.shortExit = self.bollUp30 + self.priceTick if not self.tradedata: #策略启动到现在无交易 if self.ThirtyMinTrendStatus == 'panzhen' and self.DayTrendStatus == 'duotou': self.buy(self.longEntry, self.fixedSize, True) elif self.ThirtyMinTrendStatus == 'panzhen' and self.DayTrendStatus == 'kongtou': self.short(self.shortEntry, self.fixedSize, True) else: #策略启动到现在有交易 #需要在布林线上下轨止损的但系,重新发出止损单子 trade = self.tradedata[-1] if trade.offset == Offset.CLOSE: #最后一个交易为平仓单,发送开仓单在布林线上下轨 if self.ThirtyMinTrendStatus == 'panzhen' and self.DayTrendStatus == 'duotou': self.buy(self.longEntry, self.fixedSize, True) elif self.ThirtyMinTrendStatus == 'panzhen' and self.DayTrendStatus == 'kongtou': self.short(self.shortEntry, self.fixedSize, True) elif trade.offset == Offset.OPEN and trade.direction == Direction.LONG: # 最后一笔交易为多头仓位,发送平仓单在下轨 orderList = self.sell(self.longExit, trade.volume, True) print(u"策略:%s,委托止损单,30分钟下轨平仓" % self.className) elif trade.offset == Offset.OPEN and trade.direction == Direction.SHORT: # 最后一笔交易为空头仓位,发送平仓单在上轨 orderList = self.cover(self.shortExit, trade.volume, True) print(u"策略:%s,委托止损单,30分钟上轨平仓" % self.className) #需要在保本位置设置止损的交易单,重新发出止损单子 if len(self.tradedata_baoben) > 0: i = 0 while i < len(self.tradedata_day): volume = self.tradedata_baoben[i].volume i = i + 1 if self.tradedata_baoben[i - 1].direction == Direction.LONG: orderList = self.sell(self.tradedata_baoben[i].price, volume, True) print(u"策略:%s,委托止损单,保本价格平仓" % self.className) elif self.tradedata_baoben[i - 1].direction == Direction.SHORT: orderList = self.cover(self.tradedata_baoben[i].price, volume, True) print(u"策略:%s,委托止损单,保本价格平仓" % self.className) #需要在日线中轨止损的单子,需要在新的日线中轨处发出止损单 if len(self.tradedata_day) > 0: i = 0 volume = 0 while i < len(self.tradedata_day): volume = self.tradedata_day[i].volume + volume i = i + 1 if self.tradedata_day[i - 1].direction == Direction.LONG: orderList = self.sell(self.shortExit, volume, True) print(u"策略:%s,委托止损单,日线中轨平仓" % self.className) elif self.tradedata_day[i - 1].direction == Direction.SHORT: orderList = self.cover(self.shortExit, volume, True) print(u"策略:%s,委托止损单,日线中轨平仓" % self.className) bardata = [ bar.datetime, self.ThirtyMinTrendStatus, bar.open_price, bar.close_price, bar.high_price, bar.low_price, bar.open_interest, bar.volume, self.pos, self.bollDown30, self.bollUp30, self.dealopen ] write_csv_file("datasig30.csv", None, bardata, "a+") print(u"时间:", bar.datetime) print(u"策略:%s,30分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s" % (self.className, self.FiveMinTrendStatus, self.FifteenMinTrendStatus, self.ThirtyMinTrendStatus, self.DayTrendStatus)) print(u"30分钟收盘价", self.am30.close_array[60:]) # 发出状态更新事件 self.put_event() def onDayBar(self, bar: BarData): """日K线推送""" if not self.amDay.inited: self.amDay.update_bar(bar) return #计算上一个k线的布林中轨,上轨,下轨 self.BeforebollMidDay = self.amDay.sma(self.bollWindowDay) self.BeforebollupDay, self.beforebolldownDay = self.amDay.boll( self.bollWindowDay, self.entryDevDay) self.amDay.update_bar(bar) # 计算指标数值 self.bollMidDay = self.amDay.sma(self.bollWindowDay) self.bollUpDay, self.bollDownDay = self.amDay.boll( self.bollWindowDay, self.entryDevDay) #判断当前日线布林线趋势状态 if bar.high_price > self.BeforebollupDay and bar.low_price > self.BeforebollMidDay: self.DayTrendStatus = 'duotou' elif bar.low_price < self.beforebolldownDay and bar.high_price < self.BeforebollMidDay: self.DayTrendStatus = 'kongtou' elif bar.low_price < self.BeforebollMidDay and self.DayTrendStatus == 'duotou': self.DayTrendStatus = 'panzhen' elif bar.high_price > self.BeforebollMidDay and self.DayTrendStatus == 'kongtou': self.DayTrendStatus = 'panzhen' #需要在日线中轨止损的单子,需要在新的日线中轨处发出止损单 if len(self.tradedata_day) > 0: i = 0 volume = 0 while i < len(self.tradedata_day): volume = self.tradedata_day[i].volume + volume i = i + 1 if self.tradedata_day[i - 1].direction == Direction.LONG: orderList = self.sell(self.shortExit, volume, True) print(u"策略:%s,委托止损单,日线中轨平仓" % self.className) elif self.tradedata_day[i - 1].direction == Direction.SHORT: orderList = self.cover(self.shortExit, volume, True) print(u"策略:%s,委托止损单,日线中轨平仓" % self.className) ''' #日线盘整,上下轨开仓 if self.DayTrendStatus=="panzhen" and self.pos==0: self.cancelAll() orderList=[] orderList=self.buy(self.bollUpDay+self.priceTick, self.fixedSize, True) print (u"策略:%s,委托多单,日线上轨开仓"%self.__dict__["name"]) if orderList: print (u"策略:%s,委托单成功,单号%s"%(self.__dict__["name"],orderList[-1])) else: print (u"策略:%s,委托单失败"%self.__dict__["name"]) orderList=[] orderList=self.short(self.bollDownDay-self.priceTick, self.fixedSize, True) print (u"策略:%s,委托空单,日线下轨开仓"%self.__dict__["name"]) if orderList: print (u"策略:%s,委托单成功,单号%s"%(self.__dict__["name"],orderList[-1])) else: print (u"策略:%s,委托单失败"%self.__dict__["name"] ) ''' bardata = [ bar.datetime, self.DayTrendStatus, bar.open_price, bar.close_price, bar.high_price, bar.low_price, bar.open_interest, bar.volume, self.pos, self.bollDownDay, self.bollUpDay, self.dealopen ] write_csv_file("datasigDay.csv", None, bardata, "a+") print(u"时间:", bar.datetime) print(u"策略:%s,日线刷新,趋势状态,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s" % (self.className, self.FiveMinTrendStatus, self.FifteenMinTrendStatus, self.ThirtyMinTrendStatus, self.DayTrendStatus)) print(u"日线开盘价", self.amDay.open_array[1:]) print(u"日线收盘价", self.amDay.close_array[1:]) # 发出状态更新事件 self.put_event() #---------------------------------------------------------------------- def on_order(self, order): """收到委托变化推送(必须由用户继承实现)""" pass #---------------------------------------------------------------------- def on_trade(self, trade): #打印信息 print("策略:%s,趋势状态,5分钟趋势%s,15分钟趋势%s,30分钟趋势%s,日线趋势%s" % (self.className, self.FiveMinTrendStatus, self.FifteenMinTrendStatus, self.ThirtyMinTrendStatus, self.DayTrendStatus)) print(u"策略:%s, 委托单成交" % self.className) print(trade.direction) print(trade.offset) #print "15min:",self.FifteenMinTrendStatus #print "5min:",self.FiveMinTrendStatus #head=["datetime","orderid","tradeid","direction","offset","price","volume"] #所有交易单保存下来 self.tradedata.append(trade) #开仓的交易单单独保存下来到需要布林止损的list中 if trade.offset == Offset.OPEN: self.tradedata_boll.append(trade) #保存到文件 tradedata = [ trade.datetime, trade.orderid, trade.tradeid, trade.direction, trade.offset, trade.price, trade.volume ] write_csv_file("datasigTrade.csv", None, tradedata, "a+") #开仓成功后先取消掉还有的挂单,主要针对的是日线的双向挂单 #if self.pos!=0: # self.cancel_all() # 发出状态更新事件 orderList = [] if trade.offset == Offset.OPEN and trade.direction == Direction.LONG: #多头成交,设置止损单 orderList = self.sell(self.bollDown30 - self.priceTick, trade.volume, True) print(u"委托止损单,30分钟下轨平仓") if orderList: print(u"委托单成功单号", orderList) else: print(u"委托单失败") elif trade.offset == Offset.OPEN and trade.direction == Direction.SHORT: #空头成交,设置止损单 orderList = self.cover(self.bollUp30 + self.priceTick, trade.volume, True) print(u"委托止损单,30分钟上轨平仓") if orderList: print(u"委托单成功单号", orderList) else: print(u"委托单失败") #更新周期状态 if trade.offset == Offset.OPEN: if trade.direction == Direction.LONG: self.dealopen = 1 self.DayTrendStatus = "duotou" self.FifteenMinTrendStatus = 'duotou' self.FiveMinTrendStatus = 'duotou' self.ThirtyMinTrendStatus = 'duotou' else: self.dealopen = -1 self.DayTrendStatus = "kongtou" self.FifteenMinTrendStatus = 'kongtou' self.FiveMinTrendStatus = 'kongtou' self.ThirtyMinTrendStatus = 'kongtou' if trade.offset == Offset.CLOSE: if trade.direction == Direction.LONG: self.ThirtyMinTrendStatus = 'kongtou' self.deal = 1 else: self.deal = -1 self.put_event() #---------------------------------------------------------------------- def on_stop_order(self, so): """停止单推送""" pass