def generate_3mindata(self, am:ArrayManager, bar:BarData):
        offset = -self.offset
        offset_m = int(offset / 2)
        calc_nums = np.array(self.ma_tag[-offset:-1])
        # var_val = np.var(calc_nums)
        std_val = np.std(calc_nums)
        std_val2 = np.std(np.array(self.ma_tag[-10:-1]))
        std_val3 = np.std(np.array(am.range[-30:-10]))
        ma = self.ma_tag[-1]
        
        mean_val = np.mean(calc_nums)
        mean_val2 = np.mean(np.array(self.ma_tag[-5:-1]))
        mean_val3 = np.mean(np.array(self.ma_tag[-20:-1]))
        mean_val4 = np.mean(np.array(self.ma_tag[-30:-5]))
        kdj_val = am.kdj()

        deg1 = calc_regress_deg(am.close[offset : offset_m], False)
        deg2 = calc_regress_deg(am.close[offset_m :], False)
        deg3 = calc_regress_deg(am.close[-10 :], False)
        deg_full = calc_regress_deg(am.close[offset :], False)

        wave = self.wave(am.close[-30:])
        wave_r_sum = np.sum(wave["range"])
        macd=am.macd(20,40, 16)
        calc_data = (dict(
                kdj=[round(kdj_val["k"][-1],2),round(kdj_val["d"][-1],2),round(kdj_val["j"][-1],2)],
                cci_20=am.cci(20),rsi=am.rsi(20),adx=am.adx(20),boll=am.boll(20, 3.4),
                macd=[round(macd[0],2),round(macd[1],2),round(macd[2],2)],
                deg40_20=round(deg1,2), deg20_0=round(deg2,2), deg20_10=round(calc_regress_deg(am.close[-20:-10], False),2), deg10_0=round(deg3,2),
                deg30_15=round(calc_regress_deg(am.close[-30:-15], False),2), deg15_0=round(calc_regress_deg(am.close[-15:], False),2),deg_f=round(deg_full,2),
                atr=round(am.atr(10, length=15), 3), tr=round(am.atr(1, length=2), 3),atr_40=round(am.atr(40, length=42), 3),
                time=bar.datetime, price=bar.close_price, ma=round(ma, 2), 
                std_40=round(std_val, 2),mean40=round(mean_val,2), mean_std=np.mean(self.std_range.data[-5:]),
                std_10=round(std_val2,2), mean30_10=round(mean_val4,2), mean10=round(mean_val2,2),
                vol=am.volume[-1], std_range=self.std_range.data[-1:-5:-1], range=am.range[-1:-5:-1].tolist(),
                range_sum=np.sum(am.range[-5:]), 
                pattern=list(map(lambda x: KLINE_PATTERN_CHINESE[x], self.pattern_record.keys())),
                ma120t=self.ma120_track, 
                ma120t_list=self.ma120_track_list[-1:-10:-1], 
                ma120t_sort=sorted(self.ma120_track_list[-20:-1], key=abs),
                ma120t_sum=np.sum(self.ma120_track_list[-20:-1] + [self.ma120_track]), 
                ma120t_mean=np.mean(self.ma120_track_list[-20:-1] + [self.ma120_track]),
                ma120t_std=np.std(self.ma120_track_list[-20:-1] + [self.ma120_track]),
                ma_info=list(map(lambda x:x["std"], self.ma_info[-1:])),
                wave_cnt=len(wave), wave_r_sum=wave_r_sum, atr_mean=np.mean(am.atr(20, array=True,length=240)[-200:])
                ))

        return calc_data
class RsiAdaptStrategy(CtaTemplate):
    """
	策略逻辑:
	一、、过虑信号  (小时周期)
	使用rsiboll来判断信号强弱

	二、开单信号 (分钟周期)
	1、使用布林上下轨作为开单条件

	三、止损
	使用动态布林中轨止损

	"""
    author = "yunya"

    min_window = 15
    open_window = 5
    rsi_length = 15
    boll_length = 80
    boll_dev = 2.0
    trading_size = 1

    rsi_value = 0
    rsi_up = 0
    rsi_dow = 0
    rsi_entry = 0
    boll_up = 0
    boll_down = 0
    boll_mid = 0
    boll_length_new = 0
    current_boll_mid = 0
    last_boll_mid = 0
    current_close = 0
    last_close = 0
    front_close = 0
    exit_long = 0
    exit_short = 0
    exit_long_nex = 0
    exit_long_last = 0
    exit_short_nex = 0
    exit_short_last = 0

    parameters = [
        "min_window",
        "open_window",
        "rsi_length",
        "boll_length",
        "boll_dev",
        "trading_size",
    ]

    variables = [
        "rsi_value",
        "rsi_up",
        "rsi_dow",
        "rsi_entry",
        "boll_up",
        "boll_down",
        "boll_mid",
        "boll_length_new",
        "current_boll_mid",
        "last_boll_mid",
        "current_close",
        "last_close",
        "front_close",
        "exit_long",
        "exit_short",
        "exit_long_nex",
        "exit_long_last",
        "exit_short_nex",
        "exit_short_last",
    ]

    def __init__(
        self,
        cta_engine: Any,
        strategy_name: str,
        vt_symbol: str,
        setting: dict,
    ):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.atr_stop_array = np.zeros(10)

        self.bg_xminute = NewBarGenerator(on_bar=self.on_bar,
                                          window=self.min_window,
                                          on_window_bar=self.on_xminute_bar)
        self.am_xminute = ArrayManager(self.boll_length + 100)

        self.bg_open = NewBarGenerator(on_bar=self.on_bar,
                                       window=self.open_window,
                                       on_window_bar=self.on_5min_bar)
        self.am_open = ArrayManager()

    def on_init(self):
        """
		Callback when strategy is inited.
		"""
        self.write_log("策略初始化。。")
        self.load_bar(10)

        self.put_event()

    def on_start(self):
        """
		Callback when strategy is started.
		"""
        self.write_log("策略启动。。")
        self.put_event()

    def on_stop(self):
        """
		Callback when strategy is stopped.
		"""
        self.write_log("策略停止。。")
        self.put_event()

    def on_tick(self, tick: TickData):
        """
		Callback of new tick data update.
		"""
        self.bg_open.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
		Callback of new bar data update.
		"""
        self.bg_xminute.update_bar(bar)
        self.bg_open.update_bar(bar)

    def on_5min_bar(self, bar: BarData):
        """
		:param bar: 
		:type bar: 
		:return: 
		:rtype: 
		"""
        self.cancel_all()
        self.am_open.update_bar(bar)

        if not self.am_open.inited or not self.am_xminute.inited:
            return

        if not self.pos:
            if self.rsi_entry > 0:
                self.buy(self.boll_up, self.trading_size, True)
            # print(bar.datetime, self.boll_up, self.trading_size)
            # print(bar.datetime, self.entry_up, self.trading_size, bar)

            elif self.rsi_entry < 0:
                self.short(self.boll_down, self.trading_size, True)

        elif self.pos > 0:
            # 仓位是long 时,如果价格下穿新布林中轨
            con1 = bar.close_price < self.current_boll_mid
            con2 = bar.close_price >= self.last_boll_mid
            if con1 and con2:
                self.exit_long_nex = bar.close_price  # 保存当前收盘价

                if self.exit_long_last == 0 or self.exit_long_nex > self.exit_long_last:
                    self.exit_long_last = self.exit_long_nex
                    self.boll_length_new = self.boll_length

                    # 下穿新均线,以原布林均线挂出停止单,避免快速下跌而无法止损
                    self.exit_long = self.boll_mid

                else:
                    # 收盘价在两条均线平均价上方,以当前收盘价挂出限价单
                    if bar.close_price > (
                        (self.boll_mid + self.current_boll_mid) / 2):
                        self.exit_long = bar.close_price

                    elif bar.close_price < self.boll_mid:
                        self.exit_long = bar.close_price

                    else:
                        self.exit_long = self.boll_mid
            # print(f"我是多单,收盘价在两个中轨均值下方,以原中轨挂止损单:{self.exit_long},")
            else:
                self.exit_long = self.boll_mid
            self.sell(self.exit_long, abs(self.pos), True)

        elif self.pos < 0:
            # 仓位是short 时,如果价格上穿新布林中轨
            con1 = bar.close_price > self.current_boll_mid
            con2 = bar.close_price <= self.last_boll_mid
            if con1 and con2:
                self.exit_short_nex = bar.close_price
                if self.exit_short_last == 0 or self.exit_short_nex < self.exit_short_last:
                    self.exit_short_last = self.exit_short_nex
                    self.boll_length_new = self.boll_length

                    self.exit_short = self.boll_mid

                else:
                    if bar.close_price < (self.boll_mid +
                                          self.current_boll_mid / 2):
                        self.exit_short = bar.close_price

                    elif bar.close_price < self.boll_mid:
                        self.exit_short = bar.close_price

                    else:
                        self.exit_short = self.boll_mid
            else:
                self.exit_short = self.boll_mid
            self.cover(self.exit_short, abs(self.pos), True)

        self.sync_data()
        self.put_event()

    def on_xminute_bar(self, bar: BarData):
        """
		:param bar:
		:return:
		"""
        self.am_xminute.update_bar(bar)
        if not self.am_xminute.inited:
            return

        rsi_array = talib.RSI(self.am_xminute.close[:-1], self.rsi_length)
        ema_array = talib.EMA(self.am_xminute.close, self.rsi_length)

        dev_array = abs(self.am_xminute.close[:-1] -
                        ema_array[:-1]) / rsi_array

        rsi_up_array = rsi_array + rsi_array * dev_array
        rsi_dow_array = rsi_array - rsi_array * dev_array

        self.rsi_value = self.am_xminute.rsi(self.rsi_length)
        self.rsi_up = rsi_up_array[-1]
        self.rsi_dow = rsi_dow_array[-1]

        current_rsi_up = rsi_up_array[-1]
        current_rsi_down = rsi_dow_array[-1]

        if self.rsi_value > current_rsi_up:
            self.rsi_entry = 1
        elif self.rsi_value < current_rsi_down:
            self.rsi_entry = -1

        self.boll_up, self.boll_down = self.am_xminute.boll(
            self.boll_length, self.boll_dev)
        self.boll_mid = self.am_xminute.sma(self.boll_length)

        self.current_close = self.am_xminute.close[-1]
        self.last_close = self.am_xminute.close[-2]
        self.front_close = self.am_xminute.close[-3]

        if self.pos == 0:
            self.exit_long_nex = 0
            self.exit_long_last = 0
            self.exit_short_nex = 0
            self.exit_short_last = 0
            self.boll_length_new = self.boll_length

        elif self.pos > 0:
            # 上涨或下跌时,布林中轨均值减1
            close_long = self.current_close > self.last_close > self.front_close
            if close_long:
                self.boll_length_new -= 1
                self.boll_length_new = max(self.boll_length_new, 5)

        elif self.pos < 0:
            close_short = self.current_close < self.last_close < self.front_close
            if close_short:
                self.boll_length_new -= 1
                self.boll_length_new = max(self.boll_length_new, 5)

        boll_mid_new = self.am_xminute.sma(self.boll_length_new, True)
        self.current_boll_mid = boll_mid_new[-1]
        self.last_boll_mid = boll_mid_new[-2]

        self.sync_data()

    def on_trade(self, trade: TradeData):
        """
		有成交时
		Callback of new trade data update.
		"""
        self.put_event()

    def on_order(self, order: OrderData):
        """
		订单更新回调
		Callback of new order data update.
		"""

        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
		Callback of stop order update.
		"""
        self.put_event()
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
Exemple #4
0
class AberrationBiasStrategy(CtaTemplate):
    """
    目前使用中轨加速,可以考虑使用另外一根均线来加速,这样可以避免在开仓时被平。
    """
    author = "yunya"

    open_window = 60
    boll_length = 80
    boll_dev = 2.0
    bias = 1.0
    cci_length = 6
    cci_exit = 10.0
    fixed_size = 1

    boll_up = 0
    boll_down = 0
    boll_mid = 0
    boll_mid_new = 0
    boll_mid_array = 0
    bias_value_array = 0
    bias_value = 0
    cci_value = 0
    exit_long = 0
    exit_short = 0
    boll_length_new = 0
    exit_long_nex = 0
    exit_long_last = 0
    exit_short_nex = 0
    exit_short_last = 0

    parameters = [
        "open_window",
        "boll_length",
        "boll_dev",
        "bias",
        "cci_length",
        "cci_exit",
        "fixed_size",
    ]

    variables = [
        "boll_up",
        "boll_down",
        "boll_mid",
        "bias_value",
        "cci_value",
        "exit_long",
        "exit_short",
        "boll_length_new",
        "exit_long_nex",
        "exit_long_last",
        "exit_short_nex",
        "exit_short_last",
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.bg = NewBarGenerator(self.on_bar, self.open_window,
                                  self.on_xmin_bar)
        self.am = ArrayManager(int(self.boll_length) + 100)

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)

    def on_xmin_bar(self, bar: BarData):
        """"""
        self.cancel_all()

        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return

        # 计算原布林带
        self.boll_up, self.boll_down = self.am.boll(self.boll_length,
                                                    self.boll_dev)
        self.boll_mid_array = am.sma(self.boll_length, True)
        self.boll_mid = self.boll_mid_array[-1]
        self.bias_value_array = (self.am.close -
                                 self.boll_mid_array) / self.boll_mid_array
        self.bias_value = self.bias_value_array[-1]

        self.cci_value = am.cci(self.cci_length)

        # 如果没有仓位,两条布林window一样
        if self.pos == 0:
            self.exit_long_nex = 0
            self.exit_long_last = 0
            self.exit_short_nex = 0
            self.exit_short_last = 0
            self.boll_length_new = self.boll_length

            if self.cci_value > self.cci_exit:
                self.buy(self.boll_up, self.fixed_size, True)

            if self.cci_value < -self.cci_exit:
                self.short(self.boll_down, self.fixed_size, True)

        elif self.pos > 0:
            # 上涨或下跌时,布林中轨均值减1
            close_long = am.close[-1] > am.close[-2] > am.close[-3]

            if close_long:
                self.boll_length_new -= 1
                self.boll_length_new = max(self.boll_length_new, 20)

            # 计算新的布林带
            self.boll_mid_new = am.sma(self.boll_length_new, True)

            # 仓位是long 时,如果价格上穿新布林中轨
            con1 = am.close[-1] < self.boll_mid_new[-1]
            con2 = am.close[-2] >= self.boll_mid_new[-2]

            if con1 and con2:
                self.exit_long_nex = am.close[-1]  # 保存当前收盘价
                if self.exit_long_nex > self.exit_long_last or self.exit_long_last == 0:
                    self.exit_long_last = self.exit_long_nex
                    self.boll_length_new = self.boll_length
                    # 下穿新均线,以原布林均线挂出停止单,避免快速下跌而无法止损
                    self.exit_long = self.boll_mid
                    # print(f"我是多单,exitlast:{self.exit_short_last},重置布林中轨参数,止损挂{self.exit_long}:")
                else:
                    # 收盘价在两条均线平均价上方,以当前收盘价挂出限价单
                    if self.am.close[-1] > (
                        (self.boll_mid + self.boll_mid_new[-1]) / 2):
                        self.exit_long = bar.close_price
                        # print(f"我是多单,收盘价在两个中轨均值上方,以收盘价挂止损单:{self.exit_long}")
                    elif bar.close_price < self.boll_mid:
                        self.exit_long = bar.close_price
                    else:
                        self.exit_long = self.boll_mid
                        # print(f"我是多单,收盘价在两个中轨均值下方,以原中轨挂止损单:{self.exit_long},")
            else:
                self.exit_long = self.boll_mid
                # print(f"我是多单,收盘价在新中轨上方,以原中轨挂止损单:{self.exit_long}")

            if self.bias_value > self.bias:
                self.exit_long = max(bar.close_price, self.exit_long)

            self.sell(self.exit_long, abs(self.pos), True)

        elif self.pos < 0:
            close_short = am.close[-1] < am.close[-2] < am.close[-3]

            if close_short:
                self.boll_length_new -= 1
                self.boll_length_new = max(self.boll_length_new, 20)

            # 计算新的布林带
            self.boll_mid_new = am.sma(self.boll_length_new, True)

            # 仓位是short 时,如果价格上穿新布林中轨
            con3 = am.close[-1] > self.boll_mid_new[-1]
            con4 = am.close[-2] <= self.boll_mid_new[-2]

            if con3 and con4:
                self.exit_short_nex = am.close[-1]
                if self.exit_short_nex < self.exit_short_last or self.exit_short_last == 0:
                    self.exit_short_last = self.exit_short_nex
                    self.boll_length_new = self.boll_length

                    self.exit_short = self.boll_mid
                else:
                    if self.am.close[-1] < (self.boll_mid +
                                            self.boll_mid_new[-1] / 2):
                        self.exit_short = bar.close_price

                    elif bar.close_price > self.boll_mid:
                        self.exit_short = bar.close_price

                    else:
                        self.exit_short = self.boll_mid

            else:
                self.exit_short = self.boll_mid

            if self.bias_value < -self.bias:
                self.exit_short = min(self.exit_short, bar.close_price)

            self.cover(self.exit_short, abs(self.pos), True)

        self.put_event()
        self.sync_data()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        self.put_event()
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.put_event()
        pass

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        self.put_event()
        pass
