示例#1
0
class TestBar(object):
    def __init__(self):
        self.am = ArrayManager(390)
        self.bg = BarGenerator(self.on_bar, interval=Interval.DAILY)

    def on_bar(self, bar: BarData):
        # self.am.update_bar(bar)
        self.am.update_bar(bar)
class MACDSignal(CtaSignal):
    """"""
    def __init__(self,
                 fast_window: int,
                 slow_window: int,
                 signal_period: int,
                 period: int = 30):
        """"""
        super().__init__()

        self.fast_window = fast_window
        self.slow_window = slow_window
        self.signal_period = signal_period

        self.period = period
        self.bg = BarGenerator(self.on_bar, period, self.on_n_min_bar)
        self.am = ArrayManager(
            size=max(self.fast_window, self.slow_window, self.signal_period) +
            50)
        logger.info(
            f"fast_window, slow_window, signal_period, period="
            f"{self.fast_window, self.slow_window, self.signal_period, self.period}"
        )

    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_n_min_bar(self, bar: BarData):
        """"""
        self.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

        _, _, macd = self.am.macd(self.fast_window, self.slow_window,
                                  self.signal_period)

        if macd < -5:
            self.set_signal_pos(1)
        elif macd > 5:
            self.set_signal_pos(-1)
        else:
            # self.set_signal_pos(0)
            pass
示例#3
0
 def compute_index_zz500_specifications(self, df):
     # 注意:所有的数据库数据和列表数据都按照日期的正序排序(从小到大)
     # 计算zz500指数的技术指标并入库
     """
     @ 入参:指数k线信息
     """
     am = ArrayManager(size=600)   
     for ix, row in df.iterrows():
         d = row.to_dict()
         LOG.info(d['trade_date'])   
         d['ts_code'] = d['ts_code'].replace('.', '_')
         bar = BarData(
                 gateway_name='ctp', symbol=d['ts_code'],
                 exchange=Exchange.SSE,
                 datetime=string_to_datetime(d['trade_date']))
         bar.symbol = d['ts_code']
         bar.open_price = d['open']
         bar.high_price = d['high']
         bar.low_price = d['low']
         bar.close_price = d['close']
         am.update_bar(bar)      
         rsi_20 = am.rsi(20)
         d['rsi_20'] = rsi_20
         try:
             d['ma_5'] = am.sma(5)
         except:
             traceback.print_exc()                    
             LOG.error('************************')
             LOG.error(d['ts_code'])
             LOG.error(d['trade_date'])
             LOG.error(bar)
         d['ma_10'] = am.sma(10)
         d['ma_20'] = am.sma(20)
         d['ma_30'] = am.sma(30)
         d['ma_60'] = am.sma(60)
         d['ma_120'] = am.sma(120)
         d['ma_250'] = am.sma(250)
         d['ma_500'] = am.sma(500)
         flt = {'trade_date': d['trade_date']}
         cl_index_zz500 = self.db[CL_INDEX_ZZ500]
         # cl_index_zz500.replace_one(flt, d, upsert=False)
         cl_index_zz500.update_one(flt, {'$setOnInsert': d}, upsert=True)   # 插入数据时,flt不存在则插入d,存在则不执行
示例#4
0
class MaSignal(CtaSignal):
    """"""

    def __init__(self, fast_window: int, slow_window: int):
        """"""
        super(MaSignal, self).__init__()

        self.fast_window = fast_window
        self.slow_window = slow_window

        self.bg = BarGenerator(self.on_bar, 5, self.on_5min_bar)
        self.am = ArrayManager()

    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_5min_bar(self, bar: BarData):
        """"""
        self.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

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

        if fast_ma > slow_ma:
            self.set_signal_pos(1)
        elif fast_ma < slow_ma:
            self.set_signal_pos(-1)
        else:
            self.set_signal_pos(0)
示例#5
0
class MaSignal(CtaSignal):
    """"""

    def __init__(self, fast_window: int, slow_window: int):
        """"""
        super(MaSignal, self).__init__()

        self.fast_window = fast_window
        self.slow_window = slow_window

        self.bg = BarGenerator(self.on_bar, 5, self.on_5min_bar)
        self.am = ArrayManager()

    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_5min_bar(self, bar: BarData):
        """"""
        self.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

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

        if fast_ma > slow_ma:
            self.set_signal_pos(1)
        elif fast_ma < slow_ma:
            self.set_signal_pos(-1)
        else:
            self.set_signal_pos(0)
示例#6
0
class CciSignal(CtaSignal):
    """"""

    def __init__(self, cci_window: int, cci_level: float):
        """"""
        super(CciSignal, self).__init__()

        self.cci_window = cci_window
        self.cci_level = cci_level
        self.cci_long = self.cci_level
        self.cci_short = -self.cci_level

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

    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.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

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

        if cci_value >= self.cci_long:
            self.set_signal_pos(1)
        elif cci_value <= self.cci_short:
            self.set_signal_pos(-1)
        else:
            self.set_signal_pos(0)
示例#7
0
class CciSignal(CtaSignal):
    """"""

    def __init__(self, cci_window: int, cci_level: float):
        """"""
        super(CciSignal, self).__init__()

        self.cci_window = cci_window
        self.cci_level = cci_level
        self.cci_long = self.cci_level
        self.cci_short = -self.cci_level

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

    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.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

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

        if cci_value >= self.cci_long:
            self.set_signal_pos(1)
        elif cci_value <= self.cci_short:
            self.set_signal_pos(-1)
        else:
            self.set_signal_pos(0)
示例#8
0
class RsiSignal(CtaSignal):
    """"""
    def __init__(self, rsi_window: int, rsi_level: float):
        """Constructor"""
        super().__init__()

        self.rsi_window = rsi_window
        self.rsi_level = rsi_level
        self.rsi_long = 50 + self.rsi_level
        self.rsi_short = 50 - self.rsi_level

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

    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.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

        rsi_value = self.am.rsi(self.rsi_window)

        if rsi_value >= self.rsi_long:
            self.set_signal_pos(1)
        elif rsi_value <= self.rsi_short:
            self.set_signal_pos(-1)
        else:
            self.set_signal_pos(0)