Exemple #5
0
class CincoStrategyHN(CtaTemplate):
    """"""

    author = "Huang Ning"

    boll_window = 42
    boll_dev = 2.0
    trailing_long = 0.65
    trailing_short = 0.7
    atr_window = 10
    risk_level = 100

    boll_up = 0
    boll_down = 0
    trading_size = 0
    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0
    atr_value = 0

    parameters = [
        "boll_window", "boll_dev", "trailing_long", "trailing_short",
        "atr_window", "risk_level"
    ]

    variables = [
        "boll_up", "boll_down", "trading_size", "intra_trade_high",
        "intra_trade_low", "long_stop", "short_stop", "atr_value"
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(CincoStrategyHN, self).__init__(cta_engine, strategy_name,
                                              vt_symbol, setting)

        self.bg = BarGenerator(self.on_bar, 15, self.on_15min_bar)
        self.am = ArrayManager()

    def on_init(self):
        """"""
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """"""
        self.write_log("策略启动")

    def on_stop(self):
        """"""
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """"""
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """"""
        self.bg.update_bar(bar)

    def on_15min_bar(self, bar: BarData):
        """"""
        self.cancel_all()

        self.am.update_bar(bar)
        if not self.am.inited:
            return

        self.boll_up, self.boll_down = self.am.boll(self.boll_window,
                                                    self.boll_dev)
        boll_width = self.boll_up - self.boll_down

        if not self.pos:
            self.atr_value = self.am.atr(self.atr_window)
            self.trading_size = int(self.risk_level / self.atr_value)

            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price
            self.long_stop = 0
            self.short_stop = 0

            self.buy(self.boll_up, self.trading_size, stop=True)
            self.short(self.boll_down, self.trading_size, stop=True)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.long_stop = self.intra_trade_high - self.trailing_long * boll_width
            self.sell(self.long_stop, abs(self.pos), stop=True)

        else:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.short_stop = self.intra_trade_low + self.trailing_short * boll_width
            self.cover(self.short_stop, abs(self.pos), stop=True)

        self.put_event()

    def on_order(self, order: OrderData):
        """"""

    def on_trade(self, trade: TradeData):
        """"""
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """"""
        self.put_event()
Exemple #6
0
class CuatroStrategy(CtaTemplate):
    """"""
    author = "KeKe"

    rsi_signal = 19  # 定义rsi阈值
    rsi_window = 14
    fast_window = 4
    slow_window = 26
    boll_window = 20
    boll_dev = 1.8
    trailing_short = 0.3
    trailing_long = 0.5
    fixed_size = 1

    boll_up = 0
    boll_down = 0
    rsi_value = 0
    rsi_long = 0
    rsi_short = 0
    fast_ma = 0
    slow_ma = 0
    ma_trend = 0
    long_stop = 0
    short_stop = 0
    intra_trade_high = 0
    intra_trade_low = 0

    parameters = [
        "rsi_signal", "rsi_window", "fast_window", "slow_window",
        "boll_window", "boll_dev", "trailing_long", "trailing_short",
        "fixed_size"
    ]

    variables = [
        "boll_up", "boll_down", "rsi_value", "rsi_long", "rsi_short",
        "fast_ma", "slow_ma", "ma_trend", "long_stop", "short_stop"
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(CuatroStrategy, self).__init__(cta_engine, strategy_name,
                                             vt_symbol, setting)

        self.rsi_long = 50 + self.rsi_signal  # 用rsi阈值定义rsi超买区域
        self.rsi_short = 50 - self.rsi_signal  # 用rsi阈值定义rsi超卖区域

        self.bg5 = BarGenerator(self.on_bar, 5, self.on_5min_bar)  # 合成5分钟K线
        self.am5 = ArrayManager()  # 初始化5分钟k线的时间序列

        self.bg15 = BarGenerator(self.on_bar, 15,
                                 self.on_15min_bar)  # 合成15分钟k线
        self.am15 = ArrayManager()  # 初始化15分钟k线的时间序列

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)  # 载入最近10根bar

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg5.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg5.update_bar(bar)  # 将1分钟k线推送入bg5合成5分钟线
        self.bg15.update_bar(bar)  # 将1分钟k线推送入bg15合成15分钟线

    def on_5min_bar(self, bar: BarData):
        """在5分钟级别进行交易"""
        self.cancel_all()

        self.am5.update_bar(bar)
        if not self.am5.inited:
            return

        if not self.ma_trend:  # 如果ma_trend没有初始化,就跳过这根bar
            return

        self.rsi_value = self.am5.rsi(self.rsi_window)  # 生成5分钟线的rsi指标
        self.boll_up, self.boll_down = self.am5.boll(
            self.boll_window, self.boll_dev)  # 生成5分钟线的bolling指标
        boll_width = self.boll_up - self.boll_down  # 赋值boll宽度变量
        ## 当空仓时
        if self.pos == 0:
            self.intra_trade_low = bar.low_price  # 记录最低价,用于追踪买入后最低价
            self.intra_trade_high = bar.high_price  # 记录最高价,用于追踪买入后最高价

            if self.ma_trend > 0 and self.rsi_value >= self.rsi_long:  # 当上升趋势,且进入超买区
                self.buy(self.boll_up, self.fixed_size,
                         True)  # 在bolling带上轨开1手多头单

            elif self.ma_trend < 0 and self.rsi_value <= self.rsi_short:  # 当下降趋势,且进入超卖区
                self.short(self.boll_down, self.fixed_size,
                           True)  # 在bolling带下轨开1手空头仓位
        ## 当持有多头仓时
        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high,
                                        bar.high_price)  # 逐根k线记录到达过的最高价
            self.long_stop = (self.intra_trade_high -
                              self.trailing_long * boll_width
                              )  # 追踪止损位是最高价*0.5*boll宽度
            self.sell(self.long_stop, abs(self.pos), True,
                      True)  # 在追踪止损价位平所有多头仓
        ## 当持有空头仓时
        elif self.pos < 0:
            self.intra_trade_low = min(self.intra_trade_low,
                                       bar.low_price)  # 逐根k线记录到达过的最低价
            self.short_stop = (self.intra_trade_low +
                               self.trailing_short * boll_width)  # 追踪止损位
            self.cover(self.short_stop, abs(self.pos), True, True)  # 轧空

        self.put_event()

    def on_15min_bar(self, bar: BarData):
        """在15分钟级别主要用于判断市场的趋势,起筛选作用"""
        self.am15.update_bar(bar)  # 推送bar,生成15分钟的时间序列
        if not self.am15.inited:  # 判断15分钟线是否已初始化
            return

        self.fast_ma = self.am15.sma(self.fast_window)  # 生成15分钟级别的移动平均线快线
        self.slow_ma = self.am15.sma(self.slow_window)  # 生成15分钟级别的移动平均线慢线

        if self.fast_ma > self.slow_ma:  # 当金叉以后
            self.ma_trend = 1  # 1代表上升趋势
        else:
            self.ma_trend = -1  # -1代表下降趋势

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
class AroonAtrStrategy(CtaTemplate):
    """"""

    author = "tonywang_efun"

    fixed_size = 1
    bar_window = 26
    boll_window = 39
    boll_dev = 1.9
    aroon_window = 14
    aroon_long = 50
    aroon_short = 50
    atr_window = 30
    atr_stop_multiplier = 3

    boll_up = 0
    boll_down = 0
    aroon_up = 0
    aroon_down = 0
    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0
    atr_value = 0

    parameters = [
        "fixed_size",
        "bar_window",
        "boll_window",
        "boll_dev",
        "aroon_window",
        "aroon_long",
        "aroon_short",
        "atr_window",
        "atr_stop_multiplier"
    ]

    variables = [
        "boll_up",
        "boll_down",
        "aroon_up",
        "aroon_down",
        "atr_value",
        "intra_trade_high",
        "intra_trade_low",
        "long_stop",
        "short_stop"
    ]

    def __init__(
        self,
        cta_engine,
        strategy_name: str,
        vt_symbol: str,
        setting: dict,
    ):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.bg = BarGenerator(self.on_bar, self.bar_window, self.on_xmin_bar)
        self.am = ArrayManager()

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)
    
    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")
    
    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)
    
    def on_xmin_bar(self, bar: BarData):
        """"""
        self.cancel_all()

        self.am.update_bar(bar)
        if not self.am.inited:
            return

        self.aroon_up, self.aroon_down = self.am.aroon(self.aroon_window)
        self.atr_value = self.am.atr(self.atr_window)
        self.boll_up, self.boll_down = self.am.boll(self.boll_window, self.boll_dev)

        if not self.pos:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price
            self.long_stop = 0
            self.short_stop = 0

            if self.aroon_up > self.aroon_down and self.aroon_up > self.aroon_long:
                self.buy(self.boll_up, self.fixed_size, stop=True)

            if self.aroon_down > self.aroon_up and self.aroon_down > self.aroon_short:
                self.short(self.boll_down, self.fixed_size, stop=True)
        
        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.long_stop = self.intra_trade_high - self.atr_value * self.atr_stop_multiplier
            self.sell(self.long_stop, abs(self.pos), stop=True)
        
        else:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.short_stop = self.intra_trade_low + self.atr_value * self.atr_stop_multiplier
            self.cover(self.short_stop, abs(self.pos), stop=True)
        
        self.put_event()

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.put_event()
    
    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        pass
    
    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Exemple #8
0
    def generate_data(self, am: ArrayManager, bar: BarData):
        offset = -self.offset
        offset_m = int(offset / 2)

        std_val3 = np.std(np.array(am.range[-30:-10]))

        kdj_val = am.kdj()
        has_kdj_recore = False
        k = kdj_val["k"]
        d = kdj_val["d"]
        j = kdj_val["j"]
        if (k[-1] > 75 and d[-1] > 75 and j[-1] > 75) or \
                (k[-1] < 25 and d[-1] < 25 and j[-1] < 75):
            if (j[-2] < k[-2] or j[-2] < d[-2]) and (j[-1] > k[-1] and j[-1] > d[-1]) \
                    or \
                    (j[-2] > k[-2] or j[-2] > d[-2]) and (j[-1] < k[-1] and j[-1] < d[-1]):
                has_kdj_recore = True
                t = bar.datetime
                self.kdj_record.append(
                    (t.strftime("%H:%M:%S"), round(k[-1], 3), round(d[-1], 3),
                     round(j[-1], 3)))

        deg1 = calc_regress_deg(am.close[offset:offset_m], False)
        deg2 = calc_regress_deg(am.close[offset_m:], False)
        deg3 = calc_regress_deg(am.close[-10:], False)
        deg_full = calc_regress_deg(am.close[offset:], False)

        macd = am.macd(20, 40, 16)

        calc_data = (dict(
            kdj=[
                round(kdj_val["k"][-1], 2),
                round(kdj_val["d"][-1], 2),
                round(kdj_val["j"][-1], 2)
            ],
            cci_20=am.cci(20),
            rsi=am.rsi(20),
            adx=am.adx(20),
            boll=am.boll(20, 3.4),
            macd=[round(macd[0], 2),
                  round(macd[1], 2),
                  round(macd[2], 2)],
            deg40_20=round(deg1, 2),
            deg20_0=round(deg2, 2),
            deg20_10=round(calc_regress_deg(am.close[-20:-10], False), 2),
            deg30_15=round(calc_regress_deg(am.close[-30:-15], False), 2),
            deg15_0=round(calc_regress_deg(am.close[-15:], False), 2),
            deg_f=round(deg_full, 2),
            deg30_10=round(calc_regress_deg(am.close[-30:-10], False), 2),
            deg10_0=round(deg3, 2),
            atr=round(am.atr(10, length=15), 3),
            tr=round(am.atr(1, length=2), 3),
            atr_40=round(am.atr(40, length=42), 3),
            time=bar.datetime,
            price=bar.close_price,
            mean_std=np.mean(self.std_range.data[-5:]),
            vol=am.volume[-1],
            std_range=self.std_range.data[-1:-5:-1],
            range=am.range[-1:-5:-1].tolist(),
            range_sum=np.sum(am.range[-5:]),
            pattern=list(
                map(lambda x: KLINE_PATTERN_CHINESE[x],
                    self.pattern_record.keys())),
            atr_mean=np.mean(am.atr(20, array=True, length=240)[-200:]),
        ))
        if self.ma_info.info.index.size >= 31:
            ma5 = self.ma_info.info[5][-31:]
            x = AnalyseWave(ma5)
            calc_data["ma5_info"] = x.optimize
            ma10 = self.ma_info.info[10][-31:]
            x = AnalyseWave(ma10)
            calc_data["ma10_info"] = x.optimize
        return calc_data