示例#9
0
class MaTrendStrategy(CtaTemplate):
    author = "用Python的交易员"

    ma_level = [10, 20, 30, 60, 120]

    request_order = []
    close_order = []

    volumn = 0
    kdj_record = []
    parameters = ["ma_level"]
    variables = ["fast_ma0", "fast_ma1", "slow_ma0", "slow_ma1"]
    add_pos = False
    safe_price = None
    ma_info = pd.DataFrame()
    closeout_offset = 0.003
    trade_mgr: TradeMgr = None

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(MaTrendStrategy, self).__init__(cta_engine, strategy_name,
                                              vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar,
                               1,
                               self.on_1min_bar,
                               tz_info=eastern)
        self.am = ArrayManager(400)
        self.am3 = ArrayManager(150)
        self.bg3 = BarGenerator(self.on_bar,
                                3,
                                self.on_3min_bar,
                                tz_info=eastern)
        self.am5 = ArrayManager(100)
        self.bg5 = BarGenerator(self.on_bar,
                                5,
                                self.on_5min_bar,
                                tz_info=eastern)
        self.trade_mgr = TradeMgr(self, setting["capital"], OrderType.MARKET,
                                  {})
        self.closeout_offset = 0.003
        self.clock = ClockManager(datetime.time(hour=9, minute=30),
                                  datetime.time(hour=16, minute=0))

        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)
        self.offset = 40
        self.init_datacreator()

    def init_datacreator(self):
        self.data_center = DataCenter(component={
            "array_manager_1": self.am,
            "clock": self.clock
        })

        self.data_creator = {
            "ma_info": MaInfoCreator(self.data_center),
            "trend_info": TrendInfoCreator(self.data_center),
            "ma_dist": MaDistCreator(self.data_center)
        }
        self.ma_info = self.data_creator["ma_info"]
        self.data_center.connect("trend_info", self.on_new_trend)

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

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

    def closeout_strategy(self, am: ArrayManager, bar: BarData, calc_data):
        if self.trade_mgr.get_status() == PositionStatus.Short:
            if bar.close_price > self.closeout_price:
                calc_data["trade_close"] = "平仓:到达最低价{}".format(
                    self.closeout_price)
                return self.trade_mgr.cover(bar.close_price)
                # return self.cover(bar.close_price, abs(self.volumn), type=OrderType.MARKET,
                #                   extra={"reason": "平仓:到达最低价{}".format(self.closeout_price)})
        elif self.trade_mgr.get_status() == PositionStatus.Long:
            if bar.close_price < self.closeout_price:
                calc_data["trade_close"] = "平仓:到达最低价{}".format(
                    self.closeout_price)
                return self.trade_mgr.sell(bar.close_price)
                # return self.sell(bar.close_price, abs(self.volumn), type=OrderType.MARKET,
                #        extra={"reason": "平仓:到达最低价{}".format(self.closeout_price)})

    ''' 
        检测3个ma闭合,空仓状态时如果小于0.01则标记起点,随后检测4个ma的穿越,计算角度,并买入。
        根据时间和升幅进行加仓(急速提升的情况下,3ma的闭合间隙会加大),
        3个ma如果遭遇再次闭合,则根据情况卖出
        
    '''

    def on_new_trend(self, data):
        self.trend_context = data["trend_info"]

    def range_score(self, am: ArrayManager, length):
        r_data = am.range[-length:]

    def ma_trend_strategy(self, am: ArrayManager, bar: BarData, calc_data):
        context = self.trend_context
        if context == None:
            return

        deg = context["deg"]
        data = context["data"]
        sign = context["sign"]
        if self.pos == 0:
            ma120 = self.ma_info.info[120]

            deg120 = calc_regress_deg(ma120[-5:], False)
            if deg < 0:
                calc_data["trade_open"] = "开空,deg={}".format(deg)
                sign()
                ratio = 0.2 if deg120 < 0 else 0.1
                return self.trade_mgr.short(bar.close_price, ratio, {})
            elif deg > 0:
                calc_data["trade_open"] = "开多,deg={}".format(deg)
                sign()
                ratio = 0.2 if deg120 > 0 else 0.1
                return self.trade_mgr.buy(bar.close_price, ratio, {})

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

        if self.trade_mgr.get_status() != PositionStatus.Empty:
            data = self.ma_info.info[-60:]
            length = len(data)
            close = (data[10] + data[20] + data[30]) / 3
            if length > 10:
                y_fit = reg_util.regress_y_polynomial(close[-10:], zoom=True)
                deg = calc_regress_deg(y_fit[:10], False)
            else:
                deg = calc_regress_deg(close[-10:], False)

            calc_data["trade_close_deg"] = deg
            if self.trade_mgr.get_status() == PositionStatus.Short:

                if deg > 0.01:
                    calc_data["trade_close"] = "平仓:趋势反转{}".format(deg)
                    return self.trade_mgr.cover(bar.close_price)
            elif self.trade_mgr.get_status() == PositionStatus.Long:
                if deg < -0.01:
                    calc_data["trade_close"] = "平仓:趋势反转{}".format(deg)
                    return self.trade_mgr.sell(bar.close_price)

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

        if self.safe_price is None:
            return

        rg = (bar.close_price / self.trade_price) - 1

        close_price = None
        if rg > 0.01 and self.trade_mgr.get_status() == PositionStatus.Long:
            close_price = am.sma(120)
        elif rg < -0.01 and self.trade_mgr.get_status(
        ) == PositionStatus.Short:
            close_price = am.sma(120)

        for lvl in self.ma_level[-1:]:
            # if len(self.order_data) < lvl:
            close_price = am.sma(lvl)
            break

        if close_price is None:
            lvl = self.ma_level[-1]
            close_price = am.sma(lvl)

        if self.trade_mgr.get_status() == PositionStatus.Short:
            if bar.close_price > close_price:
                calc_data["trade_close"] = "平仓:到达MA均线价{}".format(close_price)
                return self.trade_mgr.cover(bar.close_price)
                # return self.cover(bar.close_price, abs(self.volumn), type=OrderType.MARKET,
                #        extra= { "reason":"平仓:到达MA均线价{}".format(close_price)})

        elif self.trade_mgr.get_status() == PositionStatus.Long:
            if bar.close_price < close_price:
                calc_data["trade_close"] = "平仓:到达MA均线价{}".format(close_price)
                return self.trade_mgr.sell(bar.close_price)
                # return self.sell(bar.close_price, abs(self.volumn), type=OrderType.MARKET,
                #        extra={"reason": "平仓:到达MA均线价{}".format(close_price)})

    # 加仓算法
    def add_position(self,
                     am: ArrayManager,
                     bar: BarData,
                     calc_data,
                     setting={}):

        if self.safe_price is None:
            return

        if not (self.trade_mgr.get_status() == PositionStatus.Short and bar.close_price < self.safe_price or \
                self.trade_mgr.get_status() == PositionStatus.Long and bar.close_price > self.safe_price):
            return

        am = self.am
        rg = (bar.close_price / self.trade_price) - 1

        close_price = None
        if rg > 0.01 and self.trade_mgr.get_status() == PositionStatus.Long:
            close_price = am.sma(120)
            if not self.add_pos:
                self.add_pos = True
                # scale = 1 - 0.002
                # self.closeout_price = round(bar.close_price * scale, 2)
                return self.trade_mgr.buy(bar.close_price, 0.1, {})
        elif rg < -0.01 and self.trade_mgr.get_status(
        ) == PositionStatus.Short:
            close_price = am.sma(120)
            if not self.add_pos:
                self.add_pos = True
                # scale = 1 + 0.002
                # self.closeout_price = round(bar.close_price * scale, 2)
                return self.trade_mgr.short(bar.close_price, 0.1, {})

    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

    def on_strategy(self,
                    am: ArrayManager,
                    bar: BarData,
                    strategy_list,
                    close_strategy_list,
                    calc_data=None):

        order_id = None

        for open_strategy in strategy_list:
            if order_id is not None:
                break
            order_id = open_strategy(am, bar, calc_data)

        if order_id is None and self.pos != 0:
            for strategy in close_strategy_list:
                if order_id is not None:
                    break
                order_id = strategy(am, 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.trend_context = None
        self.am.update_bar(bar)
        am = self.am

        max_len = self.ma_level[-1] + 20
        data = self.am.close[-max_len:-1]

        if self.tracker is not None:
            self.tracker["bar_data"].append(bar)
        self.std_range.update(self.am.range[-1])

        self.data_center.push("bar_data", bar)
        self.data_center.push("array_manager", self.am)

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

        calc_data = self.generate_data(am, bar)
        open_strategy = [self.ma_trend_strategy, self.add_position]
        close_strategy = [
            self.ma_trend_strategy2, self.closeout_strategy,
            self.trend_reverse_close
        ]
        self.on_strategy(am, bar, open_strategy, close_strategy, calc_data)
        # 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 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))
        self.trade_mgr.on_order(order)
        if order.vt_orderid in self.request_order:
            if order.status == Status.ALLTRADED or order.status == Status.CANCELLED or order.status == Status.REJECTED:
                self.close_order.append(order.vt_orderid)

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.trade_mgr.on_trade(trade)
        if trade.vt_orderid in self.request_order:
            # self.positions.on_trade(trade)
            if self.volumn == 0:
                self.add_pos = False
                self.trade_price = trade.price
                if trade.direction == Direction.LONG:
                    self.safe_price = trade.price * 1.003
                    scale = 1 - self.closeout_offset
                    self.closeout_price = round(trade.price * scale, 2)
                elif trade.direction == Direction.SHORT:
                    self.safe_price = trade.price * 0.997
                    scale = 1 + self.closeout_offset
                    self.closeout_price = round(trade.price * scale, 2)

            if trade.direction == Direction.LONG:
                self.volumn += trade.volume
            elif trade.direction == Direction.SHORT:
                self.volumn -= trade.volume

            if trade.vt_orderid in self.close_order:
                self.request_order.remove(trade.vt_orderid)
                self.close_order.remove(trade.vt_orderid)
        self.put_event()

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

    def ma_trend_strategy2(self, am: ArrayManager, bar: BarData, calc_data):
        context = self.trend_context
        if context == None:
            return

        deg = context["deg"]
        data = context["data"]
        sign = context["sign"]
        if self.pos > 0 and deg < 0:
            ma120 = self.ma_info.info[120]

            calc_data["trade_open"] = "平仓并开空,deg={}".format(deg)
            sign()
            self.trade_mgr.sell(bar.close_price)
            return self.trade_mgr.short(bar.close_price, 0.1, {})
        elif self.pos < 0 and deg > 0:
            calc_data["trade_open"] = "开多,deg={}".format(deg)
            sign()
            self.trade_mgr.cover(bar.close_price)
            return self.trade_mgr.buy(bar.close_price, 0.1, {})
        '''
示例#10
0
 def _init_k_data(self, code, k_data):
     # 注意:所有的数据库数据和列表数据都按照日期的正序排序(从小到大)
     """
     初始化股票数据库数据
     @:param code  股票(指数)代码                
     """     
     if len(k_data) != 0:
         last_5_vol = deque([0.0] * 5)
         last_5_amount = deque([0.0] * 5)
         k_data = k_data.sort_values(by='trade_date')            
         cl_stock_code = self.db[code]
         cl_stock_code.create_index([('trade_date', ASCENDING)], unique=True)
         am = ArrayManager(size=600)
         for ix, row in k_data.iterrows():
             d = row.to_dict()              
             d['ts_code'] = d['ts_code'].replace('.', '_')
             if 0.0 not in last_5_vol:
                 vol_rate = d['vol'] / (sum(last_5_vol) / 5.0)                
                 amount_rate = d['amount'] / (sum(last_5_amount) / 5.0)   
                 d['vol_rate'] = vol_rate
                 d['amount_rate'] = amount_rate 
             else:
                 d['vol_rate'] = 0.0
                 d['amount_rate'] = 0.0
             last_5_vol.popleft()
             last_5_amount.popleft()
             last_5_vol.append(d['vol'])
             last_5_amount.append(d['amount'])                   
             if self._is_in_vnpy_db(d['ts_code'], update=False):
                 # 构建vnpy股票数据库数据
                 self._build_db_vnpy(d)                               
             if d['ts_code'][-3:] == '_SH':
                 exchange = Exchange.SSE
                 d['exchange'] = 'SSE'
             else:
                 exchange = Exchange.SZSE                
                 d['exchange'] = 'SZSE'
             bar = BarData(
                 gateway_name='ctp', symbol=d['ts_code'],
                 exchange=exchange,
                 datetime=string_to_datetime(d['trade_date']))
             bar.symbol = d['ts_code']
             bar.volume = d['vol']
             bar.open_price = d['open']
             bar.high_price = d['high']
             bar.low_price = d['low']
             bar.close_price = d['close']
             am.update_bar(bar)
             try:
                 d['ma_5'] = am.sma(5)
             except:
                 traceback.print_exc()                    
                 LOG.error('************************')
                 LOG.error(d['ts_code'])
                 LOG.error(d['trade_date'])
                 LOG.error(bar)
             d['ma_10'] = am.sma(10)
             d['ma_20'] = am.sma(20)
             d['ma_30'] = am.sma(30)
             d['ma_60'] = am.sma(60)
             d['ma_120'] = am.sma(120)
             d['ma_250'] = am.sma(250)
             d['ma_500'] = am.sma(500)
             d['high_5'] = np.max(am.high[-5:])
             d['high_10'] = np.max(am.high[-10:])
             d['high_20'] = np.max(am.high[-20:])
             d['high_30'] = np.max(am.high[-30:])
             d['high_60'] = np.max(am.high[-60:])
             d['high_120'] = np.max(am.high[-120:])
             d['high_250'] = np.max(am.high[-250:])
             d['high_500'] = np.max(am.high[-500:])
             d['low_5'] = np.min(am.low[-5:])
             d['low_10'] = np.min(am.low[-10:])
             d['low_20'] = np.min(am.low[-20:])
             d['low_30'] = np.min(am.low[-30:])
             d['low_60'] = np.min(am.low[-60:])
             d['low_120'] = np.min(am.low[-120:])
             d['low_250'] = np.min(am.low[-250:])
             d['low_500'] = np.min(am.low[-500:])
             flt = {'trade_date': d['trade_date']}
             cl_stock_code.replace_one(flt, d, upsert=True)
class TurtleCStrategy(CtaTemplate):
    """"""
    # 反向海龟信号
    author = "turtle_inverse_trade"

    entry_window = 50
    exit_window = 20
    atr_window = 20
    stop_multiple = 2
    fixed_size = 1

    entry_up = 0
    entry_down = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

    long_entry = 0
    short_entry = 0
    long_stop = 0
    short_stop = 0

    parameters = [
        "entry_window", "exit_window", "atr_window", "fixed_size",
        "stop_multiple"
    ]
    variables = ["entry_up", "entry_down", "exit_up", "exit_down", "atr_value"]

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

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

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

    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_all()

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

        # Only calculates new entry channel when no position holding
        if not self.pos:
            self.entry_up, self.entry_down = self.am.donchian(
                self.entry_window)

            # self.close_ma = self.am.sma(50)
            # self.entry_up += self.close_ma * 0.002
            # self.entry_down -= self.close_ma * 0.002

        self.exit_up, self.exit_down = self.am.donchian(self.exit_window)

        if not self.pos:
            self.atr_value = self.am.atr(self.atr_window)

            self.long_entry = 0
            self.short_entry = 0
            self.long_stop = 0
            self.short_stop = 0

            self.send_buy_orders(self.entry_up)
            self.send_short_orders(self.entry_down)
        elif self.pos > 0:
            # inverse system
            # 有多头要卖出,等向上再卖出
            self.sell(self.exit_up, abs(self.pos), False)

        elif self.pos < 0:
            # inverse system
            # 有空头要买回,等向下再补回
            self.cover(self.exit_down, abs(self.pos), False)

        self.put_event()

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        if trade.direction == Direction.LONG:
            self.long_entry = trade.price
            self.long_stop = self.long_entry - self.stop_multiple * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + self.stop_multiple * self.atr_value

    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

    def send_buy_orders(self, price):
        """"""
        # invere system
        self.short(price, self.fixed_size, False)

    def send_short_orders(self, price):
        """"""
        # inverse system
        self.buy(price, self.fixed_size, False)
class MultiTimeframeStrategy(CtaTemplate):
    """"""
    author = "KK Taiwan 交易員"

    rsi_signal = 20
    rsi_window = 14
    fast_window = 12 # init define for 5mins * 12 = 1HR  
    slow_window = 30# inti define for 5mins * 36 = 3HR
    fixed_size = 1

    rsi_value = 0
    rsi_long = 0
    rsi_short = 0
    fast_ma = 0
    slow_ma = 0
    ma_trend = 0

    parameters = ["rsi_signal", "rsi_window",
                  "fast_window", "slow_window",
                  "fixed_size"]

    variables = ["rsi_value", "rsi_long", "rsi_short",
                 "fast_ma", "slow_ma", "ma_trend","fast_ma1","slow_ma1"]
    

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        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.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)

        if self.pos == 0:
            if self.ma_trend > 0 and self.rsi_value >= self.rsi_long:
                self.buy(bar.close_price + 5, self.fixed_size)
            elif self.ma_trend < 0 and self.rsi_value <= self.rsi_short:
                self.short(bar.close_price - 5, self.fixed_size)

        elif self.pos > 0:
            if self.ma_trend < 0 or self.rsi_value < 50:
                self.sell(bar.close_price - 5, abs(self.pos))

        elif self.pos < 0:
            if self.ma_trend > 0 or self.rsi_value > 50:
                self.cover(bar.close_price + 5, abs(self.pos))

        ###KK 跟新長倉策略
        self.pettyfast_ma = self.am5.sma(self.fast_window)
        self.pettyslow_ma = self.am5.sma(self.slow_window)
        if self.pettyfast_ma > self.pettyslow_ma:
            self.ma_pettytrend = 1
        else:
            self.ma_pettytrend = -1
          

    #####
        if(buy list) 
          if (self.ma_pettytrend < 0) and (time > 0)
             if 虧 
              平倉時間點限制 - 2 time
              if < 1 平倉
             else
              平倉時間點限制 - time 
             if < 1
               跟新下限 from 15 mins均線
               #改為短平倉 and update limit
          else if time < 10
             平倉時間點限制 +time

        if(short list) 
           if (self.ma_pettytrend > 0) and (time > 0)
             if 虧 
               平倉時間點限制 - 2 time
               if timw<1
                  平倉
             else
              平倉時間點限制 - time
               if < 1
                   跟新下限 from 15 mins均線
          else if time < 10 
             平倉時間點限制 + time

        if self.pos == 0:
            if self.ma_trend > 0 and self.rsi_value >= self.rsi_long:
                self.buy_signal(bar.close_price + 5, self.fixed_size)
            elif self.ma_trend < 0 and self.rsi_value <= self.rsi_short:
                self.short(bar.close_price - 5, self.fixed_size)

        elif self.pos > 0:
            if self.ma_trend < 0 or self.rsi_value < 50:
                self.sell_signal(bar.close_price - 5, abs(self.pos))

        elif self.pos < 0:
            if self.ma_trend > 0 or self.rsi_value > 50:
                self.cover_signal(bar.close_price + 5, abs(self.pos))
        ###
            
        self.put_event()
示例#13
0
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
示例#14
0
class MultiTimeframeStrategy(CtaTemplate):
    """"""
    author = '用Python的交易员'

    rsi_signal = 20
    rsi_window = 14
    fast_window = 5
    slow_window = 20
    fixed_size = 1

    rsi_value = 0
    rsi_long = 0
    rsi_short = 0
    fast_ma = 0
    slow_ma = 0
    ma_trend = 0

    parameters = ['rsi_signal', 'rsi_window',
                  'fast_window', 'slow_window',
                  'fixed_size']

    variables = ['rsi_value', 'rsi_long', 'rsi_short',
                 'fast_ma', 'slow_ma', 'ma_trend']

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(MultiTimeframeStrategy, 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)

        if self.pos == 0:
            if self.ma_trend > 0 and self.rsi_value >= self.rsi_long:
                self.buy(bar.close_price + 5, self.fixed_size)
            elif self.ma_trend < 0 and self.rsi_value <= self.rsi_short:
                self.short(bar.close_price - 5, self.fixed_size)

        elif self.pos > 0:
            if self.ma_trend < 0 or self.rsi_value < 50:
                self.sell(bar.close_price - 5, abs(self.pos))

        elif self.pos < 0:
            if self.ma_trend > 0 or self.rsi_value > 50:
                self.cover(bar.close_price + 5, abs(self.pos))

        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
示例#15
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()
示例#16
0
class TurtleSignalStrategy(CtaTemplate):
    """"""
    author = "backtest example"

    entry_window = 20
    exit_window = 10
    atr_window = 20
    fixed_size = 1

    entry_up = 0
    entry_down = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

    long_entry = 0
    short_entry = 0
    long_stop = 0
    short_stop = 0

    parameters = ["entry_window", "exit_window", "atr_window", "fixed_size"]
    variables = ["entry_up", "entry_down", "exit_up", "exit_down", "atr_value"]

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

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

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

    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_all()

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

        # Only calculates new entry channel when no position holding
        if not self.pos:
            self.entry_up, self.entry_down = self.am.donchian(
                self.entry_window)

        self.exit_up, self.exit_down = self.am.donchian(self.exit_window)

        if not self.pos:
            self.atr_value = self.am.atr(self.atr_window)

            self.long_entry = 0
            self.short_entry = 0
            self.long_stop = 0
            self.short_stop = 0

            self.send_buy_orders(self.entry_up)
            self.send_short_orders(self.entry_down)
        elif self.pos > 0:

            sell_price = max(self.long_stop, self.exit_down)
            self.sell(sell_price, abs(self.pos), True)

        elif self.pos < 0:

            cover_price = min(self.short_stop, self.exit_up)
            self.cover(cover_price, abs(self.pos), True)

        self.put_event()

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        if trade.direction == Direction.LONG:
            self.long_entry = trade.price
            self.long_stop = self.long_entry - 2 * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + 2 * self.atr_value

    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

    def send_buy_orders(self, price):
        """"""
        self.buy(price, self.fixed_size, True)

    def send_short_orders(self, price):
        """"""
        self.short(price, self.fixed_size, True)
示例#17
0
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
示例#18
0
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()
示例#19
0
class ImprovedDtStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    fixed_size = 1
    k1 = 0.15
    k2 = 0.25
    rsi_window = 30
    rsi_signal = 10
    trailing_long = 0.8
    trailing_short = 1.4

    daily_limit = 0

    day_open = 0
    day_high = 0
    day_low = 0

    day_range = 0
    long_entry = 0
    short_entry = 0

    intra_trade_high = 0
    intra_trade_low = 0

    daily_count = 0

    parameters = [
        "k1", "k2", "rsi_window", "rsi_signal", "trailing_long",
        "trailing_short", "fixed_size"
    ]
    variables = ["day_range", "long_entry", "short_entry"]

    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.am = ArrayManager()

        self.last_bar = None

    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.cancel_all()

        self.am.update_bar(bar)

        # 计算DT范围
        if not self.last_bar:
            self.last_bar = bar
            return

        if self.last_bar.datetime.date() != bar.datetime.date():
            if self.day_high:
                self.day_range = self.day_high - self.day_low
                self.long_entry = bar.open_price + self.k1 * self.day_range
                self.short_entry = bar.open_price - self.k2 * self.day_range

            self.day_open = bar.open_price
            self.day_high = bar.high_price
            self.day_low = bar.low_price

            self.long_entered = False
            self.short_entered = False

            self.daily_count = 0
        else:
            self.day_high = max(self.day_high, bar.high_price)
            self.day_low = min(self.day_low, bar.low_price)

        self.last_bar = bar

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

        # 计算技术指标
        rsi_value = self.am.rsi(self.rsi_window)

        # 交易逻辑执行
        if self.pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            if self.daily_count < self.daily_limit:
                if rsi_value >= 50 + self.rsi_signal:
                    self.buy(self.long_entry, self.fixed_size, True)
                elif rsi_value <= 50 - self.rsi_signal:
                    self.short(self.short_entry, 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_stop = self.intra_trade_high * (1 - self.trailing_long / 100)
            long_stop = max(long_stop, self.short_entry)
            self.sell(long_stop, self.fixed_size, True)

            self.short(self.short_entry, self.fixed_size, True)

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

            short_stop = self.intra_trade_low * (1 + self.trailing_short / 100)
            short_stop = min(short_stop, self.long_entry)
            self.cover(short_stop, self.fixed_size, True)

            self.buy(self.long_entry, self.fixed_size, True)

        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.
        """
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
示例#20
0
class RsiSignal(CtaSignal):
    """"""
    minute_5_window = 5
    minute_15_window = 15
    minute_30_window = 30
    hour_1_window = 1

    ris_15_value = 0


    def __init__(self, rsi_fast_window: int, rsi_middle_window: int, rsi_slow_window: int, rsi_level: float):
        """Constructor"""
        super().__init__()

        self.rsi_fast_window = rsi_fast_window
        self.rsi_middle_window = rsi_middle_window
        self.rsi_slow_window = rsi_slow_window

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

        self.bg5 = BarGenerator(on_bar=self.on_bar, window=self.minute_5_window, on_window_bar=self.on_5minute_bar)
        self.am5 = ArrayManager()
        self.bg15 = BarGenerator(on_bar=self.on_bar, window=self.minute_15_window, on_window_bar=self.on_15minute_bar)
        self.am15 = ArrayManager()
        self.bg30 = BarGenerator(on_bar=self.on_bar, window=self.minute_30_window, on_window_bar=self.on_15minute_bar)
        self.am30 = ArrayManager()
        self.bg60 = BarGenerator(on_bar=self.on_bar,
                                 window=self.hour_1_window,
                                 on_window_bar=self.on_hour_bar,
                                 interval=Interval.HOUR)
        self.am60 = ArrayManager()

    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.am60.update_bar(bar)
        self.am30.update_bar(bar)
        self.am15.update_bar(bar)
        self.bg5.update_bar(bar)

    def on_5minute_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.am5.update_bar(bar)
        if not self.am5.inited:
            self.set_signal_pos(0)
            return

        rsi_fast_value = self.am5.rsi(self.rsi_fast_window, True)
        rsi_middle_value = self.am5.rsi(self.rsi_middle_window, True)
        rsi_slow_value = self.am5.rsi(self.rsi_slow_window, True)

        if rsi_value >= self.rsi_long:
            self.set_signal_pos(1)
        elif rsi_value <= self.rsi_short:
            self.set_signal_pos(-1)
        else:
            self.set_signal_pos(0)

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

        rsi_fast_value = self.am15.rsi(self.rsi_fast_window, True)
        rsi_middle_value = self.am15.rsi(self.rsi_middle_window, True)
        rsi_slow_value = self.am15.rsi(self.rsi_slow_window, True)

        last_fast_value = rsi_fast_value[-1]
        current_fast_value = rsi_fast_value[-2]

        last_middle_value = rsi_middle_value[-1]
        current_middle_value = rsi_middle_value[-2]

        last_slow_value = rsi_slow_value[-1]
        current_slow_value = rsi_slow_value[-2]


    def on_30minute_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.am30.update_bar(bar)
        if not self.am30.inited:
            return

        rsi_fast_value = self.am30.rsi(self.rsi_fast_window, True)
        rsi_middle_value = self.am30.rsi(self.rsi_middle_window, True)
        rsi_slow_value = self.am30.rsi(self.rsi_slow_window, True)

        last_fast_value = rsi_fast_value[-1]
        current_fast_value = rsi_fast_value[-2]

        last_middle_value = rsi_middle_value[-1]
        current_middle_value = rsi_middle_value[-2]

        last_slow_value = rsi_slow_value[-1]
        current_slow_value = rsi_slow_value[-2]

    def on_hour_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.am60.update_bar(bar)
        if not self.am60.inited:
            return


    def on_rsi(self,close, fast, slow, rsi_long, rsi_short):
        """
        判断 rsi 在80 20线上下方金叉,死叉
        :param close:
        :param fast:
        :param middle:
        :param slow:
        :param rsi_long:
        :param rsi_short:
        :return:
        """

        rsi_fast_value = talib.RSI(close, fast)
        rsi_slow_value = talib.RSI(close, slow)

        last_fast_value = rsi_fast_value[-2]
        current_fast_value = rsi_fast_value[-1]

        last_slow_value = rsi_slow_value[-2]
        current_slow_value = rsi_slow_value[-1]

        # 判断 20线 下方 金叉
        if last_fast_value < rsi_short:
            if last_fast_value <= last_slow_value and current_fast_value > current_slow_value:
                rsi_long_inited = 1

        elif last_fast_value >= last_slow_value and current_fast_value < current_slow_value:
                rsi_long_inited = -1
            else:
                rsi_long_initde = 0
class MaxSharpeStrategy(CtaTemplate):

    M = 10
    predictor = PositionPredictor(M)
    if exists('weights.h5'):
        predictor.load_weights('weights.h5')
    parameters = ["M"]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):

        super(MaxSharpeStrategy, self).__init__(cta_engine, strategy_name,
                                                vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar)
        self.am = ArrayManager(3 + self.M)
        # am.shape = (3 + M)

    def on_init(self):

        self.write_log('策略初始化')
        self.load_bar(len(self.cta_engine.history_data))
        self.mu = self.cta_engine.capital / self.cta_engine.size
        # how many possible positions

    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.cancel_all()
        self.am.update_bar(bar)
        if not self.am.inited: return
        xt = np.ones((self.M + 3), dtype=np.float32)
        # xt.shape = (M + 3)
        for i in range(1, self.M + 2):
            xt[i] = self.am.close[i] - self.am.close[i - 1]
        xt[self.M + 2] = self.pos / self.mu
        xt = tf.expand_dims(xt, axis=0)
        # xt.shape = (batch = 1, M + 3)
        F_t = self.predictor(xt)
        pos = int(F_t * self.mu)
        if self.pos > 0 and pos > 0:
            if pos > self.pos:
                self.buy(bar.close_price, pos - self.pos, stop=True)
            if pos < self.pos:
                self.sell(bar.close_price, self.pos - pos, stop=True)
        elif self.pos > 0 and pos < 0:
            self.sell(bar.close_price, abs(self.pos), stop=True)
            self.short(bar.close_price, abs(pos), stop=True)
        elif self.pos < 0 and pos < 0:
            if pos < self.pos:
                self.short(bar.close_price, self.pos - pos, stop=True)
            if pos > self.pos:
                self.cover(bar.close_price, pos - self.pos, stop=True)
        else:  # self.pos < 0 and pos > 0
            self.cover(bar.close_price, abs(self.pos), stop=True)
            self.buy(bar.close_price, abs(pos), stop=True)
        self.put_event()

    def on_trade(self, trade: TradeData):

        pass

    def on_order(self, order: OrderData):

        pass

    def on_stop_order(self, stop_order: StopOrder):

        pass
示例#22
0
 def _update_k_data(self, code, k_data):
     # 注意:所有的数据库数据和列表数据都按照日期的正序排序(从小到大)
     """
     更新股票,股指每日数据(行情,K线,市值等0)
     @:param code  股票(指数)代码                
     @:param k_data  ts中获取的最新df数据
     """        
     if len(k_data) != 0:
         k_data = k_data.sort_values(by='trade_date')            
         cl_stock_code = self.db[code]
         cl_stock_code.create_index([('trade_date', ASCENDING)], unique=True)
         # 更新k线数据
         # 1、新增日K线入库
         # 2、遍历数据库找出最近的500+22(必须保证更新数据操作在22天以内进行)条数据并更新最后的22条的ma和最高 最低价
         for ix, row in k_data.iterrows():
             d = row.to_dict()
             d['ts_code'] = d['ts_code'].replace('.', '_')
             if self._is_in_vnpy_db(d['ts_code'], update=True):
                 # 更新vnpy数据库数据                    
                 self._build_db_vnpy(d)
             flt = {'trade_date': d['trade_date']}
             cl_stock_code.replace_one(flt, d, upsert=True)
         rec = list(cl_stock_code.find({}).sort("trade_date", DESCENDING).limit(522))
         rec.reverse()
         am = ArrayManager(size=600)
         last_5_vol = deque([0.0] * 5)
         last_5_amount = deque([0.0] * 5)
         for d in rec:                
             if 0.0 not in last_5_vol:
                 vol_rate = d['vol'] / (sum(last_5_vol) / 5.0)               
                 amount_rate = d['amount'] / (sum(last_5_amount) / 5.0)   
                 d['vol_rate'] = vol_rate
                 d['amount_rate'] = amount_rate 
             else:
                 d['vol_rate'] = 0.0
                 d['amount_rate'] = 0.0
             last_5_vol.popleft()
             last_5_amount.popleft()
             last_5_vol.append(d['vol'])
             last_5_amount.append(d['amount'])                                       
             if d['ts_code'][-3:] == '_SH':
                 exchange = Exchange.SSE
                 d['exchange'] = 'SSE'
             else:
                 exchange = Exchange.SZSE
                 d['exchange'] = 'SZSE'                
             bar = BarData(
                 gateway_name='ctp', symbol=d['ts_code'],
                 exchange=exchange,
                 datetime=string_to_datetime(d['trade_date']))
             bar.symbol = d['ts_code']
             bar.volume = d['vol']
             bar.open_price = d['open']
             bar.high_price = d['high']
             bar.low_price = d['low']
             bar.close_price = d['close']
             am.update_bar(bar)
             if d['trade_date'] >= self.db_date:
                 d['ma_5'] = am.sma(5)
                 d['ma_10'] = am.sma(10)
                 d['ma_20'] = am.sma(20)
                 d['ma_30'] = am.sma(30)
                 d['ma_60'] = am.sma(60)
                 d['ma_120'] = am.sma(120)
                 d['ma_250'] = am.sma(250)
                 d['ma_500'] = am.sma(500)
                 d['high_5'] = np.max(am.high[-5:])
                 d['high_10'] = np.max(am.high[-10:])
                 d['high_20'] = np.max(am.high[-20:])
                 d['high_30'] = np.max(am.high[-30:])
                 d['high_60'] = np.max(am.high[-60:])
                 d['high_120'] = np.max(am.high[-120:])
                 d['high_250'] = np.max(am.high[-250:])
                 d['high_500'] = np.max(am.high[-500:])
                 d['low_5'] = np.min(am.low[-5:])
                 d['low_10'] = np.min(am.low[-10:])
                 d['low_20'] = np.min(am.low[-20:])
                 d['low_30'] = np.min(am.low[-30:])
                 d['low_60'] = np.min(am.low[-60:])
                 d['low_120'] = np.min(am.low[-120:])
                 d['low_250'] = np.min(am.low[-250:])
                 d['low_500'] = np.min(am.low[-500:])
                 flt = {'trade_date': d['trade_date']}
                 cl_stock_code.replace_one(flt, d, upsert=True)
示例#23
0
class TurtleSignalStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    entry_window = 20
    exit_window = 10
    atr_window = 20
    fixed_size = 1

    entry_up = 0
    entry_down = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

    long_entry = 0
    short_entry = 0
    long_stop = 0
    short_stop = 0

    parameters = ["entry_window", "exit_window", "atr_window", "fixed_size"]
    variables = ["entry_up", "entry_down", "exit_up", "exit_down", "atr_value"]

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

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

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

    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_all()

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

        self.entry_up, self.entry_down = self.am.donchian(self.entry_window)
        self.exit_up, self.exit_down = self.am.donchian(self.exit_window)

        if not self.pos:
            self.atr_value = self.am.atr(self.atr_window)

            self.long_entry = 0
            self.short_entry = 0
            self.long_stop = 0
            self.short_stop = 0

            self.send_buy_orders(self.entry_up)
            self.send_short_orders(self.entry_down)
        elif self.pos > 0:
            self.send_buy_orders(self.long_entry)

            sell_price = max(self.long_stop, self.exit_down)
            self.sell(sell_price, abs(self.pos), True)

        elif self.pos < 0:
            self.send_short_orders(self.short_entry)

            cover_price = min(self.short_stop, self.exit_up)
            self.cover(cover_price, abs(self.pos), True)

        self.put_event()

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        if trade.direction == Direction.LONG:
            self.long_entry = trade.price
            self.long_stop = self.long_entry - 2 * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + 2 * self.atr_value

    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

    def send_buy_orders(self, price):
        """"""
        t = self.pos / self.fixed_size

        if t < 1:
            self.buy(price, self.fixed_size, True)

        if t < 2:
            self.buy(price + self.atr_value * 0.5, self.fixed_size, True)

        if t < 3:
            self.buy(price + self.atr_value, self.fixed_size, True)

        if t < 4:
            self.buy(price + self.atr_value * 1.5, self.fixed_size, True)

    def send_short_orders(self, price):
        """"""
        t = self.pos / self.fixed_size

        if t > -1:
            self.short(price, self.fixed_size, True)

        if t > -2:
            self.short(price - self.atr_value * 0.5, self.fixed_size, True)

        if t > -3:
            self.short(price - self.atr_value, self.fixed_size, True)

        if t > -4:
            self.short(price - self.atr_value * 1.5, self.fixed_size, True)
示例#24
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()
示例#25
0
class SuperTurtleStrategyHNTest(CtaTemplate):
    """"""
    author = "Huang Ning"

    entry_window = 28
    exit_window = 7
    atr_window = 4
    risk_level = 0.2

    trading_size = 0
    entry_up = 0
    entry_down = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

    long_entry = 0
    short_entry = 0
    long_stop = 0
    short_stop = 0

    parameters = ["entry_window", "exit_window", "atr_window", "risk_level"]
    variables = [
        "entry_up", "entry_down", "exit_up", "exit_down", "trading_size",
        "atr_value"
    ]

    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,
                               1,
                               self.on_hour_bar,
                               interval=Interval.HOUR)
        self.am = ArrayManager()

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

    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_hour_bar(self, bar: BarData):
        """"""

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

        self.entry_up, self.entry_down = self.am.donchian(self.entry_window)
        self.exit_up, self.exit_down = self.am.donchian(self.exit_window)

        if not self.pos:
            self.atr_value = self.am.atr(self.atr_window)

            if self.atr_value == 0:
                return

            atr_risk = talib.ATR(1 / self.am.high, 1 / self.am.low,
                                 1 / self.am.close, self.atr_window)[-1]
            self.trading_size = max(int(self.risk_level / atr_risk), 1)

            self.long_entry = 0
            self.short_entry = 0
            self.long_stop = 0
            self.short_stop = 0

            self.buy(self.entry_up, self.trading_size, True)
            self.short(self.entry_down, self.trading_size, True)

        elif self.pos > 0:
            sell_price = max(self.long_stop, self.exit_down)
            self.sell(sell_price, abs(self.pos), True)

        elif self.pos < 0:
            cover_price = min(self.short_stop, self.exit_up)
            self.cover(cover_price, abs(self.pos), True)

        self.put_event()

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        if trade.direction == Direction.LONG:
            self.long_entry = trade.price
            self.long_stop = self.long_entry - 2 * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + 2 * self.atr_value

        self.sync_data()

    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
示例#26
0
class MultiTimeframeStrategyHNTest(CtaTemplate):
    """"""
    author = "Huang Ning"

    parameters = []

    variables = []

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

        self.pricetick = self.get_pricetick()

        self.bg1 = XminBarGenerator(self.on_bar, self.bar_window1,
                                    self.on_Xmin1_bar)
        self.am1 = ArrayManager()

        self.bg2 = XminBarGenerator(self.on_bar, self.bar_window2,
                                    self.on_Xmin2_bar)
        self.am2 = ArrayManager()

        self.buy_vt_orderids = []
        self.sell_vt_orderids = []
        self.short_vt_orderids = []
        self.cover_vt_orderids = []

        self.buy_price = 0
        self.sell_price = 0
        self.short_price = 0
        self.cover_price = 0

    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.bg1.update_tick(tick)

    def on_bar(self, bar: BarData):
        """"""
        # 注意:不同周期K线合成的顺序对结果是有影响的
        self.bg1.update_bar(bar)
        self.bg2.update_bar(bar)

        if self.buy_vt_orderids:
            for vt_orderid in self.buy_vt_orderids:
                self.cancel_order(vt_orderid)
            self.buy_vt_orderids = self.buy(
                bar.close_price + self.pricetick * self.pricetick_multilplier2,
                self.fixed_size, True)

        elif self.sell_vt_orderids:
            for vt_orderid in self.sell_vt_orderids:
                self.cancel_order(vt_orderid)
            self.sell_vt_orderids = self.sell(
                bar.close_price - self.pricetick * self.pricetick_multilplier2,
                self.fixed_size, True)

        elif self.short_vt_orderids:
            for vt_orderid in self.short_vt_orderids:
                self.cancel_order(vt_orderid)
            self.short_vt_orderids = self.short(
                bar.close_price - self.pricetick * self.pricetick_multilplier2,
                self.fixed_size, True)

        elif self.cover_vt_orderids:
            for vt_orderid in self.cover_vt_orderids:
                self.cancel_order(vt_orderid)
            self.cover_vt_orderids = self.cover(
                bar.close_price + self.pricetick * self.pricetick_multilplier2,
                self.fixed_size, True)

    def on_Xmin1_bar(self, bar: BarData):
        """"""
        self.am1.update_bar(bar)
        if not self.am1.inited:
            return

        if not self.ma_trend:
            return

        self.rsi_value = self.am1.rsi(self.rsi_window)

        if self.pos == 0:
            self.buy_price = bar.close_price + self.pricetick * self.pricetick_multiplier1
            self.sell_price = 0
            self.short_price = bar.close_price - self.pricetick * self.pricetick_multiplier1
            self.cover_price = 0

        elif self.pos > 0:
            self.buy_price = 0
            self.sell_price = bar.close_price - self.pricetick * self.pricetick_multiplier1
            self.short_price = 0
            self.cover_price = 0

        else:
            self.buy_price = 0
            self.sell_price = 0
            self.short_price = 0
            self.cover_price = bar.close_price + self.pricetick * self.pricetick_multiplier1

        if self.pos == 0:
            if not self.buy_vt_orderids:
                if self.ma_trend > 0 and self.rsi_value >= self.rsi_long:
                    self.buy(self.buy_price, self.fixed_size, True)
                    self.buy_price = 0
            else:
                for vt_orderid in self.buy_vt_orderids:
                    self.cancel_order(vt_orderid)

            if not self.short_vt_orderids:
                if self.ma_trend < 0 and self.rsi_value <= self.rsi_short:
                    self.short(self.short_price, self.fixed_size, True)
                    self.short_price = 0
            else:
                for vt_orderid in self.short_vt_orderids:
                    self.cancel_order(vt_orderid)

        elif self.pos > 0:
            if not self.sell_vt_orderids:
                if self.ma_trend < 0 or self.rsi_value < 50:
                    self.sell(self.sell_price, abs(self.pos), True)
                    self.sell_price = 0
            else:
                for vt_orderid in self.sell_vt_orderids:
                    self.cancel_order(vt_orderid)

        else:
            if not self.cover_vt_orderids:
                if self.ma_trend > 0 or self.rsi_value > 50:
                    self.cover(self.cover_price, abs(self.pos), True)
                    self.cover_price = 0
            else:
                for vt_orderid in self.cover_vt_orderids:
                    self.cancel_order(vt_orderid)

    def on_Xmin2_bar(self, bar: BarData):
        """"""
        self.am2.update_bar(bar)
        if not self.am2.inited:
            return

        self.fast_ma = self.am2.sma(self.fast_window)
        self.slow_ma = self.am2.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 = -1
        else:
            self.ma_trend = 0

    def on_stop_order(self, stop_order: StopOrder):
        """"""
        if stop_order.status == StopOrderStatus.WAITING:
            return

        for buf_orderids in [
                self.buy_vt_orderids, self.sell_vt_orderids,
                self.short_vt_orderids, self.cover_vt_orderids
        ]:
            if stop_order.stop_orderid in buf_orderids:
                buf_orderids.remove(stop_order.stop_orderid)
示例#27
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
示例#28
0
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
示例#29
0
class BollingerBotStrategy(CtaTemplate):
    """基于布林通道的交易策略"""
    className = 'BollingerBotStrategy'
    author = u'ForwardCapital'

    # 策略参数
    bollWindow = 28  # 通道窗口数
    entryDev = 3.2  # 开仓偏差
    exitDev = 1.2  # 平仓偏差
    trailingPrcnt = 0.4  # 移动止损百分比
    maWindow = 10  # 过滤用均线窗口
    initDays = 10  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量

    # 策略变量
    bollMid = 0  # 布林带中轨
    bollStd = 0  # 布林带宽度
    entryUp = 0  # 开仓上轨
    exitUp = 0  # 平仓上轨

    maFilter = 0  # 均线过滤
    maFilter1 = 0  # 上一期均线

    intraTradeHigh = 0  # 持仓期内的最高点
    longEntry = 0  # 多头开仓
    longExit = 0  # 多头平仓

    orderList = []  # 保存委托代码的列表
    buyOrderID = None
    sellOrderID = None

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

    # 变量列表,保存了变量的名称
    varList = [
        'inited', 'trading', 'pos', 'bollMid', 'bollStd', 'entryUp', 'exitUp',
        'intraTradeHigh', 'longEntry', 'longExit'
    ]

    # 同步列表
    syncList = ['pos', 'intraTradeHigh']

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

        self.bm = BarGenerator(self.on_bar, 15, self.onFiveBar)
        self.am = ArrayManager()

    #----------------------------------------------------------------------
    def on_init(self):
        """初始化策略(必须由用户继承实现)"""
        self.write_log(u'策略初始化')

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        self.load_bar(self.initDays)

        self.put_event()

    #----------------------------------------------------------------------
    def on_start(self):
        """启动策略(必须由用户继承实现)"""
        self.write_log(u'策略启动')
        self.put_event()

    #----------------------------------------------------------------------
    def on_stop(self):
        """停止策略(必须由用户继承实现)"""
        self.write_log(u'策略停止')
        self.put_event()

    #----------------------------------------------------------------------
    def on_tick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bm.update_tick(tick)

    #----------------------------------------------------------------------
    def on_bar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.bm.update_bar(bar)

    #----------------------------------------------------------------------
    def orderIDConvert(self, orderList):
        if not orderList:
            return []
        else:
            return orderList[0]

    #----------------------------------------------------------------------
    def onFiveBar(self, bar):
        """收到5分钟K线"""
        # 保存K线数据
        self.am.update_bar(bar)
        if not self.am.inited or not self.trading:
            return

        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        # 计算指标数值
        self.bollMid = self.am.sma(self.bollWindow)
        self.bollStd = self.am.std(self.bollWindow)
        self.entryUp = self.bollMid + self.bollStd * self.entryDev
        self.exitUp = self.bollMid + self.bollStd * self.exitDev

        maArray = self.am.sma(self.maWindow, True)
        self.maFilter = maArray[-1]
        self.maFilter1 = maArray[-2]

        # 判断是否要进行交易
        if not self.buyOrderID:
            if self.pos == 0:
                self.intraTradeHigh = bar.high
                # 下开仓单
                if bar.close > self.maFilter and self.maFilter > self.maFilter1:
                    self.longEntry = self.entryUp
                    self.buyOrderID = self.buy(self.longEntry, self.fixedSize,
                                               True)
                    self.buyOrderID = self.orderIDConvert(self.buyOrderID)
                    print('order None!!!buyOrderID is : %s ' % self.buyOrderID)
                    self.orderList.append(self.buyOrderID)
                    # 下平仓单
                    self.longExit = self.intraTradeHigh * (
                        1 - self.trailingPrcnt / 100)
                    self.longExit = min(self.longExit, self.exitUp)

                    self.sellOrderID = self.sell(self.longExit, abs(self.pos),
                                                 True)
                    self.sellOrderID = self.orderIDConvert(self.sellOrderID)
                    print('order None!!!ellOrderID is : %s ' %
                          self.sellOrderID)
                    self.orderList.append(self.sellOrderID)
            elif self.pos > 0:
                self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
                # 下平仓单
                self.longExit = self.intraTradeHigh * (
                    1 - self.trailingPrcnt / 100)
                self.longExit = min(self.longExit, self.exitUp)

                self.sellOrderID = self.sell(self.longExit, abs(self.pos),
                                             True)
                self.sellOrderID = self.orderIDConvert(self.sellOrderID)
                print('order None!!!sellOrderID is : %s ' % self.sellOrderID)
                self.orderList.append(self.sellOrderID)

        else:
            if self.buyOrderID in self.orderList:
                self.intraTradeHigh = bar.high
                self.cancel_all()
                # 下开仓单
                if bar.close > self.maFilter and self.maFilter > self.maFilter1:
                    self.longEntry = self.entryUp
                    self.buyOrderID = self.buy(self.longEntry, self.fixedSize,
                                               True)
                    print('buyOrderID is : %s ' % self.buyOrderID)
                    self.buyOrderID = self.orderIDConvert(self.buyOrderID)
                    self.orderList.append(self.buyOrderID)
                    # 下平仓单
                    self.longExit = self.intraTradeHigh * (
                        1 - self.trailingPrcnt / 100)
                    self.longExit = min(self.longExit, self.exitUp)

                    self.sellOrderID = self.sell(self.longExit, abs(self.pos),
                                                 True)
                    self.sellOrderID = self.orderIDConvert(self.sellOrderID)
                    print('sellOrderID is : %s ' % self.sellOrderID)
                    self.orderList.append(self.sellOrderID)
            else:
                if self.sellOrderID in self.orderList:
                    self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
                    self.cancel_order(self.sellOrderID)
                    # 下平仓单
                    self.longExit = self.intraTradeHigh * (
                        1 - self.trailingPrcnt / 100)
                    self.longExit = min(self.longExit, self.exitUp)

                    self.sellOrderID = self.sell(self.longExit, abs(self.pos),
                                                 True)
                    self.sellOrderID = self.orderIDConvert(self.sellOrderID)
                    print('sellOrderID is : %s ' % self.sellOrderID)
                    self.orderList.append(self.sellOrderID)
                else:
                    self.intraTradeHigh = bar.high
                    # 下开仓单
                    if bar.close > self.maFilter and self.maFilter > self.maFilter1:
                        self.longEntry = self.entryUp
                        self.buyOrderID = self.buy(self.longEntry,
                                                   self.fixedSize, True)
                        self.buyOrderID = self.orderIDConvert(self.buyOrderID)
                        print('buyOrderID is : %s ' % self.buyOrderID)
                        self.orderList.append(self.buyOrderID)
                        # 下平仓单
                        self.longExit = self.intraTradeHigh * (
                            1 - self.trailingPrcnt / 100)
                        self.longExit = min(self.longExit, self.exitUp)

                        self.sellOrderID = self.sell(self.longExit,
                                                     abs(self.pos), True)
                        self.sellOrderID = self.orderIDConvert(
                            self.sellOrderID)
                        print('sellOrderID is : %s ' % self.sellOrderID)
                        self.orderList.append(self.sellOrderID)

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

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

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

    #----------------------------------------------------------------------
    def onStopOrder(self, so):
        """停止单推送"""
        print(u'StopOrder回报,stopOrderID:%s, status:%s' %
              (so.stopOrderID, so.status))
        if so.status == StopOrderStatus.CANCELLED or so.status == StopOrderStatus.TRIGGERED:
            self.orderList.remove(so.stopOrderID)
        pass
示例#30
0
class HLBeatStrategy(CtaTemplate):
    """基于布林通道的交易策略"""
    className = 'HLBeatStrategy'
    author = u'ForwardCapital'

    # 策略参数
    turtleWindow = 20  # 通道窗口数
    ma1Window = 5  # 过滤用均线窗口
    ma2Window = 10  # 过滤用均线窗口
    initDays = 10  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量
    xMinBar = 15

    # 策略变量
    periodHigh = 0  # 布林带中轨
    periodLow = 0  # 布林带宽度

    entryUp = 0  # 开仓上轨
    longEntry = 0
    entryDown = 0
    shortEntry = 0  # 开仓下轨
    exitUp = 0  # 平仓上轨
    shortExit = 0
    exitDown = 0
    longExit = 0  # 平仓上轨

    CCIFilter = 0  # 均线过滤
    CCIFilter1 = 0  # 上一期均线

    intraTradeHigh = 0  # 持仓期内的最高点
    intraTradeLow = 0  # 持仓期内的最低点
    longEntry = 0  # 多头开仓
    longExit = 0  # 多头平仓

    orderList = []  # 保存委托代码的列表
    buyOrderID = None
    sellOrderID = None
    shortOrderID = None
    coverOrderID = None

    minute = None
    timeFuncTurn = False

    # 参数列表,保存了参数的名称
    paramList = [
        'className', 'author', 'vtSymbol', "turtleWindow", "ma1Window",
        "ma2Window", "xMinBar"
    ]

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

    # 同步列表
    syncList = [
        'pos', 'sellOrderID', 'coverOrderID', 'shortOrderID', 'buyOrderID',
        'longExit', 'shortExit', 'orderList'
    ]

    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(HLBeatStrategy, self).__init__(ctaEngine, setting)
        self.bm = BarGenerator(self.on_bar, self.xMinBar, self.onFiveBar)
        self.am = ArrayManager()

        self.cta_engine.eventEngine.register(EVENT_TIMER, self.onTimeFunc)

    #----------------------------------------------------------------------
    def on_init(self):
        """初始化策略(必须由用户继承实现)"""
        self.write_log(u'策略初始化')

        # 载入历史数据,并采用回放计算的方式初始化策略数值
        self.load_bar(self.initDays)

        self.put_event()

    #----------------------------------------------------------------------
    def on_start(self):
        """启动策略(必须由用户继承实现)"""
        self.write_log(u'策略启动')
        self.put_event()

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

        self.write_log(u'策略停止')
        self.put_event()

    #----------------------------------------------------------------------
    def on_tick(self, tick):
        """收到行情TICK推送(必须由用户继承实现)"""
        self.bm.update_tick(tick)

    #----------------------------------------------------------------------
    def on_bar(self, bar):
        """收到Bar推送(必须由用户继承实现)"""
        self.bm.update_bar(bar)

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

        # 计算指标数值
        self.exitUp = min(self.am.low[-self.turtleWindow / 2:])
        self.exitDown = max(self.am.high[-self.turtleWindow / 2:])

        # 只发平仓单
        if self.pos > 0:
            if not self.longExit:
                self.longExit = self.exitDown

                if self.sellOrderID:
                    self.cancel_order
                    (self.sellOrderID)
                else:
                    self.cancel_all()

                    self.sellOrderID = self.sell(self.longExit, self.fixedSize,
                                                 False)
                    print(u'None sellOrderID###多头平仓,单号:%s' % self.sellOrderID)
                    self.sellOrderID = self.orderIDConvert(self.sellOrderID)
            else:
                if self.longExit != self.exitDown:
                    self.longExit = self.exitDown
                    self.cancel_order(self.sellOrderID)

        elif self.pos < 0:
            if not self.shortExit:
                self.shortExit = self.exitUp
                if self.coverOrderID:
                    self.cancel_order(self.coverOrderID)
                else:
                    self.cancel_all()

                    self.coverOrderID = self.cover(self.shortExit,
                                                   self.fixedSize, False)
                    print(u'None coverOrderID###空头平仓,单号:%s' %
                          self.coverOrderID)
                    self.coverOrderID = self.orderIDConvert(self.coverOrderID)
            else:
                if self.shortExit != self.exitUp:
                    self.shortExit = self.exitUp
                    self.cancel_order(self.coverOrderID)

    #----------------------------------------------------------------------
    def orderIDConvert(self, orderList):
        if not orderList:
            return []
        else:
            return orderList[0]

    #----------------------------------------------------------------------
    def onFiveBar(self, bar, lastTick):
        """收到5分钟K线"""
        # 保存K线数据
        self.am.update_bar(bar)
        if not self.am.inited or not self.trading:
            return

        # 计算指标数值
        print(u'highArray is ↓↓↓↓↓↓↓↓↓↓')
        print(self.am.high[-self.turtleWindow:])
        print(u'lowArray is ↓↓↓↓↓↓↓↓↓↓')
        print(self.am.low[-self.turtleWindow:])
        self.entryUp = max(self.am.high[-self.turtleWindow:])
        self.entryDown = min(self.am.low[-self.turtleWindow:])
        # self.exitUp = min(self.am.low[-self.turtleWindow/2:])
        # self.exitDown = max(self.am.high[-self.turtleWindow/2:])
        # print u'entryup:%s, entryDown:%s' % (self.entryUp, self.entryDown)
        # ma1 = self.am.sma(self.ma1Window, False)
        # ma2 = self.am.sma(self.ma2Window, False)
        # cci = self.am.cci(self.CCIWindow, True)

        # 判断是否进行交易,只发开仓单
        if not self.buyOrderID or self.buyOrderID in self.orderList:
            if self.pos == 0:
                if not self.longEntry:
                    if (self.entryUp - self.entryDown) / self.entryUp < 0.006:
                        print(u'%s 高低点太窄,放弃交易!' % self.vt_symbol)
                        return
                    self.longEntry = self.entryDown

                    self.buyOrderID = self.buy(self.longEntry, self.fixedSize,
                                               False)
                    self.buyOrderID = self.orderIDConvert(self.buyOrderID)
                    self.orderList.append(self.buyOrderID)

                elif self.longEntry != self.entryDown:
                    self.cancel_order(self.buyOrderID)
                    if (self.entryUp - self.entryDown) / self.entryUp < 0.006:
                        print(u'%s 高低点太窄,放弃交易!' % self.vt_symbol)
                        return
                    self.longEntry = self.entryDown

                    self.buyOrderID = self.buy(self.longEntry, self.fixedSize,
                                               False)
                    self.buyOrderID = self.orderIDConvert(self.buyOrderID)
                    self.orderList.append(self.buyOrderID)

        if not self.shortOrderID or self.shortOrderID in self.orderList:
            if self.pos == 0:
                if not self.shortEntry:
                    if (self.entryUp - self.entryDown) / self.entryUp < 0.006:
                        print(u'%s 高低点太窄,放弃交易!' % self.vt_symbol)
                        return
                    self.shortEntry = self.entryUp

                    self.shortOrderID = self.short(self.shortEntry,
                                                   self.fixedSize, False)
                    self.shortOrderID = self.orderIDConvert(self.shortOrderID)
                    self.orderList.append(self.shortOrderID)

                elif self.shortEntry != self.entryUp:
                    self.cancel_order(self.shortOrderID)
                    if (self.entryUp - self.entryDown) / self.entryUp < 0.006:
                        print(u'%s 高低点太窄,放弃交易!' % self.vt_symbol)
                        return
                    self.shortEntry = self.entryUp

                    self.shortOrderID = self.short(self.shortEntry,
                                                   self.fixedSize, False)
                    self.shortOrderID = self.orderIDConvert(self.shortOrderID)
                    self.orderList.append(self.shortOrderID)

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

    #----------------------------------------------------------------------
    def on_order(self, order):
        """收到委托变化推送(必须由用户继承实现)"""
        # print u'委托变化推送:%s' % order.__dict__
        # if self.buyOrderID:
        #     if order.orderID == self.buyOrderID.split('.')[1]:
        #         if order.status == STATUS_CANCELLED:
        #             self.orderList.remove(self.buyOrderID)

        # if self.shortOrderID:
        #     if order.orderID == self.shortOrderID.split('.')[1]:
        #         if order.status == STATUS_CANCELLED:
        #             self.orderList.remove(self.shortOrderID)

        if self.sellOrderID:
            if order.orderID == self.sellOrderID.split('.')[1]:
                if order.status == Status.CANCELLED:
                    self.sellOrderID = self.sell(self.longExit, self.fixedSize,
                                                 False)
                    print(u'###多头平仓,单号:%s' % self.sellOrderID)
                    self.sellOrderID = self.orderIDConvert(self.sellOrderID)
        if self.coverOrderID:
            if order.orderID == self.coverOrderID.split('.')[1]:
                if order.status == Status.CANCELLED:
                    self.coverOrderID = self.cover(self.shortExit,
                                                   self.fixedSize, False)
                    print(u'###空头平仓,单号:%s' % self.coverOrderID)
                    self.coverOrderID = self.orderIDConvert(self.coverOrderID)

        pass

    #----------------------------------------------------------------------
    def on_trade(self, trade):
        """收到成交推送(必须由用户继承实现)"""
        # print u'成交推送:%s' % trade.__dict__
        if self.buyOrderID:
            if trade.tradeID == self.buyOrderID.split('.')[1]:
                self.orderList.remove(self.buyOrderID)

        if self.shortOrderID:
            if trade.tradeID == self.shortOrderID.split('.')[1]:
                self.orderList.remove(self.shortOrderID)

        if trade.offset in [
                Offset.CLOSE, Offset.CLOSETODAY, Offset.CLOSEYESTERDAY
        ]:
            self.buyOrderID = None
            self.shortOrderID = None
            self.longExit = 0
            self.shortExit = 0

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

    #----------------------------------------------------------------------
    def on_stop_order(self, so):
        """停止单推送"""
        # print u'StopOrder回报,stopOrderID:%s, status:%s' % (so.stopOrderID, so.status)
        # if so.status == STOPORDER_CANCELLED or so.status == STOPORDER_TRIGGERED:
        #     self.orderList.remove(so.stopOrderID)
        pass

    #----------------------------------------------------------------------
    def onTimeFunc(self, event):
        now = dt.datetime.now()
        now_hour = now.hour
        now_minute = now.minute

        if self.minute != now_minute:
            self.minute = now_minute
            if not self.timeFuncTurn:
                self.timeFuncTurn = True

        if now_hour == 2 and now_minute == 32 and self.timeFuncTurn:
            self.cta_engine.saveSyncData(self)
            self.timeFuncTurn = False

        elif now_hour == 15 and now_minute == 10 and self.timeFuncTurn:
            self.buyOrderID = None
            self.shortOrderID = None
            self.coverOrderID = None
            self.sellOrderID = None
            self.longExit = 0
            self.shortExit = 0
            self.orderList = []
            self.cta_engine.saveSyncData(self)
            self.timeFuncTurn = False
class Boll_Kc_Dc_Reverse_Strategy(CtaTemplate):
    """
    本策略为反向策略,币本位  Reverse 反向
    """

    author = "yunya"
    open_window = 2
    xsmall_window = 15
    com_length = 250
    boll_kk_dev = 2.0
    kk_atr_length = 30
    sl_multiplier = 0.5
    risk_level = 10000

    trading_size = 0
    xsmall_up_min = 0
    xsmall_down_min = 0
    xsmall_up_max = 0
    xsmall_down_max = 0
    xsmall_ema_mid = 0
    xsmall_com_width = 0
    long_entry = 0
    short_entry = 0
    long_stop = 0
    short_stop = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

    intra_trade_high = 0
    intra_trade_low = 0

    parameters = [
        "open_window",
        "xsmall_window",
        "com_length",
        "boll_kk_dev",
        "kk_atr_length",
        "sl_multiplier",
        "risk_level",
    ]
    variables = [
            "trading_size",
            "xsmall_up_min",
            "xsmall_down_min",
            "xsmall_up_max",
            "xsmall_down_max",
            "xsmall_ema_mid",
            "xsmall_com_width",
            "long_entry",
            "short_entry",
            "long_stop",
            "short_stop",
            "exit_up",
            "exit_down",
            "atr_value",
    ]

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

        self.bg_xsmall = BarGenerator(
            on_bar=self.on_bar,
            window=self.xsmall_window,
            on_window_bar=self.on_xsmall_bar,
            interval=Interval.MINUTE
        )
        self.am_xsmall = ArrayManager(self.com_length + 10)
        self.bg = BarGenerator(self.on_bar, self.open_window, self.on_open_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_xsmall.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)
        self.bg_xsmall.update_bar(bar)
  
    def on_open_bar(self,bar:BarData):
        """
        :param bar:
        :return:
        """
        # 先使用挂单全撤的粗化订单管理
        self.cancel_all()

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

        if self.pos == 0:
            # 根据布林带宽度动态调整仓位大小
            self.trading_size = max(int(self.risk_level / self.xsmall_com_width), 1)
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            # 如果价格突破 xsmall_up_min 线时,在xsmall_up_max 价格挂停止单
            if self.am_xsmall.close[-1] >= self.xsmall_up_min and self.am.close[-1] >=self.xsmall_up_min:
                self.buy(self.xsmall_up_max,self.trading_size,True)

            # 如果价格突破 xsmall_down_min 线时,在xsmall_down_max 价格挂停止单
            elif self.am_xsmall.close[-1] <= self.xsmall_down_min and self.am.close[-1] <= self.xsmall_down_min:
                self.short(self.xsmall_down_max,self.trading_size,True)

        elif self.pos > 0:
            # 成交价固定止损位与中轨中最大值为当前止损位
            # self.exit_up = max(self.xsmall_ema_mid,self.long_stop)

            # 成交价回定止损 与最高价回撤一定比例通道宽度值
            self.intra_trade_high = max(self.intra_trade_high,bar.high_price)
            self.intra_trade_low = bar.low_price

            exit_long_stop = self.intra_trade_high - self.xsmall_com_width * self.sl_multiplier
            self.exit_up = max(exit_long_stop,self.long_stop)
            self.sell(self.exit_up,abs(self.pos),True)

        elif self.pos < 0:
            # 成交价固定止损位与中轨中最小值为当前止损位
            # self.exit_down = min(self.xsmall_ema_mid,self.short_stop)

            # 成交价回定止损 与最高价回撤一定比例通道宽度值
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = min(self.intra_trade_low,bar.low_price)

            exit_short_stop = self.intra_trade_low - self.xsmall_com_width * self.sl_multiplier
            self.exit_down = min(exit_short_stop,self.short_stop)
            self.cover(self.exit_down,abs(self.pos),True)

        self.sync_data()
        self.put_event()

    def on_xsmall_bar(self, bar: BarData):
        """
        :param bar:
        :return:
        """
        # x分钟 多策略合合成的通道线
        self.am_xsmall.update_bar(bar)
        if not self.am_xsmall.inited :
            return

        self.xsmall_ema_mid,self.xsmall_com_width,self.xsmall_up_min, self.xsmall_down_min,\
        self.xsmall_up_max, self.xsmall_down_max = self.boll_kc_dc_combination(
                                                                        high=self.am_xsmall.high[:-1],
                                                                        low=self.am_xsmall.low[:-1],
                                                                        close=self.am_xsmall.close[:-1],
                                                                        boll_kk_dev=self.boll_kk_dev,
                                                                        kk_atr_length=self.kk_atr_length,
                                                                        com_length=self.com_length
                                                                        )

        # print(f"xsmall: mid:{self.xsmall_ema_mid},width:{self.xsmall_com_width},upmin:{self.xsmall_up_min},\
        #         downmin:{self.xsmall_down_min},upmax:{self.xsmall_up_max},downmax:{self.xsmall_down_max}" + "\n")

        self.atr_value = self.am_xsmall.atr(self.kk_atr_length)

        self.sync_data()
        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.
        """
        if trade.direction == Direction.LONG:
            self.long_entry = trade.price  # 成交最高价
            self.long_stop = self.long_entry - 2 * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + 2 * self.atr_value

        self.sync_data()

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

    def boll_kc_dc_combination(self, high, close, low, boll_kk_dev,kk_atr_length,com_length):

        # 计算组合均线
        ema_com = talib.EMA(close, com_length)

        # 计算布林带
        boll_std = talib.STDDEV(close, com_length)
        boll_up = ema_com + boll_kk_dev * boll_std
        boll_down = ema_com - boll_kk_dev * boll_std

        # 计算肯特通道
        kc_atr = talib.ATR(high, low, close, kk_atr_length)
        kc_up = ema_com + kc_atr * boll_kk_dev
        kc_dowm = ema_com - kc_atr * boll_kk_dev

        # 计算唐安奇通道
        dc_up = talib.MAX(high, com_length)
        dc_down = talib.MIN(low, com_length)

        # 计算轨道 因kc通道是直接,最小值大概率是直接,所以去除
        pass_up_min = min(dc_up[-1], boll_up[-1])
        pass_down_min = max(dc_down[-1], boll_down[-1])

        pass_up_max = max(kc_up[-1], dc_up[-1], boll_up[-1])
        pass_down_max = min(kc_dowm[-1], dc_down[-1], boll_down[-1])
        ema_mid = ema_com[-1]

        com_width = abs(pass_up_max - pass_down_max)

        return ema_mid, com_width, pass_up_min, pass_down_min, pass_up_max, pass_down_max
示例#32
0
class MarketStationary(CtaTemplate):
    """"""
    author = ""

    stationary_threshold = 4 / 1000

    market_open_time = time(hour=9, minute=30)
    start_record_time_m = time(hour=9, minute=30)
    start_trade_time_m = time(hour=10, minute=20)
    exit_time_m = time(hour=11, minute=30)
    start_trade_time_a = time(hour=13, minute=33)
    exit_time_a = time(hour=14, minute=55)

    fixed_size = 1
    pct_array_m = []
    pct_array_a = []
    open_price = 0
    draw_back_mean_m = 0
    draw_back_inverse_mean_m = 0
    draw_back_inverse_mean_a = 0
    stationary_value_m = 0
    draw_back_mean_a = 0
    draw_back_inverse_a = 0
    stationary_value_m = 0
    stationary_value_a = 0
    exit_loss = 5 / 1000
    bar_num = 0

    long_order_record_m = []
    short_order_record_m = []
    long_order_record_a = []
    short_order_record_a = []

    trend_bool_m = False
    trend_bool_a = False
    first_time_m = True
    first_time_a = True

    parameters = ['stationary_threshold']
    variables = ['stationary_value_m', 'stationary_value_a', 'trend_bool']

    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.am = ArrayManager(size=300)

        self.long_order_record_m = []
        self.short_order_record_m = []
        self.long_order_record_a = []
        self.short_order_record_a = []
        self.pct_array_m = []
        self.pct_array_a = []

    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.cancel_all()
        self.am.update_bar(bar)

        if not self.am.inited:
            return

        am = self.am

        if bar.datetime.time() == self.market_open_time:
            self.open_price = bar.close_price
        if bar.datetime.time() == self.start_trade_time_m:
            self.bar_num = 0
        elif bar.datetime.time() < self.start_trade_time_a:
            self.bar_num += 1
        elif bar.datetime.time() >= self.exit_time_a:
            self.bar_num = 0

        if self.open_price > 0:

            if bar.datetime.time() == self.start_trade_time_m:

                price_array = am.close[-self.bar_num:]
                draw_back_record = []
                draw_back_inverse_record = []
                for ind in range(self.bar_num):
                    if ind < self.bar_num - 1:

                        self.pct_array_m = (
                            price_array - price_array[ind]) / price_array[ind]
                        print(self.pct_array_m)
                        draw_back = max(self.pct_array_m[ind + 1:])
                        draw_back_inverse = -min(self.pct_array_m[ind + 1:])
                        draw_back_record.append(draw_back)
                        draw_back_inverse_record.append(draw_back_inverse)

                self.draw_back_mean_m = np.mean(draw_back_record)
                self.draw_back_inverse_mean_m = np.mean(
                    draw_back_inverse_record)
                self.stationary_value_m = np.min(
                    [self.draw_back_mean_m, self.draw_back_inverse_mean_m])

                if self.stationary_value_m < self.stationary_threshold:
                    self.trend_bool_m = True

            elif bar.datetime.time() < self.exit_time_m:
                if self.trend_bool_m:
                    if self.pos == 0 and self.first_time_m:
                        if bar.close_price > self.open_price:
                            self.buy(bar.close_price + 5, self.fixed_size)
                            self.long_order_record_m.append(bar.close_price +
                                                            5)
                        elif bar.close_price < self.open_price:
                            self.short(bar.close_price - 5, self.fixed_size)
                            self.short_order_record_m.append(bar.close_price -
                                                             5)

                    elif self.pos > 0:
                        self.first_time_m = False
                        buy_order_price = self.long_order_record_m[-1]
                        if bar.close_price <= buy_order_price * (
                                1 - self.exit_loss):
                            self.sell(bar.close_price * 0.99, abs(self.pos))

                    elif self.pos < 0:
                        self.first_time_m = False
                        sell_order_price = self.short_order_record_m[-1]
                        if bar.close_price >= sell_order_price * (
                                1 + self.exit_loss):
                            self.cover(bar.close_price * 1.01, abs(self.pos))

            elif self.exit_time_m <= bar.datetime.time(
            ) < self.start_trade_time_a:
                if self.pos > 0:
                    self.sell(bar.close_price * 0.99, abs(self.pos))
                elif self.pos < 0:
                    self.cover(bar.close_price * 1.01, abs(self.pos))
                self.trend_bool_m = False
                self.first_time_m = True
            elif bar.datetime.time() == self.start_trade_time_a:
                price_array = am.close[-self.bar_num:]
                draw_back_record = []
                draw_back_inverse_record = []
                for ind in range(self.bar_num):
                    if ind < self.bar_num - 1:
                        self.pct_array_a = (
                            price_array - price_array[ind]) / price_array[ind]
                        draw_back = max(self.pct_array_a[ind + 1:])
                        draw_back_inverse = -min(self.pct_array_a[ind + 1:])
                        draw_back_record.append(draw_back)
                        draw_back_inverse_record.append(draw_back_inverse)

                self.draw_back_mean_a = np.mean(draw_back_record)
                self.draw_back_inverse_mean_a = np.mean(
                    draw_back_inverse_record)
                self.stationary_value_a = np.min(
                    [self.draw_back_mean_a, self.draw_back_inverse_mean_a])
                if self.stationary_value_a < self.stationary_threshold:
                    self.trend_bool_a = True
            elif self.start_trade_time_a <= bar.datetime.time(
            ) < self.exit_time_a:
                if self.trend_bool_a:
                    if self.pos == 0 and self.first_time_a:
                        if bar.close_price > self.open_price:
                            self.buy(bar.close_price + 5, self.fixed_size)
                            self.long_order_record_a.append(bar.close_price +
                                                            5)
                        elif bar.close_price < self.open_price:
                            self.short(bar.close_price - 5, self.fixed_size)
                            self.short_order_record_a.append(bar.close_price -
                                                             5)

                    elif self.pos > 0:
                        self.first_time_a = False
                        buy_order_price = self.long_order_record_a[-1]
                        if bar.close_price <= buy_order_price * (
                                1 - self.exit_loss):
                            self.sell(bar.close_price * 0.99, abs(self.pos))

                    elif self.pos < 0:
                        self.first_time_a = False
                        sell_order_price = self.short_order_record_a[-1]
                        if bar.close_price >= sell_order_price * (
                                1 + self.exit_loss):
                            self.cover(bar.close_price * 1.01, abs(self.pos))
            elif bar.datetime.time() >= self.exit_time_a:
                if self.pos > 0:
                    self.sell(bar.close_price * 0.99, abs(self.pos))
                elif self.pos < 0:
                    self.cover(bar.close_price * 1.01, abs(self.pos))
                self.trend_bool_a = False
                self.first_time_a = True
                self.open_price = 0
        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.
        """
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
示例#33
0
class TurtleSignalStrategy(CtaTemplate):
    """"""
    author = "用Python的交易员"

    # 唐奇安上下轨突破的周期,买入位置
    entry_window = 20
    # 唐奇安通道,卖出位置
    exit_window = 10
    atr_window = 20
    # 乘数,每次下单的单位大小
    fixed_size = 1

    entry_up = 0
    entry_down = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

    # 多头入场价,每次交易后,设置为当前交易价格
    long_entry = 0
    short_entry = 0
    # 多头止损价格
    long_stop = 0
    short_stop = 0

    parameters = ["entry_window", "exit_window", "atr_window", "fixed_size"]
    variables = ["entry_up", "entry_down", "exit_up", "exit_down", "atr_value"]

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

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

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

    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_all()

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

        # Only calculates new entry channel when no position holding
        # 没有持仓时才计算入场价
        if not self.pos:
            self.entry_up, self.entry_down = self.am.donchian(
                self.entry_window)

        self.exit_up, self.exit_down = self.am.donchian(self.exit_window)

        if not self.pos:
            self.atr_value = self.am.atr(self.atr_window)

            self.long_entry = 0
            self.short_entry = 0
            self.long_stop = 0
            self.short_stop = 0

            # 下本地止损单,等到突破或者跌破成交
            self.send_buy_orders(self.entry_up)
            self.send_short_orders(self.entry_down)
        elif self.pos > 0:
            # 如果之前有多头突破单成交,下单,根据atr加仓.
            # 不用考虑历史仓位,默认前面都是按照规则正确下单成交的仓位,不考虑未成交情况
            self.send_buy_orders(self.entry_up)

            # 止损价和止盈退出价中的大的一方
            sell_price = max(self.long_stop, self.exit_down)
            # 下多头止盈单
            self.sell(sell_price, abs(self.pos), True)

        elif self.pos < 0:
            # 如果之前有空仓,加仓
            self.send_short_orders(self.entry_down)

            cover_price = min(self.short_stop, self.exit_up)
            # 下空头止盈单
            self.cover(cover_price, abs(self.pos), True)

        self.put_event()

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        print(
            f"海龟交易,{trade.tradeid}, {trade.price}, {trade.direction}, {trade.time}"
        )
        if trade.direction == Direction.LONG:
            self.long_entry = trade.price
            # 修改多头止损价格
            self.long_stop = self.long_entry - 2 * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + 2 * self.atr_value

    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

    def send_buy_orders(self, price):
        """"""
        t = self.pos / self.fixed_size

        if t < 1:
            self.buy(price, self.fixed_size, True)

        if t < 2:
            self.buy(price + self.atr_value * 0.5, self.fixed_size, True)

        if t < 3:
            self.buy(price + self.atr_value, self.fixed_size, True)

        if t < 4:
            self.buy(price + self.atr_value * 1.5, self.fixed_size, True)

    def send_short_orders(self, price):
        """"""
        t = self.pos / self.fixed_size

        if t > -1:
            self.short(price, self.fixed_size, True)

        if t > -2:
            self.short(price - self.atr_value * 0.5, self.fixed_size, True)

        if t > -3:
            self.short(price - self.atr_value, self.fixed_size, True)

        if t > -4:
            self.short(price - self.atr_value * 1.5, self.fixed_size, True)