Exemple #9
0
class Aberration_V2_Strategy(CtaTemplate):
    """
    1、v1基础版上,调整了开仓进场条件为布林带收口。
    2、去掉cci
    """
    author = "yunya"

    open_window = 15
    boll_length = 440
    boll_dev = 1.8
    fixed_size = 1

    boll_up = 0
    boll_up_last = 0
    boll_down = 0
    boll_down_last = 0
    boll_mid = 0
    boll_mid_new = 0
    boll_mid_array = 0
    boll_length_new = 0
    exit_long_nex = 0
    exit_long_last = 0
    exit_short_nex = 0
    exit_short_last = 0
    bbw_min = 0
    bbw_ma = 0
    bbw = 0

    amplitude = 0
    stop_time = 8
    time_stop = 0
    amplitude_inited = False

    # 画图专用
    time_list = []
    open_list = []
    high_list = []
    low_list = []
    close_list = []
    volume_list = []
    up_list = []
    down_list = []
    mid_list = []
    mid_new_list = []
    bias_value_list = []
    bias_list = []
    singnal_plot = []
    singnal_list = None
    singnal = None

    plot_echarts = {}

    parameters = [
        "open_window",
        "boll_length",
        "boll_dev",
        "bias",
        "cci_length",
        "cci_exit",
        "fixed_size",
    ]

    variables = [
        "boll_up",
        "boll_down",
        "boll_mid",
        "bias_value",
        "cci_value",
        "exit_long",
        "exit_short",
        "boll_length_new",
        "exit_long_nex",
        "exit_long_last",
        "exit_short_nex",
        "exit_short_last",
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.bg = BarGenerator(self.on_bar, self.open_window, self.on_xmin_bar)
        self.am = ArrayManager(int(self.boll_length) * 2)

        self.boll_length_new = self.boll_length

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)

    def on_xmin_bar(self, bar: BarData):
        """"""
        self.cancel_all()

        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return

        # 计算原布林带
        boll_up_array, boll_down_array = self.am.boll(self.boll_length,
                                                      self.boll_dev, True)
        boll_mid_array = am.sma(self.boll_length, True)

        self.boll_up = boll_up_array[-1]
        self.boll_up_last = boll_up_array[-2]
        self.boll_down = boll_down_array[-1]
        self.boll_down_last = boll_down_array[-2]
        self.boll_mid = boll_mid_array[-1]

        #   计算布林宽度
        bbw_array = (boll_up_array - boll_down_array) / boll_mid_array
        bbw_length = int(self.boll_length / 2)
        self.bbw_min = bbw_array[-bbw_length - 1:-1].min()
        self.bbw_ma = bbw_array[-bbw_length - 1:-1].mean()
        self.bbw = bbw_array[-1]

        #   计算新中轨
        close_short = am.close[-1] < am.close[-2]
        close_long = am.close[-1] > am.close[-2]
        if close_short or close_long:
            self.boll_length_new -= 1
            self.boll_length_new = max(self.boll_length_new, 10)
        self.boll_mid_new = am.sma(self.boll_length_new, True)

        # 如果没有仓位,两条布林window一样
        if self.pos == 0:
            self.exit_long_nex = 0
            self.exit_long_last = 0
            self.exit_short_nex = 0
            self.exit_short_last = 0
            self.boll_length_new = self.boll_length

            if self.bbw > self.bbw_min and self.bbw_min < self.bbw_ma:
                if self.am.close[-1] > self.boll_up and self.am.close[
                        -2] <= self.boll_up_last:
                    self.buy(bar.close_price, self.fixed_size)

                elif self.am.close[-1] < self.boll_up and self.am.close[
                        -2] >= self.boll_up_last:
                    self.short(bar.close_price, self.fixed_size)

        elif self.pos > 0:

            # 仓位是long 时,如果价格上穿新布林中轨
            con1 = am.close[-1] < self.boll_mid_new[-1]
            con2 = am.close[-2] >= self.boll_mid_new[-2]

            if con1 and con2:
                self.exit_long_nex = am.close[-1]  # 保存当前收盘价
                if self.exit_long_nex > self.exit_long_last or self.exit_long_last == 0:
                    self.exit_long_last = self.exit_long_nex
                    self.boll_length_new = self.boll_length - 10
                    # 下穿新均线,以原布林均线挂出停止单,避免快速下跌而无法止损
                    self.exit_long = self.boll_mid
                    # print(f"我是多单,exitlast:{self.exit_short_last},重置布林中轨参数,止损挂{self.exit_long}:")
                else:
                    # 收盘价在两条均线平均价上方,以当前收盘价挂出限价单
                    if self.am.close[-1] > (
                        (self.boll_mid + self.boll_mid_new[-1]) / 2):
                        self.exit_long = bar.close_price
                        # print(f"我是多单,收盘价在两个中轨均值上方,以收盘价挂止损单:{self.exit_long}")
                    elif bar.close_price < self.boll_mid:
                        self.exit_long = bar.close_price
                    else:
                        self.exit_long = self.boll_mid
                        # print(f"我是多单,收盘价在两个中轨均值下方,以原中轨挂止损单:{self.exit_long},")
            else:
                self.exit_long = self.boll_mid
                # print(f"我是多单,收盘价在新中轨上方,以原中轨挂止损单:{self.exit_long}")

            self.sell(self.exit_long, abs(self.pos), True)

        elif self.pos < 0:
            # 仓位是short 时,如果价格上穿新布林中轨
            con3 = am.close[-1] > self.boll_mid_new[-1]
            con4 = am.close[-2] <= self.boll_mid_new[-2]

            if con3 and con4:
                self.exit_short_nex = am.close[-1]
                if self.exit_short_nex < self.exit_short_last or self.exit_short_last == 0:
                    self.exit_short_last = self.exit_short_nex
                    self.boll_length_new = self.boll_length - 10

                    self.exit_short = self.boll_mid
                else:
                    if self.am.close[-1] < (self.boll_mid +
                                            self.boll_mid_new[-1] / 2):
                        self.exit_short = bar.close_price

                    elif bar.close_price > self.boll_mid:
                        self.exit_short = bar.close_price

                    else:
                        self.exit_short = self.boll_mid
            else:
                self.exit_short = self.boll_mid

            self.cover(self.exit_short, abs(self.pos), True)

        # 画图专用
        if self.singnal != self.singnal_list:
            plot = self.singnal
        else:
            plot = None

        self.time_list.append(bar.datetime)
        self.open_list.append(bar.open_price)
        self.high_list.append(bar.high_price)
        self.low_list.append(bar.low_price)
        self.close_list.append(bar.close_price)
        self.volume_list.append(bar.volume)
        self.up_list.append(self.boll_up)
        self.down_list.append(self.boll_down)
        self.mid_list.append(self.boll_mid)
        self.mid_new_list.append(self.boll_mid_new[-1])
        self.singnal_plot.append(plot)

        self.plot_echarts = {
            "datetime": self.time_list,
            "open": self.open_list,
            "high": self.high_list,
            "low": self.low_list,
            "close": self.close_list,
            "volume": self.low_list,
            "boll_up": self.up_list,
            "boll_down": self.down_list,
            "boll_mid": self.mid_list,
            "boll_mid_new": self.mid_new_list,
            "bias": self.bias_value_list,
            "bias_value": self.bias_list,
            "signal": self.singnal_plot
        }
        self.singnal_list = self.singnal

        self.put_event()
        self.sync_data()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        self.put_event()
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """

        #   画图专用
        if trade.direction.value == Direction.LONG.value:
            if trade.offset.value == Offset.OPEN.value:
                self.singnal = 1

            elif trade.offset.value == Offset.CLOSE.value:
                self.singnal = 0

            else:
                self.singnal = None

        elif trade.direction.value == Direction.SHORT.value:
            if trade.offset.value == Offset.OPEN.value:
                self.singnal = -1

            elif trade.offset.value == Offset.CLOSE.value:
                self.singnal = 0

            else:
                self.singnal = None

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        self.put_event()
        pass
    def generate_data(self, am:ArrayManager, bar:BarData):
        offset = -self.offset
        offset_m = int(offset / 2)
        calc_nums = np.array(self.ma_tag[-offset:-1])
        # var_val = np.var(calc_nums)
        std_val = np.std(calc_nums)
        std_val2 = np.std(np.array(self.ma_tag[-10:-1]))
        std_val3 = np.std(np.array(am.range[-30:-10]))
        ma = self.ma_tag[-1]
        
        mean_val = np.mean(calc_nums)
        mean_val2 = np.mean(np.array(self.ma_tag[-5:-1]))
        mean_val3 = np.mean(np.array(self.ma_tag[-20:-1]))
        mean_val4 = np.mean(np.array(self.ma_tag[-30:-5]))
        
        kdj_val = am.kdj()
        has_kdj_recore = False
        k = kdj_val["k"]
        d = kdj_val["d"]
        j = kdj_val["j"]
        if  (k[-1] > 75 and d[-1] > 75 and j[-1] > 75) or \
            (k[-1] < 25 and d[-1] < 25 and j[-1] < 75):
            if (j[-2] < k[-2] or j[-2] < d[-2]) and (j[-1] > k[-1] and j[-1] > d[-1]) \
                or \
            (j[-2] > k[-2] or j[-2] > d[-2]) and (j[-1] < k[-1] and j[-1] < d[-1]):
                has_kdj_recore = True
                t = local_to_eastern(bar.datetime.timestamp())
                self.kdj_record.append((t.strftime("%H:%M:%S"), round(k[-1], 3), round(d[-1], 3), round(j[-1], 3)))

        
        deg1 = calc_regress_deg(am.close[offset : offset_m], False)
        deg2 = calc_regress_deg(am.close[offset_m :], False)
        deg3 = calc_regress_deg(am.close[-10 :], False)
        deg_full = calc_regress_deg(am.close[offset :], False)

        wave = self.wave(am.close[-30:])
        wave_r_sum = np.sum(wave["range"])


        macd=am.macd(20,40, 16)
        calc_data = (dict(
                ma_info=self.ma_info[-1:],
                kdj=[round(kdj_val["k"][-1],2),round(kdj_val["d"][-1],2),round(kdj_val["j"][-1],2)],
                cci_20=am.cci(20),rsi=am.rsi(20),adx=am.adx(20),boll=am.boll(20, 3.4),
                macd=[round(macd[0],2),round(macd[1],2),round(macd[2],2)],
                deg40_20=round(deg1,2), deg20_0=round(deg2,2), deg20_10=round(calc_regress_deg(am.close[-20:-10], False),2), 
                deg30_10=round(calc_regress_deg(am.close[-30:-10], False),2),deg10_0=round(deg3,2),
                deg30_15=round(calc_regress_deg(am.close[-30:-15], False),2), deg15_0=round(calc_regress_deg(am.close[-15:], False),2),deg_f=round(deg_full,2),
                atr=round(am.atr(10, length=15), 3), tr=round(am.atr(1, length=2), 3),atr_40=round(am.atr(40, length=42), 3),
                time=bar.datetime, price=bar.close_price, ma=round(ma, 2), 
                std_40=round(std_val, 2),mean40=round(mean_val,2), mean_std=np.mean(self.std_range.data[-5:]),
                std_10=round(std_val2,2), mean30_10=round(mean_val4,2), mean10=round(mean_val2,2),
                vol=am.volume[-1], std_range=self.std_range.data[-1:-5:-1], range=am.range[-1:-5:-1].tolist(),
                range_sum=np.sum(am.range[-5:]), 
                pattern=list(map(lambda x: KLINE_PATTERN_CHINESE[x], self.pattern_record.keys())),
                ma120t=self.ma120_track, 
                ma120t_list=self.ma120_track_list[-1:-10:-1], 
                ma120t_sort=sorted(self.ma120_track_list[-20:-1], key=abs),
                ma120t_sum=np.sum(self.ma120_track_list[-20:-1] + [self.ma120_track]), 
                ma120t_mean=np.mean(self.ma120_track_list[-20:-1] + [self.ma120_track]),
                ma120t_std=np.std(self.ma120_track_list[-20:-1] + [self.ma120_track]),
                wave_cnt=len(wave), wave_r_sum=wave_r_sum, atr_mean=np.mean(am.atr(20, array=True,length=240)[-200:]),
                kdj_record=self.kdj_record[-10:],
                ))
        if self.ma_info[-1]["ma5"] <= 0.16:
            calc_data["kdj_key"] = True
        return calc_data
class MacdRsibollDcMinuteStrategy(CtaTemplate):
	"""
	策略逻辑:
	一、、过虑信号  (小时周期)
	1、使用macd 快慢线交叉来判断多空大方向。
	2、使用rsiboll来判断信号强弱

	二、开单信号 (分钟周期)
	1、使用布林上下轨作为开单条件

	三、止损
	1、使用固定止损
	2、dc 移动止损
	3、布林宽度比例
	三个止损相结合的方式
	"""
	author = "yunya"

	max_window = 45
	min_window = 15
	open_window = 5
	fast_macd = 12
	slow_macd = 26
	signal_macd = 9
	macd_trend_level = 1.0
	rsi_length = 15
	boll_length = 20
	boll_dev = 2.0
	dc_length = 20
	atr_window = 30
	trailing_tax = 2.0
	risk_level = 1

	exit_down = 0
	exit_up = 0
	macd = 0
	macd_entry = 0
	rsi_entry = 0
	intra_trade_high = 0
	intra_trade_low = 0
	long_stop = 0
	short_stop = 0
	atr_value = 0

	parameters = [
		"max_window",
		"min_window",
		"open_window",
		"fast_macd",
		"slow_macd",
		"signal_macd",
		"macd_trend_level",
		"boll_length",
		"boll_dev",
		"rsi_length",
		"dc_length",
		"atr_window",
		"trailing_tax",
		"risk_level",
	]

	variables = [
		"exit_down",
		"exit_up",
		"macd",
		"macd_entry",
		"rsi_entry",
		"intra_trade_high",
		"intra_trade_low",
		"long_stop",
		"short_stop",
		"atr_value",
	]

	def __init__(
			self,
			cta_engine: Any,
			strategy_name: str,
			vt_symbol: str,
			setting: dict,
	):
		""""""
		super().__init__(cta_engine, strategy_name, vt_symbol, setting)
		self.atr_stop_array = np.zeros(10)

		
		self.bg_xhour = NewBarGenerator(
			on_bar=self.on_bar,
			window=self.max_window,
			on_window_bar=self.on_xhour_bar,
			interval=Interval.MINUTE   # 由小时修改到分钟级
		)
		self.am_hour = ArrayManager(self.boll_length + 100)

		self.bg_xminute = NewBarGenerator(
			on_bar=self.on_bar,
			window=self.min_window,
			on_window_bar=self.on_xminute_bar
		)
		self.am_xminute = ArrayManager(self.boll_length + 100)

		self.bg_open = NewBarGenerator(
			on_bar=self.on_bar,
			window=self.open_window,
			on_window_bar=self.on_5min_bar
		)
		self.am_open = ArrayManager(self.dc_length * int(self.min_window / self.open_window) + 30)

	def on_init(self):
		"""
		Callback when strategy is inited.
		"""
		self.write_log("策略初始化。。")
		self.load_bar(10)

		self.put_event()

	def on_start(self):
		"""
		Callback when strategy is started.
		"""
		self.write_log("策略启动。。")
		self.put_event()

	def on_stop(self):
		"""
		Callback when strategy is stopped.
		"""
		self.write_log("策略停止。。")
		self.put_event()

	def on_tick(self, tick: TickData):
		"""
		Callback of new tick data update.
		"""
		self.bg_open.update_tick(tick)
		self.ask = tick.ask_price_1  # 卖一价
		self.bid = tick.bid_price_1  # 买一价

		self.put_event()

	def on_bar(self, bar: BarData):
		"""
		Callback of new bar data update.
		"""
		self.bg_xhour.update_bar(bar)
		self.bg_xminute.update_bar(bar)
		self.bg_open.update_bar(bar)

	def on_5min_bar(self, bar: BarData):

		self.cancel_all()
		self.am_open.update_bar(bar)

		if not self.am_open.inited or not self.am_xminute.inited or not self.am_hour.inited:
			return

		#
		self.exit_up, self.exit_down = self.am_open.donchian(
			self.dc_length * int(self.min_window / self.open_window))

		if not self.pos:

			self.intra_trade_high = bar.high_price
			self.intra_trade_low = bar.low_price

			if self.macd_entry > 0 and self.rsi_entry > 0:
				self.buy(self.boll_up, self.trading_size, True)
			# print(bar.datetime, self.boll_up, self.trading_size)
			# print(bar.datetime, self.entry_up, self.trading_size, bar)

			if self.macd_entry < 0 and self.rsi_entry < 0:
				self.short(self.boll_down, self.trading_size, True)

		elif self.pos > 0:
			self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
			long_high = self.intra_trade_high * \
			            (1 - self.trailing_tax / 100)
			self.long_stop = max(self.exit_down, long_high)
			self.sell(self.long_stop, abs(self.pos), True)

		elif self.pos < 0:
			self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
			short_low = self.intra_trade_low * \
			            (1 + self.trailing_tax / 100)
			self.short_stop = min(self.exit_up, short_low)
			self.cover(short_low, abs(self.pos), True)

		self.put_event()

	def on_xminute_bar(self, bar: BarData):
		"""
		:param bar:
		:return:
		"""
		self.am_xminute.update_bar(bar)
		if not self.am_hour.inited or not self.am_xminute.inited:
			return

		rsi_array = talib.RSI(self.am_xminute.close[:-1], self.rsi_length)
		ema_array = talib.EMA(self.am_xminute.close, self.rsi_length)

		dev_array = abs(self.am_xminute.close[:-1] - ema_array[:-1]) / rsi_array

		rsi_up_array = rsi_array + rsi_array * dev_array
		rsi_dow_array = rsi_array - rsi_array * dev_array

		self.rsi_value = self.am_xminute.rsi(self.rsi_length, True)
		self.rsi_up = rsi_up_array[-1]
		self.rsi_dow = rsi_dow_array[-1]

		current_rsi_up = rsi_up_array[-1]
		current_rsi_down = rsi_dow_array[-1]
		current_rsi_value = self.rsi_value[-1]

		if current_rsi_value > current_rsi_up:
			self.rsi_entry = 1
		elif current_rsi_value < current_rsi_down:
			self.rsi_entry = -1
		else:
			self.rsi_entry = 0

		self.boll_up, self.boll_down = self.am_xminute.boll(self.boll_length, self.boll_dev)

	def on_xhour_bar(self, bar: BarData):
		""""""
		am_hour = self.am_hour
		am_hour.update_bar(bar)

		if not am_hour.inited:
			return
		macd_signal, signal, hist = self.am_hour.macd(
			self.fast_macd,
			self.slow_macd,
			self.signal_macd
		)
		self.macd = signal - hist

		if self.macd > self.macd_trend_level:
			self.macd_entry = 1

		elif self.macd < (-self.macd_trend_level):
			self.macd_entry = -1
		else:
			self.macd_entry = 0

		# 动态调整仓位
		if not self.pos:
			self.atr_value = self.am_hour.atr(self.atr_window)

			if self.atr_value == 0:  # 保证仓位值是有效的
				return
			# 正向合约
			atr_risk = self.am_hour.atr(self.atr_window)
			self.trading_size = max(int(self.risk_level / atr_risk), 1)

		self.put_event()

	def on_trade(self, trade: TradeData):
		"""
		有成交时
		Callback of new trade data update.
		"""
		self.put_event()

	def on_order(self, order: OrderData):
		"""
		订单更新回调
		Callback of new order data update.
		"""

		self.put_event()

	def on_stop_order(self, stop_order: StopOrder):
		"""
		Callback of stop order update.
		"""
		self.put_event()
Exemple #12
0
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
Exemple #13
0
class RisBollStrategy(CtaTemplate):
    """
    目前使用中轨加速,可以考虑使用另外一根均线来加速,这样可以避免在开仓时被平。
    """
    author = "yunya"

    open_window = 15
    boll_length = 80
    boll_dev = 2.0
    rsi_window = 12
    rsi_entry = 19
    atr_window = 16
    long_trailing = 4.0
    short_trailing = 4.0
    fixed_size = 1

    rsi_long = 0
    rsi_short = 0
    rsi_value = 0
    atr_value = 0
    boll_up = 0
    boll_down = 0
    boll_mid = 0
    boll_mid_new = 0
    exit_long = 0
    exit_short = 0
    boll_length_new = 0
    exit_long_nex = 0
    exit_long_last = 0
    exit_short_nex = 0
    exit_short_last = 0
    long_stop_trade = 0
    short_stop_trade = 0
    trade_price_long = 0
    trade_price_short = 0

    parameters = [
                "open_window",
                "boll_length",
                "boll_dev",
                "rsi_window",
                "rsi_entry",
                "atr_window",
                "long_trailing",
                "short_trailing",
                "fixed_size",
                ]

    variables = [
            "rsi_long",
            "rsi_short",
            "rsi_value",
            "atr_value",
            "boll_up",
            "boll_down",
            "boll_mid",
            "boll_mid_new",
            "exit_long",
            "exit_short",
            "boll_length_new",
            "exit_long_nex",
            "exit_long_last",
            "exit_short_nex",
            "exit_short_last",
            "long_stop_trade",
            "short_stop_trade",
            "trade_price_long",
            "trade_price_short",
                ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.bg = NewBarGenerator(self.on_bar, self.open_window, self.on_xmin_bar)
        self.am = ArrayManager(int(self.boll_length) + 100)

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")

        self.rsi_long = 50 + self.rsi_entry
        self.rsi_short = 50 - self.rsi_entry

        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)

    def on_xmin_bar(self, bar: BarData):
        """"""
        self.cancel_all()

        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return

        # 计算原布林带
        self.boll_up, self.boll_down = self.am.boll(self.boll_length, self.boll_dev)
        self.boll_mid = am.sma(self.boll_length)
        self.rsi_value = am.rsi(self.rsi_window)

        # 如果没有仓位,两条布林window一样
        if self.pos == 0:
            self.atr_value = am.atr(self.atr_window)
            self.exit_long_nex = 0
            self.exit_long_last = 0
            self.exit_short_nex = 0
            self.exit_short_last = 0
            self.boll_length_new = self.boll_length

            if self.rsi_value > self.rsi_long:
                self.buy(self.boll_up, self.fixed_size, True)

            if self.rsi_value < self.rsi_short:
                self.short(self.boll_down, self.fixed_size, True)

        elif self.pos > 0:
            # 上涨或下跌时,布林中轨均值减1
            close_long = am.close[-1] > am.close[-2] > am.close[-3] > am.close[-4]

            if close_long:
                self.boll_length_new -= 1
                self.boll_length_new = max(self.boll_length_new, 10)

            # 计算新的布林带
            self.boll_mid_new = am.sma(self.boll_length_new, True)

            # 仓位是long 时,如果价格上穿新布林中轨
            con1 = am.close[-1] < self.boll_mid_new[-1]
            con2 = am.close[-2] >= self.boll_mid_new[-2]

            if con1 and con2:
                self.exit_long_nex = am.close[-1]  # 保存当前收盘价
                if self.exit_long_nex > self.exit_long_last or self.exit_long_last == 0:
                    self.exit_long_last = self.exit_long_nex
                    self.boll_length_new = self.boll_length
                    # 下穿新均线,以原布林均线挂出停止单,避免快速下跌而无法止损
                    self.exit_long = self.boll_mid

                else:
                    # 收盘价在两条均线平均价上方,以当前收盘价挂出限价单
                    if self.am.close[-1] > ((self.boll_mid + self.boll_mid_new[-1]) / 2):
                        self.exit_long = bar.close_price

                    elif bar.close_price < self.boll_mid:
                        self.exit_long = bar.close_price
                    else:
                        self.exit_long = self.boll_mid

            else:
                self.exit_long = self.boll_mid

            if bar.close_price < self.trade_price_long * (1 - self.long_trailing / 100):
                exit_long_price = self.trade_price_long * (1 - (self.long_trailing + 1) / 100)
                self.exit_long = max(exit_long_price, self.exit_long)

            self.exit_long = max(self.exit_long, self.long_stop_trade)
            self.sell(self.exit_long, abs(self.pos), True)

        elif self.pos < 0:
            close_short = am.close[-1] < am.close[-2] < am.close[-3] < am.close[-4]

            if close_short:
                self.boll_length_new -= 1
                self.boll_length_new = max(self.boll_length_new, 10)

            # 计算新的布林带
            self.boll_mid_new = am.sma(self.boll_length_new, True)

            # 仓位是short 时,如果价格上穿新布林中轨
            con3 = am.close[-1] > self.boll_mid_new[-1]
            con4 = am.close[-2] <= self.boll_mid_new[-2]

            if con3 and con4:
                self.exit_short_nex = am.close[-1]
                if self.exit_short_nex < self.exit_short_last or self.exit_short_last == 0:
                    self.exit_short_last = self.exit_short_nex
                    self.boll_length_new = self.boll_length

                    self.exit_short = self.boll_mid
                else:
                    if self.am.close[-1] < (self.boll_mid + self.boll_mid_new[-1] / 2):
                        self.exit_short = bar.close_price

                    elif bar.close_price > self.boll_mid:
                        self.exit_short = bar.close_price
                    else:
                        self.exit_short = self.boll_mid
            else:
                self.exit_short = self.boll_mid

            # 如果 有3%以上的收益,止损价为买入成交价
            if bar.close_price > self.trade_price_short * (1 + self.short_trailing / 100):
                exit_short_price = self.trade_price_short * (1 + (self.short_trailing + 1) / 100)
                self.exit_short = min(exit_short_price, self.exit_short)

            self.exit_short = min(self.exit_short, self.short_stop_trade)
            self.cover(self.exit_short, abs(self.pos), True)

        self.put_event()
        self.sync_data()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        self.put_event()
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        if trade.direction == Direction.LONG:
            self.trade_price_long = trade.price  # 成交最高价
            self.long_stop_trade = self.trade_price_long - 2 * self.atr_value
        else:
            self.trade_price_short = trade.price
            self.short_stop_trade = self.trade_price_short + 2 * self.atr_value

        self.sync_data()
        self.put_event()
Exemple #14
0
class CuatroStrategy(CtaTemplate):
    """"""

    author = "黄柠"

    # 定义参数
    boll_window = 20
    boll_dev = 2.0
    rsi_window = 14
    rsi_signal = 30
    fast_window = 5
    slow_window = 20
    trailing_long = 1.0
    trailing_short = 1.0
    fixed_size = 1

    # 定义变量
    boll_up = 0.0
    boll_down = 0.0
    rsi_value = 0.0
    rsi_long = 0.0
    rsi_short = 0.0
    fast_ma = 0.0
    slow_ma = 0.0
    ma_trend = 0
    intra_trade_high = 0.0
    intra_trade_low = 0.0
    long_stop = 0.0
    short_stop = 0.0

    parameters = [
        "boll_window",
        "boll_dev",
        "rsi_window", 
        "rsi_signal", 
        "fast_window",
        "slow_window", 
        "trailing_long",
        "trailing_short",
        "fixed_size"
    ]

    variables = [
        "boll_up",
        "boll_down",
        "rsi_value",
        "rsi_long",
        "rsi_short",
        "fast_ma",
        "slow_ma",
        "ma_trend",
        "intra_trade_high",
        "intra_trade_low",
        "long_stop",
        "short_stop"
    ]

    def __init__(
        self,
        cta_engine: Any,
        strategy_name: str,
        vt_symbol: str,
        setting: dict,
    ):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.rsi_long = 50 + self.rsi_signal
        self.rsi_short = 50 - self.rsi_signal
        
        self.bg5 = BarGenerator(self.on_bar, 5, self.on_5min_bar)
        self.bg15 = BarGenerator(self.on_bar, 15, self.on_15min_bar)

        self.am5 = ArrayManager()
        self.am15 = ArrayManager()

    
    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    
    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    
    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    
    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg5.update_tick(tick)

    
    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg5.update_bar(bar)
        self.bg15.update_bar(bar)


    def on_5min_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.cancel_all()

        self.am5.update_bar(bar)
        if not self.am5.inited or not self.am15.inited:
            return

        self.boll_up, self.boll_down = self.am5.boll(self.boll_window, self.boll_dev)
        self.rsi_value = self.am5.rsi(self.rsi_window)
        boll_width = self.boll_up - self.boll_down

        engine_type = self.get_engine_type()

        if self.pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low =  bar.low_price
            self.long_stop = 0
            self.short_stop = 0

            if self.ma_trend > 0 and self.rsi_value >= self.rsi_long:
                if engine_type == EngineType.BACKTESTING:
                    self.buy(self.boll_up, self.fixed_size, stop=True)
                else:
                    self.buy(self.boll_up, self.fixed_size, stop=True, lock=True)

            if self.ma_trend <= 0 and self.rsi_value <= self.rsi_short:
                if engine_type == EngineType.BACKTESTING:
                    self.short(self.boll_down, self.fixed_size, stop=True)
                else:
                    self.short(self.boll_down, self.fixed_size, stop=True, lock=True)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.long_stop = (self.intra_trade_high - self.trailing_long * boll_width)
            self.sell(self.long_stop, abs(self.pos), stop=True)
            
        else:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.short_stop= (self.intra_trade_low + self.trailing_short * boll_width)
            self.cover(self.short_stop, abs(self.pos), stop=True)

        self.put_event()


    def on_15min_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.am15.update_bar(bar)
        if self.am15.inited:
            return

        self.fast_ma = self.am15.sma(self.fast_window)
        self.slow_ma =  self.am15.sma(self.slow_window)

        if self.fast_ma > self.slow_ma:
            self.ma_trend = 1
        elif self.fast_ma <= self.slow_ma:
            self.ma_trend = 0

        self.put_event()


    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.put_event()

    
    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        self.put_event()

    
    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        self.put_event()
Exemple #15
0
class MaLevelTrackStrategy(CtaTemplate):
    author = "用Python的交易员"

    ma_level = [5, 10, 20, 30, 120]
    ma_tag = []
    bd = []
    fast_ma0 = 0.0
    fast_ma1 = 0.0

    slow_ma0 = 0.0
    slow_ma1 = 0.0
    request_order = []
    bar_identify = []

    parameters = ["ma_level"]
    variables = ["fast_ma0", "fast_ma1", "slow_ma0", "slow_ma1"]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(MaLevelTrackStrategy, self).__init__(cta_engine, strategy_name,
                                                   vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar, 15, self.on_1min_bar)
        self.am = ArrayManager(400)
        self.am3 = ArrayManager(150)
        self.bg3 = BarGenerator(self.on_bar, 3, self.on_3min_bar)
        self.am5 = ArrayManager(120)
        self.bg5 = BarGenerator(self.on_bar, 5, self.on_5min_bar)
        self.order_data = None
        self.positions = Position(self)
        self.std_range = IntervalGen(np.std, 5)
        self.std_range3 = IntervalGen(np.std, 5)
        self.std_range5 = IntervalGen(np.std, 5)
        self.pattern_record = PatternRecord()
        # self.pattern_record.set_expiry([KlinePattern.CDLEVENINGSTAR], 3)
        self.pattern_record.set_expiry(list(KlinePattern), 1)

        five_min_open_5 = partial(self.reverse_shape_strategy,
                                  setting={
                                      "atr": 10,
                                      "atr_valve": 0.8,
                                      "deg1": (10, 5),
                                      "deg2": 5
                                  })
        self.open_strategy = {
            "1": [self.reverse_shape_strategy],
            "5": [five_min_open_5],
        }
        self.offset = 40
        self.ma120_track = None
        self.ma120_track_list = []

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")
        self.put_event()

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

        self.put_event()

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)
        self.bg3.update_tick(tick)
        self.bg5.update_tick(tick)

    def on_3min_bar(self, bar: BarData):
        self.am3.update_bar(bar)
        self.std_range3.update(self.am3.range[-1])
        if not self.am.inited or not self.trading:
            return
        pattern = self.am3.pattern(
            [KlinePattern.CDLEVENINGSTAR, KlinePattern.CDL2CROWS])

        if len(pattern) > 0:
            print(pattern)
            self.pattern_record.add_pattern(pattern)
            # deg = calc_regress_deg(self.am3.close[-20:])

    def wave(self, data, window=0.0002):

        if len(data) <= 0:
            return
        # r = array[::-1]
        result = {"value": [], "range": [], "pos": [], "length": []}
        r = data
        l = len(data) - 1
        now = r[0]
        # v_list.append(now)
        # p_list.append(0)
        pos = 1

        vol = 0
        u_tag = None
        d_tag = None
        end_tag = None
        start_pos = 0
        while pos < l:
            if math.isnan(now):
                now = r[pos]
                pos += 1
                continue
            else:
                start_pos = pos - 1
                break

        while pos < l:

            if now < r[pos]:
                u_tag = pos
                if d_tag:
                    diff = r[start_pos] - r[d_tag]
                    if abs(diff /
                           r[start_pos]) > window and d_tag - start_pos > 1:
                        end_tag = d_tag

            elif now > r[pos]:
                d_tag = pos
                if u_tag:
                    diff = r[start_pos] - r[u_tag]
                    if abs(diff /
                           r[start_pos]) > window and d_tag - start_pos > 1:
                        end_tag = u_tag

            if end_tag is not None:
                result["range"].append(r[end_tag] / r[start_pos] - 1)
                result["length"].append(end_tag - start_pos)
                start_pos = end_tag
                result["value"].append(r[end_tag])
                result["pos"].append(end_tag)
                end_tag = None

            vol += r[pos] - now
            now = r[pos]
            pos += 1
        return pd.DataFrame(result)

    def mode_identify(self, bar: BarData):
        self.bar_identify = []
        hl_scale = round(bar.high_price / bar.low_price - 1, 4)
        if hl_scale > 0.001:
            diff = bar.high_price - bar.low_price
            diff_up = bar.low_price + diff / 2 * 1.20
            diff_down = bar.low_price + diff / 2 * 0.80
            close = bar.close_price
            if bar.open_price < diff_up and bar.open_price > diff_down and \
               bar.close_price < diff_up and bar.close_price > diff_down:
                if bar.close_price > bar.open_price:
                    print("绿十字星", bar.datetime, bar.high_price, bar.low_price,
                          diff, diff_up, diff_down, bar.open_price,
                          bar.close_price)
                else:
                    print("红十字星", bar.datetime, bar.high_price, bar.low_price,
                          diff, diff_up, diff_down, bar.open_price,
                          bar.close_price)

    def on_5min_bar(self, bar: BarData):
        self.std_range5.update(self.am5.range[-1])
        self.am5.update_bar(bar)
        if not self.am.inited or not self.trading:
            return

        self.on_strategy(self.am5, bar, self.open_strategy["5"])
        # pattern_list = [KlinePattern.CDLEVENINGSTAR, KlinePattern.CDL2CROWS, KlinePattern.CDLCONCEALBABYSWALL, KlinePattern.CDLEVENINGDOJISTAR]

    #     pattern = self.am5.pattern(list(KlinePattern))
    #     if len(pattern) > 0:
    #         print(list(map(lambda x: (KLINE_PATTERN_CHINESE[x[0]],x[1]), pattern)))
    #         self.pattern_record.add_pattern(pattern)
    #         deg_full = calc_regress_deg(self.am.close[-40 :], False)
    #         print("deg:",deg_full)

    #     self.pattern_record.update()

    def open_v3(self, am: ArrayManager, bar: BarData):
        std_val2 = np.std(np.array(self.ma_tag[-10:-1]))
        mean_val2 = np.mean(np.array(self.ma_tag[-10:-1]))
        mean = np.mean(np.array(self.ma_tag[-30:-10]))

        if std_val2 < 0.2:
            if mean_val2 > 3:
                if mean_val2 >= (mean + 1):
                    return self.buy(bar.close_price, 1, type=OrderType.MARKET)
            elif mean_val2 < 2:
                if mean_val2 <= (mean - 1):
                    return self.short(bar.close_price,
                                      1,
                                      type=OrderType.MARKET)

    def open_v1(self, am: ArrayManager, bar: BarData):
        offset = -40
        offset_m = int(offset / 2)
        calc_nums = np.array(self.ma_tag[-offset:-1])
        mean_val = np.mean(calc_nums)
        # var_val = np.var(calc_nums)
        std_val = np.std(calc_nums)
        if std_val < 1 and mean_val < 2 and self.ma_tag[-1] >= (mean_val + 2):
            return self.buy(bar.close_price, 1, type=OrderType.MARKET)
        elif std_val < 1 and mean_val > 3 and self.ma_tag[-1] <= (mean_val -
                                                                  2):
            return self.short(bar.close_price, 1, type=OrderType.MARKET)

    def open_v2(self, am: ArrayManager, bar: BarData):
        std_val2 = np.std(np.array(self.ma_tag[-10:-1]))
        mean_val2 = np.mean(np.array(self.ma_tag[-10:-1]))
        mean = np.mean(np.array(self.ma_tag[-30:-10]))

        if std_val2 < 0.2:
            if mean_val2 > 2.5:
                if mean_val2 >= (mean + 1):
                    return self.buy(bar.close_price, 1, type=OrderType.MARKET)
            elif mean_val2 < 2.5:
                if mean_val2 <= (mean - 1):
                    return self.short(bar.close_price,
                                      1,
                                      type=OrderType.MARKET)

    def open2(self, am: ArrayManager, bar: BarData, calc_data):
        deg = calc_data["deg20"]
        ma = self.ma_tag[-1]
        if deg > 0.5 and ma > 3 and self.am5.range[-1] > -0.002:
            return self.buy(bar.close_price, 1, type=OrderType.MARKET)
        elif deg < -0.5 and ma < 2 and self.am5.range[-1] < 0.002:
            return self.short(bar.close_price, 1, type=OrderType.MARKET)

    def open1(self, am: ArrayManager, bar: BarData, calc_data):

        mean = calc_data["mean30_10"]
        mean_val2 = calc_data["mean10"]
        # if std_val2 < 0.2:
        if mean_val2 > 3.5 and mean_val2 >= (mean + 2):
            return self.buy(bar.close_price, 1, type=OrderType.MARKET)
        elif mean_val2 < 1.5 and mean_val2 <= (mean - 2):
            return self.short(bar.close_price, 1, type=OrderType.MARKET)

    # v形反转捕获
    def reverse_shape_strategy(self,
                               am: ArrayManager,
                               bar: BarData,
                               calc_data,
                               setting={
                                   "atr": 40,
                                   "atr_valve": 0.8,
                                   "deg1": (40, 20),
                                   "deg2": (20, 0),
                               }):

        deg1 = calc_data["deg40_20"]
        deg2 = calc_data["deg20_0"]
        kdj = calc_data["kdj"]

        atr = self.am.atr(40)

        if atr < 0.08:
            return

        if deg1 > 0 and deg2 > 0 or \
           deg1 < 0 and deg2 < 0:
            return

        if not (abs(deg1) > 0.15 and abs(deg2) > 0.1 and
                (abs(deg1) + abs(deg2)) > 0.3):
            return

        close = am.close[-40:]
        min_val = np.min(close)
        max_val = np.max(close)
        mid_val = max_val if deg1 > 0 else min_val
        mid_pos = np.where(close == mid_val)[0][0]

        if mid_pos < 10 or mid_pos > 30:
            return

        start_val = np.min(close[:mid_pos]) if deg1 > 0 else np.max(
            close[:mid_pos])
        start_pos = np.where(close == start_val)[0][0]
        l = mid_pos - start_pos

        # pos2 = np.where(close == min_val)[0][0]

        x_fit = reg_util.regress_y_polynomial(close[:mid_pos], zoom=True)
        deg1_remake = calc_regress_deg(x_fit[:abs(mid_pos)], False)
        y_fit = reg_util.regress_y_polynomial(close[mid_pos:], zoom=True)
        deg2_remake = calc_regress_deg(y_fit[:abs(mid_pos)], False)
        print(start_pos, mid_pos, deg1, deg2, deg1_remake, deg2_remake, l,
              start_val, mid_val)
        if deg2 < 0:
            if kdj[0] < 20 and kdj[1] < 10 and kdj[2] < 10:
                # if kdj[2] < 10:
                return self.short(bar.close_price, 1, type=OrderType.MARKET)
        else:
            if kdj[0] > 80 and kdj[1] > 90 and kdj[2] > 90:
                # if kdj[2] > 90:
                return self.buy(bar.close_price, 1, type=OrderType.MARKET)

        # print("找到大v形:", deg1, deg2 )

    def open5(self, am: ArrayManager, bar: BarData, calc_data):

        ma = self.ma_tag[-1]
        mean = calc_data["mean30_10"]
        atr = self.am.atr(10, array=True, length=20)
        tr = self.am.atr(1, array=True, length=11)
        # self.ma120_track
        ma120 = self.am.sma(120)
        # if std_val2 < 0.2:
        mean_std = calc_data["mean_std"]
        if mean_std < 0.8 and tr[-1] > 0.1 and tr[-1] / tr[-10] > 3 and tr[
                -1] / atr[-1] >= 1.7 and tr[-10] / atr[-10] < 1:
            if np.sum(self.am.range[-10:]) > 0 and self.ma120_track > 0:
                return self.buy(bar.close_price, 1, type=OrderType.MARKET)
            elif self.ma120_track < 0:
                return self.short(bar.close_price, 1, type=OrderType.MARKET)

    def open_kline1(self, am: ArrayManager, bar: BarData, calc_data):

        if KlinePattern.CDLEVENINGSTAR not in self.pattern_record:
            return
        # if std_val2 < 0.2:
        deg = calc_regress_deg(self.am.close[-5:], False)
        print("kline_strategy", deg)
        if deg < -0.1:
            return self.short(bar.close_price, 1, type=OrderType.MARKET)

    def generate_data(self, bar: BarData):
        offset = -self.offset
        offset_m = int(offset / 2)
        calc_nums = np.array(self.ma_tag[-offset:-1])
        # var_val = np.var(calc_nums)
        std_val = np.std(calc_nums)
        std_val2 = np.std(np.array(self.ma_tag[-10:-1]))
        std_val3 = np.std(np.array(self.am.range[-30:-10]))
        ma = self.ma_tag[-1]

        mean_val = np.mean(calc_nums)
        mean_val2 = np.mean(np.array(self.ma_tag[-5:-1]))
        mean_val3 = np.mean(np.array(self.ma_tag[-20:-1]))
        mean_val4 = np.mean(np.array(self.ma_tag[-30:-5]))
        kdj_val = self.am.kdj()

        deg1 = calc_regress_deg(self.am.close[offset:offset_m], False)
        deg2 = calc_regress_deg(self.am.close[offset_m:], False)
        deg3 = calc_regress_deg(self.am.close[-10:], False)
        deg_full = calc_regress_deg(self.am.close[offset:], False)

        wave = self.wave(self.am.close[-30:])
        wave_r_sum = np.sum(wave["range"])
        macd = self.am.macd(20, 40, 16)
        calc_data = (dict(
            kdj=[
                round(kdj_val["k"][-1], 2),
                round(kdj_val["d"][-1], 2),
                round(kdj_val["j"][-1], 2)
            ],
            cci_20=self.am.cci(20),
            rsi=self.am.rsi(20),
            adx=self.am.adx(20),
            boll=self.am.boll(20, 3.4),
            macd=[round(macd[0], 2),
                  round(macd[1], 2),
                  round(macd[2], 2)],
            deg40_20=round(deg1, 2),
            deg20_0=round(deg2, 2),
            deg20_10=round(calc_regress_deg(self.am.close[-20:-10], False), 2),
            deg10_0=round(deg3, 2),
            deg30_15=round(calc_regress_deg(self.am.close[-30:-15], False), 2),
            deg15_0=round(calc_regress_deg(self.am.close[-15:], False), 2),
            deg_f=round(deg_full, 2),
            atr=round(self.am.atr(10, length=15), 3),
            tr=round(self.am.atr(1, length=2), 3),
            atr_40=round(self.am.atr(40, length=42), 3),
            time=bar.datetime,
            price=bar.close_price,
            ma=round(ma, 2),
            std_40=round(std_val, 2),
            mean40=round(mean_val, 2),
            mean_std=np.mean(self.std_range.data[-5:]),
            std_10=round(std_val2, 2),
            mean30_10=round(mean_val4, 2),
            mean10=round(mean_val2, 2),
            vol=self.am.volume[-1],
            std_range=self.std_range.data[-1:-5:-1],
            range=self.am.range[-1:-5:-1].tolist(),
            range_sum=np.sum(self.am.range[-5:]),
            pattern=list(
                map(lambda x: KLINE_PATTERN_CHINESE[x],
                    self.pattern_record.keys())),
            ma120t=self.ma120_track,
            ma120t_list=self.ma120_track_list[-1:-10:-1],
            ma120t_sort=sorted(self.ma120_track_list[-20:-1], key=abs),
            ma120t_sum=np.sum(self.ma120_track_list[-20:-1] +
                              [self.ma120_track]),
            ma120t_mean=np.mean(self.ma120_track_list[-20:-1] +
                                [self.ma120_track]),
            ma120t_std=np.std(self.ma120_track_list[-20:-1] +
                              [self.ma120_track]),
            wave_cnt=len(wave),
            wave_r_sum=wave_r_sum,
            atr_mean=np.mean(self.am.atr(20, array=True, length=240)[-200:])))

        return calc_data

    def on_strategy(self, am: ArrayManager, bar: BarData, strategy_list):
        calc_data = self.generate_data(bar)

        order_id = None
        if self.pos == 0:
            for open_strategy in strategy_list:
                if order_id is not None:
                    break
                order_id = open_strategy(am, bar, calc_data)
        else:
            order_id = self.positions.on_strategy(bar, calc_data)

        if order_id is not None:
            offset = -self.offset
            offset_m = int(offset / 2)
            self.tracker["trade_info"].append(
                (self.am.time_array[offset], self.am.time_array[offset_m],
                 bar.datetime, calc_data["deg40_20"], calc_data["deg20_0"]))
            self.request_order.extend(order_id)

        if self.tracker is not None:
            self.tracker["ma_tag_ls"].append(calc_data)

    def on_1min_bar(self, bar: BarData):
        self.am.update_bar(bar)
        am = self.am
        max_len = self.ma_level[-1] + 20
        data = self.am.close[-max_len:-1]
        ma_lvl = []
        for i in self.ma_level:
            ma = self.am.sma(i, True)[-1]
            ma_lvl.append(ma)

        l = len(ma_lvl)
        ma_lvl_tag = []
        now = bar.close_price
        direction = 1 if now > ma_lvl[0] else 0
        ma_lvl_tag.append(direction)
        for i in range(l - 1):
            val = 1 if ma_lvl[i] > ma_lvl[i + 1] else 0
            ma_lvl_tag.append(val)
        bincount_val = np.bincount(np.array(ma_lvl_tag))
        tag_val = 0
        if len(bincount_val) == 2:
            tag_val = bincount_val[1]

        if len(self.ma_tag) < 200:
            self.ma_tag.append(tag_val)
        else:
            self.ma_tag[:-1] = self.ma_tag[1:]
            self.ma_tag[-1] = tag_val
        if self.tracker is not None:
            self.tracker["bar_data"].append(bar)
        self.std_range.update(self.am.range[-1])

        ma120 = self.am.sma(120)

        if bar.close_price >= ma120:
            if self.ma120_track is None:
                self.ma120_track = 1
            elif self.ma120_track > 0:
                self.ma120_track += 1
            else:
                self.ma120_track_list.append(self.ma120_track)
                self.ma120_track = 1
        elif bar.close_price < ma120:
            if self.ma120_track is None:
                self.ma120_track = -1
            elif self.ma120_track < 0:
                self.ma120_track -= 1
            else:
                self.ma120_track_list.append(self.ma120_track)
                self.ma120_track = -1

        if not am.inited or not self.trading:
            return

        self.on_strategy(am, bar, self.open_strategy["1"])
        # median_val = np.median(calc_nums)

        self.put_event()

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg3.update_bar(bar)
        self.bg5.update_bar(bar)
        self.bg.update_bar(bar)

    # def init_order_data(self):
    #     self.order_data = np.array([])

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        print("{}产生了{},价格为{},笔数为{},交易{},pos={}".format(
            order.datetime.strftime("%m/%d %H:%M:%S"),
            order.offset.value + order.direction.value, order.price,
            order.volume, order.status.value, self.pos))

        if order.vt_orderid in self.request_order:
            self.positions.on_order(order)
            if order.status == Status.ALLTRADED or order.status == Status.CANCELLED or order.status == Status.REJECTED:
                self.request_order.remove(order.vt_orderid)
        # if order.status == Status.ALLTRADED or order.status == Status.PARTTRADED:
        #     if order.direction == Direction.LONG:
        #         if self.positions.volumn == 0:
        #             self.positions.close_price = round(order.price * 0.995)
        #         self.positions.volumn += order.volume
        #     elif order.direction == Direction.SHORT:
        #         self.positions.volumn -= order.volume
        #     elif order.direction == Direction.NET:
        #         self.positions.volumn = order.volume

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Exemple #16
0
class RSIStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    no_trade_time_begin1 = time(hour=9, minute=0)
    no_trade_time_end1 = time(hour=9, minute=30)
    no_trade_time_begin2 = time(hour=23, minute=0)
    no_trade_time_end2 = time(hour=23, minute=30)

    load_bar_day = 20

    boll_window = 16
    boll_dev = 2.6
    # cci_window = 10
    atr_window = 30
    # atr_ma_window = 10
    rsi_f_window = 5
    rsi_l_window = 10
    grow_window = 5
    reduce_window = 5
    # rsi_entry = 16
    # ma_window = 5
    sl_multiplier = 7.6
    fixed_size = 1
    db_record = 0
    bar_size = 100

    boll_up = 0
    boll_down = 0
    # cci_value = 0
    atr_value = 0
    # atr_ma = 0

    rsi_f_value = 0
    rsi_l_value = 0
    rsi_max_value = 0
    rsi_min_value = 0
    rsi_f_ma = 0
    rsi_l_ma = 0

    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0

    vt_1m_orderids = []
    vt_15m_orderids = []

    parameters = [
        "boll_window", "boll_dev", "atr_window", "rsi_f_window",
        "rsi_l_window", "grow_window", "reduce_window", "sl_multiplier",
        "fixed_size", "bar_size", "db_record"
    ]
    variables = [
        "boll_up", "boll_down", "atr_value", "rsi_f_value", "rsi_l_value",
        "rsi_f_ma", "rsi_l_ma", "rsi_max_value", "rsi_min_value",
        "intra_trade_high", "intra_trade_low", "long_stop", "short_stop"
    ]

    # parameters = ["boll_window", "boll_dev", "cci_window","rsi_window","rsi_entry","ma_window",
    #               "atr_window","atr_ma_window","sl_multiplier", "fixed_size"]
    # variables = ["boll_up", "boll_down", "cci_value", "atr_value","atr_ma","rsi_value",
    #              "intra_trade_high", "intra_trade_low", "long_stop", "short_stop"]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        #todo,多时间周期,分长短期,判断不同的指标
        self.bg = BarGenerator(self.on_bar, 15, self.on_15min_bar)
        #self.am_1m = ArrayManager()
        self.am_15m = ArrayManager(self.bar_size)

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(self.load_bar_day)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        # self.cancel_order_list(self.vt_1m_orderids)
        # self.am_1m.update_bar(bar)
        # if not self.am_1m.inited:
        #     return
        # # #todo 1分钟的策略
        #
        # self.boll_up, self.boll_down = self.am_1m.boll(self.boll_window, self.boll_dev)
        # self.atr_value = self.am_1m.atr(self.atr_window)
        # rsi_f_array = self.am_1m.rsi(self.rsi_f_window, array=True)
        # rsi_l_array = self.am_1m.rsi(self.rsi_l_window, array=True)
        # self.rsi_f_value = rsi_f_array[-1]
        # self.rsi_l_value = rsi_l_array[-1]
        #
        # if self.pos == 0:
        #     self.intra_trade_high = bar.high_price
        #     self.intra_trade_low = bar.low_price
        #
        #     # todo,波动不够大,应该过滤
        #     if self.rsi_f_value > self.rsi_l_value and if_keep_grow(self.grow_window, rsi_f_array):
        #         vt_orderids = self.buy(self.boll_up, self.fixed_size, True)
        #         self.vt_1m_orderids.extend(vt_orderids)
        #     elif self.rsi_f_value < self.rsi_l_value and if_keep_reduce(self.reduce_window, rsi_f_array):
        #         vt_orderids = self.short(self.boll_down, self.fixed_size, True)
        #         self.vt_1m_orderids.extend(vt_orderids)
        # # todo,持续范围内小波动,震荡策略
        #
        #
        #
        # elif self.pos > 0:
        #     self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
        #     self.intra_trade_low = bar.low_price
        #     if if_keep_reduce(self.reduce_window, rsi_f_array):  # self.rsi_f_value < self.rsi_l_value and
        #         vt_orderids = self.sell(bar.close_price - 5, abs(self.pos))
        #     else:
        #         self.long_stop = self.intra_trade_high - self.atr_value * self.sl_multiplier
        #         vt_orderids = self.sell(self.long_stop, abs(self.pos), True)
        #     self.vt_1m_orderids.extend(vt_orderids)
        # elif self.pos < 0:
        #     self.intra_trade_high = bar.high_price
        #     self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
        #     if if_keep_grow(self.grow_window, rsi_f_array):  # self.rsi_f_value > self.rsi_l_value and
        #         vt_orderids = self.cover(bar.close_price + 5, abs(self.pos))
        #     else:
        #         self.short_stop = self.intra_trade_low + self.atr_value * self.sl_multiplier
        #         vt_orderids = self.cover(self.short_stop, abs(self.pos), True)
        #     self.vt_1m_orderids.extend(vt_orderids)
        # if self.db_record:
        #     database_manager.save_bar_calc(bar, self.get_variables())
        #
        # self.put_event()

        self.bg.update_bar(bar)

    def on_15min_bar(self, bar: BarData):
        """"""
        self.cancel_order_list(self.vt_15m_orderids)
        self.am_15m.update_bar(bar)
        if not self.am_15m.inited:
            return

        self.boll_up, self.boll_down = self.am_15m.boll(
            self.boll_window, self.boll_dev)
        #self.cci_value = am.cci(self.cci_window)
        self.atr_value = self.am_15m.atr(self.atr_window)
        # atr_array = am.atr(self.atr_window, array=True)
        # self.atr_value = atr_array[-1]
        #self.atr_ma = atr_array[-self.atr_ma_window:].mean()
        rsi_f_array = self.am_15m.rsi(self.rsi_f_window, array=True)
        rsi_l_array = self.am_15m.rsi(self.rsi_l_window, array=True)
        # self.rsi_max_value = rsi_f_array[-self.rsi_f_window:].max()
        # self.rsi_min_value = rsi_f_array[-self.rsi_f_window:].min()
        # self.rsi_f_ma = rsi_f_array[-self.rsi_f_window:].mean()
        # self.rsi_l_ma = rsi_f_array[-self.rsi_f_window:].mean()
        self.rsi_f_value = rsi_f_array[-1]
        self.rsi_l_value = rsi_l_array[-1]

        #self.ma_value = am.sma(self.ma_window)

        # if (bar.datetime.time() >= self.no_trade_time_begin1 and bar.datetime.time() <= self.no_trade_time_end1) \
        #         or (bar.datetime.time() >= self.no_trade_time_begin2 and bar.datetime.time() <= self.no_trade_time_end2):
        #     return

        if self.pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            #todo,波动不够大,应该过滤
            #if self.rsi_f_value > 50 and self.rsi_f_value > self.rsi_l_value and if_keep_grow(self.grow_window, rsi_f_array) and self.rsi_f_value < 85: #self.rsi_f_value>=self.rsi_max_value:
            if self.rsi_f_value > self.rsi_l_value:  #and if_keep_grow(self.grow_window, rsi_f_array):
                #self.buy(bar.close_price+5, self.fixed_size)
                vt_orderids = self.buy(self.boll_up, self.fixed_size, True)
                self.vt_15m_orderids.extend(vt_orderids)
            #elif self.rsi_f_value < 50 and self.rsi_f_value < self.rsi_l_value and if_keep_reduce(self.reduce_window, rsi_f_array) and self.rsi_f_value >15: #self.rsi_f_value <=self.rsi_min_value:
            elif self.rsi_f_value < self.rsi_l_value:  # and if_keep_reduce(self.reduce_window, rsi_f_array):
                #self.short(bar.close_price-5, self.fixed_size)
                vt_orderids = self.short(self.boll_down, self.fixed_size, True)
                self.vt_15m_orderids.extend(vt_orderids)
#todo,持续范围内小波动,震荡策略

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.intra_trade_low = bar.low_price
            if if_keep_reduce(
                    self.reduce_window,
                    rsi_f_array):  #self.rsi_f_value < self.rsi_l_value and
                vt_orderids = self.sell(bar.close_price - 5, abs(self.pos))
            else:
                self.long_stop = self.intra_trade_high - self.atr_value * self.sl_multiplier
                vt_orderids = self.sell(self.long_stop, abs(self.pos), True)
            self.vt_15m_orderids.extend(vt_orderids)

        elif self.pos < 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            if if_keep_grow(
                    self.grow_window,
                    rsi_f_array):  #self.rsi_f_value > self.rsi_l_value and
                vt_orderids = self.cover(bar.close_price + 5, abs(self.pos))
            else:
                self.short_stop = self.intra_trade_low + self.atr_value * self.sl_multiplier
                vt_orderids = self.cover(self.short_stop, abs(self.pos), True)
            self.vt_15m_orderids.extend(vt_orderids)

        if self.db_record:
            database_manager.save_bar_calc(bar, self.get_variables())

        self.put_event()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        #数据库记录成交记录,bar记录,variables值
        if self.db_record:
            database_manager.save_trade_data(trade, self.get_variables())

        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Exemple #17
0
class FbbStrategy(CtaTemplate):
    """"""

    author = "feng.shao"

    boll_window = 20  #
    boll_dev = 2.0  #
    boll_bw_limit = 0.01
    fixed_size: float = 0.2  # 单笔buy 暂时固定为总资产的 千分之 1~4  (风险随之增加)
    limit_amt = 10.0  # 最小交易资金10 USDT -binance

    #BB
    boll_up = 0
    boll_down = 0
    boll_mid = 0
    boll_pb = 0
    boll_bw = 0

    #kdj

    k = 0
    d = 0
    j = 0

    last_boll_pb = 0

    parameters = [
        "boll_window",
        "boll_dev",
        # "boll_dev_2",
        # "boll_pb_sal",
        "boll_bw_limit",
        "fixed_size"
    ]
    variables = [
        # "boll_up",
        # "boll_down",
        # "boll_mid",
        "boll_pb",
        # "boll_bw",
        # "boll_up_2",
        # "boll_down_2",
        # "boll_mid_2",
        # "boll_pb_2",
        # "boll_bw_2",
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.bg = BarGenerator(self.on_bar, 15, self.on_mins_bar)
        self.am = ArrayManager()

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(2)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)

    def on_mins_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.cancel_all()

        am = self.am
        am.update_bar(bar)

        if not am.inited:
            return

        # start
        self.get_boll(bar)
        self.get_kdj()

        print(
            str(self.k) + "  -  " + str(self.d) + "  -  " + str(self.j) +
            "  -  " + bar.datetime.strftime("%Y-%m-%d %H:%M:%S"))

        # 低于 boll_down 并且width 不小于limit 买入
        if self.boll_pb <= 0 and self.boll_bw > self.boll_bw_limit:
            self.buy(bar.close_price,
                     self.check_minimum_size(bar.close_price, self.fixed_size),
                     False)

        if self.pos > 0:
            # 上穿 up 卖出信号
            if self.last_boll_pb < 1 <= self.boll_pb and self.boll_bw < self.boll_bw_limit:
                self.sell(bar.close_price, self.pos, False)
            # 未达up 而下穿 mid 卖出
            if self.last_boll_pb > 0.5 >= self.boll_pb and self.boll_bw < self.boll_bw_limit:
                self.sell(bar.close_price, self.pos, False)
            # down 下方 ,width 很小 卖出
            if self.boll_pb <= 0 and self.boll_bw <= self.boll_bw_limit:
                self.sell(bar.close_price, self.pos, False)

        self.last_boll_pb = self.boll_pb

        #     self.short(bar.close_price, self.fixed_size, False)

        #     self.cover(bar.close_price, self.pos, False)

        self.put_event()

    def check_minimum_size(self, price: float, order_size) -> float:
        min_size = self.size_by_limit_amt(self.limit_amt, price)
        return max(order_size, min_size)

    def kdj_signal(self):
        if self.d <= self.k < 20:
            return True

    def get_boll(self, bar: BarData):
        self.boll_up, self.boll_mid, self.boll_down = self.am.boll(
            self.boll_window, self.boll_dev)
        self.boll_pb = self.percentbeta(bar.close_price, self.boll_up,
                                        self.boll_down)
        self.boll_bw = self.bandwidth(self.boll_up, self.boll_mid,
                                      self.boll_down)

    def get_kdj(self):
        self.k, self.d, self.j = self.am.kdj()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass

    def percentbeta(self, close: float, up: float, low: float) -> float:
        """
        %b of boll
        """
        pb = (close - low) / (up - low)

        return pb

    def bandwidth(self, up: float, mid: float, low: float) -> float:
        """
        bandwidth of boll
        """
        bw = (up - low) / mid

        return bw

    def size_by_limit_amt(self, limit_amt: float, price: float) -> float:

        return math.ceil(limit_amt / price * 1000000) / 1000000
class CincoRB2005Strategy(CtaTemplate):
    """"""

    author = "tonywang_efun"

    boll_window = 44
    boll_dev = 2.0
    rsi_window = 8
    rsi_long = 58
    rsi_short = 20
    trailing_long = 2.6
    trailing_short = 2.6
    fixed_size = 2

    boll_up = 0
    boll_down = 0
    rsi_value = 0
    trading_size = 0
    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0
    atr_value = 0

    parameters = [
        "boll_window", "boll_dev", "rsi_window", "rsi_long", "rsi_short",
        "trailing_long", "trailing_short", "fixed_size"
    ]

    variables = [
        "boll_up", "boll_down", "rsi_value", "trading_size",
        "intra_trade_high", "intra_trade_low", "long_stop", "short_stop",
        "atr_value"
    ]

    def __init__(
        self,
        cta_engine,
        strategy_name: str,
        vt_symbol: str,
        setting: dict,
    ):
        """"""
        super(CincoRB2005Strategy, self).__init__(cta_engine, strategy_name,
                                                  vt_symbol, setting)

        self.bg = BarGenerator(self.on_bar, 13, self.on_15min_bar)
        self.am = ArrayManager()

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)

    def on_15min_bar(self, bar: BarData):
        """"""
        self.cancel_all()

        self.am.update_bar(bar)
        if not self.am.inited:
            return

        self.boll_up, self.boll_down = self.am.boll(self.boll_window,
                                                    self.boll_dev)
        self.rsi_value = self.am.rsi(self.rsi_window)
        boll_width = self.boll_up - self.boll_down

        if not self.pos:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price
            self.long_stop = 0
            self.short_stop = 0

            # print(self.boll_up, self.boll_down, self.intra_trade_high, self.intra_trade_low)

            if self.rsi_value >= self.rsi_long:
                self.buy(self.boll_up, self.fixed_size, stop=True)

            if self.rsi_value <= self.rsi_short:
                self.short(self.boll_down, self.fixed_size, stop=True)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.long_stop = self.intra_trade_high - self.trailing_long * boll_width
            self.sell(self.long_stop, abs(self.pos), stop=True)

        else:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.short_stop = self.intra_trade_low + self.trailing_short * boll_width
            self.cover(self.short_stop, abs(self.pos), stop=True)

        self.put_event()

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.put_event()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        pass

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Exemple #19
0
class MacdBollDcStrategy(CtaTemplate):
    """"""

    author = "云崖"

    open_window = 2
    xminute_window = 15
    xhour_window = 1
    fast_length = 14
    show_length = 28
    boll_length = 20
    boll_dev = 2.0
    dc_length = 30
    trailing_tax = 2.0
    fixed_size = 1

    macd_inited = 0
    boll_up = 0
    boll_down = 0
    dc_up = 0
    dc_down = 0
    exit_long = 0
    exit_short = 0
    long_stop = 0
    short_stop = 0

    intra_trade_high = 0
    intra_trade_low = 0

    parameters = [
        "open_window",
        "xminute_window",
        "xhour_window",
        "fast_length",
        "show_length",
        "boll_length",
        "boll_dev",
        "dc_length",
        "trailing_tax",
        "fixed_size",
    ]

    variables = [
        "macd_inited",
        "boll_up",
        "boll_down",
        "dc_up",
        "dc_down",
        "exit_long",
        "exit_short",
        "long_stop",
        "short_stop",
    ]

    def __init__(self, cta_engine, strategy_nam_xminutee, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_nam_xminutee, vt_symbol, setting)

        self.bg_open = NewBarGenerator(self.on_bar, self.open_window,
                                       self.on_open_bar)
        self.am_open = ArrayManager()

        self.bg_xminute = NewBarGenerator(self.on_bar, self.xminute_window,
                                          self.on_xminute_bar)
        self.am_xminute = ArrayManager(150)

        self.bg_xhour = NewBarGenerator(self.on_bar,
                                        self.xhour_window,
                                        self.on_xhour_bar,
                                        interval=Interval.HOUR)
        self.am_xhour = ArrayManager()

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg_xminute.update_tick(tick)
        self.ask = tick.ask_price_1  # 卖一价
        self.bid = tick.bid_price_1  # 买一价

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg_xhour.update_bar(bar)
        self.bg_xminute.update_bar(bar)
        self.bg_open.update_bar(bar)

    def on_open_bar(self, bar: BarData):
        """"""
        self.cancel_all()

        self.am_open.update_bar(bar)
        if not self.am_xminute.inited or not self.am_open.inited:

            return

        if self.pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            self.long_stop = 0
            self.short_stop = 0

            if self.macd_inited > 0:
                self.buy(self.boll_up, self.fixed_size, True)

            elif self.macd_inited < 0:
                self.short(self.boll_down, self.fixed_size, True)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.intra_trade_low = bar.low_price

            long_high = self.intra_trade_high * (1 - self.trailing_tax / 100)
            self.long_stop = max(self.exit_long, long_high)

            self.sell(self.long_stop, abs(self.pos), True)

        elif self.pos < 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)

            stop_low = self.intra_trade_low * (1 + self.trailing_tax / 100)
            self.short_stop = min(self.exit_short, stop_low)

            self.cover(self.short_stop, abs(self.pos), True)

        self.put_event()

    def on_xminute_bar(self, bar: BarData):
        """"""
        self.am_xminute.update_bar(bar)
        if not self.am_xminute.inited:
            return

        self.boll_up, self.boll_down = self.am_xminute.boll(
            self.boll_length, self.boll_dev)
        self.exit_short, self.exit_long = self.am_xminute.donchian(
            self.dc_length)

    def on_xhour_bar(self, bar: BarData):
        """
        :param bar:
        :type bar:
        :return:
        :rtype:
        """
        self.am_xhour.update_bar(bar)
        if self.am_xhour.inited:
            return
        fast_ema_value = self.am_xhour.ema(self.fast_length, True)
        show_ema_value = self.am_xhour.ema(self.show_length, True)
        diff = fast_ema_value - show_ema_value
        macd_diff = (fast_ema_value - show_ema_value) / show_ema_value * 100

        if diff[-2] > macd_diff[-2]:
            self.macd_inited = 1

        elif diff[-2] < macd_diff[-2]:
            self.macd_inited = -1

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        self.put_event()

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        self.put_event()
class AberrationBias_V1_Strategy(CtaTemplate):
    """
    目前使用中轨加速,可以考虑使用另外一根均线来加速,这样可以避免在开仓时被平。
    """
    author = "yunya"

    open_window = 15
    boll_length = 560
    boll_dev = 1.6
    bias = 0.16
    cci_length = 6
    cci_exit = 10.0
    fixed_size = 1

    boll_up = 0
    boll_down = 0
    boll_mid = 0
    boll_mid_new = 0
    boll_mid_array = 0
    bias_value_array = 0
    bias_value = 0
    cci_value = 0
    exit_long = 0
    exit_short = 0
    boll_length_new = 0
    exit_long_nex = 0
    exit_long_last = 0
    exit_short_nex = 0
    exit_short_last = 0

    # 画图专用
    time_list = []
    open_list = []
    high_list = []
    low_list = []
    close_list = []
    volume_list = []
    up_list = []
    down_list = []
    mid_list = []
    mid_new_list = []
    exit_long_list = []
    exit_short_list = []
    bias_value_list = []
    bias_list = []
    singnal_plot = []
    singnal_list = None
    singnal = None

    plot_echarts = {}

    parameters = [
        "open_window",
        "boll_length",
        "boll_dev",
        "bias",
        "cci_length",
        "cci_exit",
        "fixed_size",
    ]

    variables = [
        "boll_up",
        "boll_down",
        "boll_mid",
        "bias_value",
        "cci_value",
        "exit_long",
        "exit_short",
        "boll_length_new",
        "exit_long_nex",
        "exit_long_last",
        "exit_short_nex",
        "exit_short_last",
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.bg = BarGenerator(self.on_bar, self.open_window, self.on_xmin_bar)
        self.am = ArrayManager(int(self.boll_length) * 2 + 10)

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)

    def on_xmin_bar(self, bar: BarData):
        """"""
        self.cancel_all()

        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return

        # 计算原布林带
        self.boll_up, self.boll_down = self.am.boll(self.boll_length,
                                                    self.boll_dev)
        self.boll_mid_array = am.sma(self.boll_length, True)
        self.boll_mid = self.boll_mid_array[-1]
        self.bias_value_array = (self.am.close -
                                 self.boll_mid_array) / self.boll_mid_array
        self.bias_value = self.bias_value_array[-1]

        self.cci_value = am.cci(self.cci_length)

        # 上涨或下跌时,布林中轨均值减1
        close_long = am.close[-1] > am.close[-2]
        close_short = am.close[-1] < am.close[-2]

        if close_long or close_short:
            self.boll_length_new -= 2
            self.boll_length_new = max(self.boll_length_new, 5)

        # 计算新的布林带
        self.boll_mid_new = am.sma(int(self.boll_length_new), True)

        # 如果没有仓位,两条布林window一样
        if self.pos == 0:
            self.exit_long_nex = 0
            self.exit_long_last = 0
            self.exit_short_nex = 0
            self.exit_short_last = 0
            self.boll_length_new = self.boll_length

            #   远离均线不开仓位
            if self.bias > abs(self.bias_value):
                if self.cci_value > self.cci_exit:
                    self.buy(self.boll_up, self.fixed_size, True)

                if self.cci_value < -self.cci_exit:
                    self.short(self.boll_down, self.fixed_size, True)

        elif self.pos > 0:

            # 仓位是long 时,如果价格上穿新布林中轨
            con1 = am.close[-1] < self.boll_mid_new[-1]
            con2 = am.close[-2] >= self.boll_mid_new[-2]

            if con1 and con2:
                self.exit_long_nex = am.close[-1]  # 保存当前收盘价
                if self.exit_long_nex > self.exit_long_last or self.exit_long_last == 0:
                    self.exit_long_last = self.exit_long_nex
                    self.boll_length_new = self.boll_length - 10
                    # 下穿新均线,以原布林均线挂出停止单,避免快速下跌而无法止损
                    self.exit_long = self.boll_mid
                    # print(f"我是多单,exitlast:{self.exit_short_last},重置布林中轨参数,止损挂{self.exit_long}:")
                else:
                    # 收盘价在两条均线平均价上方,以当前收盘价挂出限价单
                    if self.am.close[-1] > (
                        (self.boll_mid + self.boll_mid_new[-1]) / 2):
                        self.exit_long = bar.close_price
                        # print(f"我是多单,收盘价在两个中轨均值上方,以收盘价挂止损单:{self.exit_long}")
                    elif bar.close_price < self.boll_mid:
                        self.exit_long = bar.close_price
                    else:
                        self.exit_long = self.boll_mid
                        # print(f"我是多单,收盘价在两个中轨均值下方,以原中轨挂止损单:{self.exit_long},")
            else:
                self.exit_long = (self.boll_mid + self.boll_mid_new[-2]) / 2
                # print(f"我是多单,收盘价在新中轨上方,以原中轨挂止损单:{self.exit_long}")

            if self.bias_value > self.bias:
                self.exit_long = max(bar.close_price, self.exit_long)

            exit_long = (self.boll_mid + self.boll_mid_new[-1]) / 2
            if bar.close_price > exit_long:
                self.exit_long = max(self.exit_long, exit_long)

            self.sell(self.exit_long, abs(self.pos), True)

        elif self.pos < 0:

            # 仓位是short 时,如果价格上穿新布林中轨
            con3 = am.close[-1] > self.boll_mid_new[-1]
            con4 = am.close[-2] <= self.boll_mid_new[-2]

            if con3 and con4:
                self.exit_short_nex = am.close[-1]
                if self.exit_short_nex < self.exit_short_last or self.exit_short_last == 0:
                    self.exit_short_last = self.exit_short_nex
                    self.boll_length_new = self.boll_length - 10

                    self.exit_short = self.boll_mid
                else:
                    if self.am.close[-1] < (self.boll_mid +
                                            self.boll_mid_new[-1] / 2):
                        self.exit_short = bar.close_price

                    elif bar.close_price > self.boll_mid:
                        self.exit_short = bar.close_price

                    else:
                        self.exit_short = self.boll_mid

            else:
                self.exit_short = (self.boll_mid + self.boll_mid_new[-1]) / 2

            if self.bias_value < -self.bias:
                self.exit_short = min(self.exit_short, bar.close_price)

            exit_short = (self.boll_mid + self.boll_mid_new[-1]) / 2
            if bar.close_price < exit_short:
                self.exit_short = min(self.exit_short, exit_short)

            self.cover(self.exit_short, abs(self.pos), True)

        # # 画图专用
        # if self.singnal != self.singnal_list:
        #     plot = self.singnal
        # else:
        #     plot = None
        #
        # self.time_list.append(bar.datetime)
        # self.open_list.append(bar.open_price)
        # self.high_list.append(bar.high_price)
        # self.low_list.append(bar.low_price)
        # self.close_list.append(bar.close_price)
        # self.volume_list.append(bar.volume)
        # self.up_list.append(self.boll_up)
        # self.down_list.append(self.boll_down)
        # self.mid_list.append(self.boll_mid)
        # self.mid_new_list.append(self.boll_mid_new[-1])
        # self.exit_long_list.append(self.exit_long)
        # self.exit_short_list.append(self.exit_short)
        # self.singnal_plot.append(plot)
        #
        # self.plot_echarts = {
        #     "datetime": self.time_list,
        #     "open": self.open_list,
        #     "high": self.high_list,
        #     "low": self.low_list,
        #     "close": self.close_list,
        #     "volume": self.low_list,
        #     "boll_up": self.up_list,
        #     "boll_down": self.down_list,
        #     "boll_mid": self.mid_list,
        #     "boll_mid_new": self.mid_new_list,
        #     "bias": self.bias_value_list,
        #     "bias_value": self.bias_list,
        #     "exit_long": self.exit_long_list,
        #     "exit_short": self.exit_short_list,
        #     "signal": self.singnal_plot
        #
        # }
        # self.singnal_list = self.singnal

        self.put_event()
        self.sync_data()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        self.put_event()
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """

        #   画图专用
        if trade.direction.value == Direction.LONG.value:
            if trade.offset.value == Offset.OPEN.value:
                self.singnal = 1

            elif trade.offset.value == Offset.CLOSE.value:
                self.singnal = 0

            else:
                self.singnal = None

        elif trade.direction.value == Direction.SHORT.value:
            if trade.offset.value == Offset.OPEN.value:
                self.singnal = -1

            elif trade.offset.value == Offset.CLOSE.value:
                self.singnal = 0

            else:
                self.singnal = None
Exemple #21
0
class CuatroStrategy(CtaTemplate):
    """"""
    author = "KeKe"

    rsi_signal = 19
    rsi_window = 14
    fast_window = 4
    slow_window = 26
    boll_window = 21
    boll_dev = 1.9
    trailing_short = 0.3
    trailing_long = 0.5
    fixed_size = 1

    boll_up = 0
    boll_down = 0
    rsi_value = 0
    rsi_long = 0
    rsi_short = 0
    fast_ma = 0
    slow_ma = 0
    ma_trend = 0
    long_stop = 0
    short_stop = 0
    intra_trade_high = 0
    intra_trade_low = 0

    parameters = [
        "rsi_signal", "rsi_window", "fast_window", "slow_window",
        "boll_window", "boll_dev", "trailing_long", "trailing_short",
        "fixed_size"
    ]

    variables = [
        "boll_up", "boll_down", "rsi_value", "rsi_long", "rsi_short",
        "fast_ma", "slow_ma", "ma_trend", "long_stop", "short_stop"
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(CuatroStrategy, self).__init__(cta_engine, strategy_name,
                                             vt_symbol, setting)

        self.rsi_long = 50 + self.rsi_signal
        self.rsi_short = 50 - self.rsi_signal

        self.bg5 = BarGenerator(self.on_bar, 5, self.on_5min_bar)
        self.am5 = ArrayManager()

        self.bg15 = BarGenerator(self.on_bar, 15, self.on_15min_bar)
        self.am15 = ArrayManager()

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg5.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg5.update_bar(bar)
        self.bg15.update_bar(bar)

    def on_5min_bar(self, bar: BarData):
        """"""
        self.cancel_all()

        self.am5.update_bar(bar)
        if not self.am5.inited:
            return

        if not self.ma_trend:
            return

        self.rsi_value = self.am5.rsi(self.rsi_window)
        self.boll_up, self.boll_down = self.am5.boll(self.boll_window,
                                                     self.boll_dev)
        boll_width = self.boll_up - self.boll_down

        if self.pos == 0:
            self.intra_trade_low = bar.low_price
            self.intra_trade_high = bar.high_price

            if self.ma_trend > 0 and self.rsi_value >= self.rsi_long:
                self.buy(self.boll_up, self.fixed_size, True)

            elif self.ma_trend < 0 and self.rsi_value <= self.rsi_short:
                self.short(self.boll_down, self.fixed_size, True)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.long_stop = (self.intra_trade_high -
                              self.trailing_long * boll_width)
            self.sell(self.long_stop, abs(self.pos), True, True)

        elif self.pos < 0:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.short_stop = (self.intra_trade_low +
                               self.trailing_short * boll_width)
            self.cover(self.short_stop, abs(self.pos), True, True)

        self.put_event()

    def on_15min_bar(self, bar: BarData):
        """"""
        self.am15.update_bar(bar)
        if not self.am15.inited:
            return

        self.fast_ma = self.am15.sma(self.fast_window)
        self.slow_ma = self.am15.sma(self.slow_window)

        if self.fast_ma > self.slow_ma:
            self.ma_trend = 1
        else:
            self.ma_trend = -1

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass