Exemplo n.º 1
0
class DudlThrustEmaPositionStrategy(CtaTemplate):
    """"""
    author = "yunyu"

    open_window = 5
    xminute_window = 30
    rolling_period = 70
    upper_open = 0.45
    lower_open = 0.45
    cci_length = 5
    ema_length = 60
    position_atr_length = 6
    risk_level = 1000
    # fixed_size = 1

    trading_size = 0
    atr_value = 0
    up = 0
    down = 0
    current_ema = 0
    last_ema = 0
    ema_mid = 0
    ema_new_value = 0
    ema_length_new = 0
    cci_value = 0
    exit_long_nex = 0
    exit_long_last = 0
    exit_short_nex = 0
    exit_short_last = 0
    current_close = 0
    last_close = 0
    front_close = 0
    exit_long = 0
    exit_short = 0

    ask = 0
    bid = 0

    parameters = [
        "open_window", "xminute_window", "rolling_period", "upper_open",
        "lower_open", "cci_length", "ema_length", "position_atr_length",
        "risk_level"
    ]

    variables = [
        "trading_size",
        "up",
        "down",
        "current_ema",
        "last_ema",
        "ema_mid",
        "ema_new_value",
        "ema_length_new",
        "cci_value",
        "exit_long_nex",
        "exit_long_last",
        "exit_short_nex",
        "exit_short_last",
        "current_close",
        "last_close",
        "front_close",
        "exit_long",
        "exit_short",
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)
        self.bg_open = BarGenerator(on_bar=self.on_bar,
                                    window=self.open_window,
                                    on_window_bar=self.on_open_bar)
        self.am_open = ArrayManager()

        self.bg = NewBarGenerator(on_bar=self.on_bar,
                                  window=self.xminute_window,
                                  on_window_bar=self.on_xmin_bar)
        self.am = ArrayManager(self.rolling_period + 50)

    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)
        self.ask = tick.ask_price_1  # 卖一价
        self.bid = tick.bid_price_1  # 买一价

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

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

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

        if self.pos == 0:
            self.cci_value = self.am.cci(self.cci_length)

            # 判断数据是否正常,如果atr 计算结果正常,才计算仓位,避免下单时下出不正常的数量
            self.atr_value = self.am.atr(self.position_atr_length)

            if self.atr_value == 0:
                return

            self.trading_size = max(int(self.risk_level / self.atr_value), 1)

            if self.cci_value > 0:
                self.buy(self.up, self.trading_size, True)

            elif self.cci_value < 0:
                self.short(self.down, self.trading_size, True)

        elif self.pos > 0:
            con1 = bar.close_price < self.current_ema
            con2 = bar.close_price >= self.last_ema
            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.ema_length_new = self.ema_length

                    self.exit_long = self.ema_mid

                else:
                    if bar.close_price > (
                        (self.ema_mid + self.current_ema) / 2):
                        self.exit_long = bar.close_price

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

                    else:
                        self.exit_long = self.ema_mid
            else:
                self.exit_long = self.ema_mid

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

        elif self.pos < 0:
            con1 = bar.close_price > self.current_ema
            con2 = bar.close_price <= self.last_ema
            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.ema_length_new = self.ema_length

                    self.exit_short = self.ema_mid

                else:
                    if bar.close_price < (self.ema_mid + self.current_ema / 2):
                        self.exit_short = bar.close_price

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

                    else:
                        self.exit_short = self.ema_mid
            else:
                self.exit_short = self.ema_mid

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

        self.put_event()
        self.sync_data()

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

        if not self.am.inited:
            return

        #  计算海龟 上轨,下轨
        high_max = self.am.high[-self.rolling_period:].max()
        close_min = self.am.close[-self.rolling_period:].min()
        close_max = self.am.close[-self.rolling_period:].max()
        low_min = self.am.low[-self.rolling_period:].min()

        hc = high_max - close_min
        cl = close_max - low_min
        dual = max(hc, cl)

        self.up = self.am.open[-2] + dual * self.upper_open
        self.down = self.am.open[-2] - dual * self.upper_open

        # print(f"up:{self.up},{self.down}")
        self.current_close = self.am.close[-1]
        self.last_close = self.am.close[-2]
        self.front_close = self.am.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.ema_length_new = self.ema_length

        elif self.pos > 0:
            close_long = self.current_close > self.last_close > self.front_close
            if close_long:
                self.ema_length_new -= 1
                self.ema_length_new = max(self.ema_length_new, 5)

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

        self.ema_mid = self.am.ema(self.ema_length)
        ema_mid_new = self.am.ema(self.ema_length_new, True)

        self.current_ema = ema_mid_new[-1]
        self.last_ema = ema_mid_new[-2]

    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.
        """
        pass

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

    def market_order(self):
        """"""
        pass
        # self.buy(self.last_tick.limit_up, 1)
        # self.write_log("执行市价单测试")

    def limit_order(self):
        """"""
        pass
        # self.buy(self.last_tick.limit_down, 1)
        # self.write_log("执行限价单测试")

    def stop_order(self):
        """"""
        pass
Exemplo n.º 2
0
class MacdBollDcStrategy(CtaTemplate):
    """"""

    author = "云崖"

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

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

    intra_trade_high = 0
    intra_trade_low = 0

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

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

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

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

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

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

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

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

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

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

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

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

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

            return

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

            self.long_stop = 0
            self.short_stop = 0

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

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

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

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

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

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

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

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

        self.put_event()

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

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

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

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

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

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

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

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        self.put_event()
Exemplo n.º 3
0
class RsiAdaptStrategy(CtaTemplate):
    """
	策略逻辑:
	一、、过虑信号  (小时周期)
	使用rsiboll来判断信号强弱

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

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

	"""
    author = "yunya"

    min_window = 45
    open_window = 15
    rsi_length = 23
    kk_length = 80
    kk_dev = 2.0
    trading_size = 1
    atr_length = 30

    rsi_entry = 0
    kk_up = 0
    kk_down = 0
    long_stop = 0
    short_stop = 0
    rsi_value = 0
    rsi_up = 0
    rsi_dow = 0
    ema_mid = 0
    ema_length_new = 0
    current_ema_mid = 0
    last_ema_mid = 0
    current_close = 0
    last_close = 0
    front_close = 0
    exit_long = 0
    exit_short = 0
    long_entry = 0
    short_entry = 0
    long_stop_trade = 0
    short_stop_drade = 0
    exit_long_nex = 0
    exit_long_last = 0
    exit_short_nex = 0
    exit_short_last = 0
    atr_value = 0

    parameters = [
        "open_window",
        "min_window",
        "rsi_length",
        "kk_length",
        "kk_dev",
        "trading_size",
        "atr_length",
    ]

    variables = [
        "rsi_entry",
        "long_stop",
        "short_stop",
        "rsi_value",
        "rsi_up",
        "rsi_dow",
        "ema_mid",
        "ema_length_new",
        "current_ema_mid",
        "last_ema_mid",
        "current_close",
        "last_close",
        "front_close",
        "exit_long",
        "exit_short",
        "long_entry",
        "short_entry",
        "long_stop_trade",
        "short_stop_drade",
        "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.bg_xminute = NewBarGenerator(on_bar=self.on_bar,
                                          window=self.min_window,
                                          on_window_bar=self.on_xminute_bar)
        self.am_xminute = ArrayManager(self.kk_length * 2 + 10)

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

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

        ema_mid_array = self.am_open.ema(self.kk_length, True)
        atr = self.am_open.atr(self.kk_length, True)
        kk_up_array = ema_mid_array + atr * self.kk_dev
        kk_down_array = ema_mid_array - atr * self.kk_dev

        self.ema_mid = ema_mid_array[-1]
        self.kk_up = kk_up_array[-1]
        self.kk_down = kk_down_array[-1]

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

        if not self.pos:
            self.exit_long_nex = 0
            self.exit_long_last = 0
            self.exit_short_nex = 0
            self.exit_short_last = 0
            self.ema_length_new = self.kk_length

            self.atr_value = self.am_open.atr(self.atr_length)

            if self.rsi_entry > 0:
                self.buy(self.kk_up, self.trading_size, True)
                self.write_log(
                    f"下多单:{bar.datetime}, {self.kk_up}, {self.trading_size}")

            elif self.rsi_entry < 0:
                self.short(self.kk_down, self.trading_size, True)
                self.write_log(
                    f"下多单:{bar.datetime}, {self.kk_down}, {self.trading_size}")

        elif self.pos > 0:
            close_long = self.current_close > self.last_close > self.front_close
            if close_long:
                self.ema_length_new -= 1
                self.ema_length_new = max(self.ema_length_new, 5)

            ema_mid_new = self.am_xminute.sma(self.ema_length_new, True)
            self.current_ema_mid = ema_mid_new[-1]
            self.last_ema_mid = ema_mid_new[-2]
            # 仓位是long 时,如果价格下穿新布林中轨
            con1 = bar.close_price < self.current_ema_mid
            con2 = bar.close_price >= self.last_ema_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.ema_length_new = self.kk_length

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

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

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

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

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

            ema_mid_new = self.am_xminute.sma(self.ema_length_new, True)
            self.current_ema_mid = ema_mid_new[-1]
            self.last_ema_mid = ema_mid_new[-2]

            # 仓位是short 时,如果价格上穿新布林中轨
            con1 = bar.close_price > self.current_ema_mid
            con2 = bar.close_price <= self.last_ema_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.ema_length_new = self.kk_length

                    self.exit_short = self.ema_mid

                else:
                    if bar.close_price < (self.ema_mid +
                                          self.current_ema_mid / 2):
                        self.exit_short = bar.close_price

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

                    else:
                        self.exit_short = self.ema_mid
            else:
                self.exit_short = self.ema_mid

            self.short_stop = min(self.exit_short, self.short_stop_drade)
            self.cover(self.short_stop, 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

        ema_array = talib.EMA(self.am_xminute.close, self.rsi_length)
        std_array = talib.EMA(self.am_xminute.close, self.rsi_length)

        dev_array = abs(self.am_xminute.close[:-1] -
                        ema_array[:-1]) / std_array[:-1]
        dev_max = max(dev_array[-self.rsi_length:])

        rsi_array = talib.RSI(self.am_xminute.close[:-1], self.rsi_length)
        rsi_up_array = rsi_array + rsi_array * dev_max
        rsi_dow_array = rsi_array - rsi_array * dev_max

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

        self.rsi_value = rsi_value_array[-1]
        current_rsi = rsi_value_array[-1]
        last_rsi = rsi_value_array[-2]
        current_rsi_up = rsi_up_array[-1]
        last_rsi_up = rsi_up_array[-2]
        current_rsi_down = rsi_dow_array[-1]
        last_rsi_down = rsi_dow_array[-2]

        con1 = current_rsi > current_rsi_up
        con2 = last_rsi <= last_rsi_up
        con3 = current_rsi < current_rsi_down
        con4 = last_rsi >= last_rsi_down

        if con1 > con2:
            self.rsi_entry = 1
        elif con3 and con4:
            self.rsi_entry = -1

        self.sync_data()

    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_trade = self.long_entry - 2 * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop_drade = self.short_entry + 2 * self.atr_value

        self.sync_data()

    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()
Exemplo n.º 4
0
class EmaStrategy(CtaTemplate):
    author = "CHENG LI"

    trade_money = 1000000
    fixed_size = 1
    bars = []
    # exit_time = time(hour=14, minute=55)

    # for EMA algorithm
    fast_window = 12
    slow_window = 48
    fast_ema0 = 0.0
    fast_ema1 = 0.0
    slow_ema0 = 0.0
    slow_ema1 = 0.0

    # 菲阿里四价:昨日高点、昨日低点、昨天收盘、今天开盘
    yesterday_high = 0.0
    yesterday_low = 0.0
    yesterday_close = 0.0
    today_open = 0.0

    short_stop_loss = 0.0
    long_stop_loss = 0.0

    parameters = ["fast_window", "slow_window", "trade_money"]
    variables = [
        "fast_ema0", "fast_ema1", "slow_ema0", "slow_ema1", "yesterday_high",
        "yesterday_low", "yesterday_close", "today_open", "short_stop_loss",
        "long_stop_loss"
    ]

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

        self.bg_hour = BarGenerator(self.on_bar,
                                    window=1,
                                    on_window_bar=self.on_hour_bar,
                                    interval=Interval.HOUR)
        self.bg_day = BarGenerator(self.on_bar,
                                   window=24,
                                   on_window_bar=self.on_day_bar,
                                   interval=Interval.HOUR)

        self.am_hour = ArrayManager(100)
        self.am_day = ArrayManager(2)

        self.bars = []

    def on_init(self):
        print("on init")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        print("on_start strategy")

    def on_tick(self, tick: TickData):

        self.bg_hour.update_tick(tick)
        self.bg_day.update_tick(tick)

    def on_bar(self, bar: BarData):

        self.bg_hour.update_bar(bar)
        self.bg_day.update_bar(bar)

    def on_day_bar(self, bar: BarData):
        """
        菲阿里四价算法实现
        """
        # bar 初始化
        self.cancel_all()
        am = self.am_day
        am.update_bar(bar)
        if not am.inited:
            self.bars.append(bar)
            return

        self.bars.append(bar)
        if len(self.bars) <= 2:
            return
        else:
            self.bars.pop(0)
        last_bar = self.bars[-2]

        # compute 4 different prices from data
        self.yesterday_high = last_bar.high_price
        self.yesterday_low = last_bar.low_price
        self.yesterday_close = last_bar.close_price
        self.today_open = bar.open_price

        # 设置多头止损
        if self.today_open / self.yesterday_high > 1.005:  # 如果当天开盘价大于昨天最高价
            self.long_stop_loss = self.yesterday_high
        elif self.today_open / self.yesterday_high < 0.995:  # 如果当天开盘价小于昨天最高价
            self.long_stop_loss = self.today_open
        else:  # 如果当天开盘价接近于昨天最高价
            self.long_stop_loss = (self.yesterday_high +
                                   self.yesterday_low) / 2  # 设置多头止损为昨天中间价

        # 设置空头止损
        if self.today_open / self.yesterday_low < 0.995:  # 如果当天开盘价小于昨天最低价
            self.short_stop_loss = self.yesterday_low
        elif self.today_open / self.yesterday_low > 1.005:  # 如果当天开盘价大于昨天最低价
            self.short_stop_loss = self.today_open
        else:  # 如果当天开盘价接近于昨天最低价
            self.short_stop_loss = (self.yesterday_high +
                                    self.yesterday_low) / 2

        self.put_event()

    def on_hour_bar(self, bar: BarData):

        # 确保day bar初始化
        self.am_hour.update_bar(bar)
        if not self.am_hour.inited:
            return
        self.am_day.update_bar(bar)
        if not self.am_day.inited:
            return

        # compute exp. moving average
        fast_ema = self.am_hour.ema(self.fast_window, array=True)
        self.fast_ema0 = fast_ema[-1]  # at T
        self.fast_ema1 = fast_ema[-2]  # at T-1

        slow_ema = self.am_hour.ema(self.slow_window, array=True)
        self.slow_ema0 = slow_ema[-1]
        self.slow_ema1 = slow_ema[-2]

        # identify trend: 1:bullish, -1:bearish, 0:sideways
        if self.fast_ema0 > self.slow_ema0 and self.fast_ema1 < self.slow_ema1:
            trend_status = 1
        elif self.fast_ema0 < self.slow_ema0 and self.fast_ema1 > self.slow_ema1:
            trend_status = -1
        else:
            trend_status = 0

        self.fixed_size = 0.1 * self.trade_money / bar.close_price
        # if bar.datetime.time() < self.exit_time:
        if self.pos == 0:  # 没有仓位
            if trend_status == 1:
                if bar.close_price > self.yesterday_high:
                    self.buy(bar.close_price * 1.005, self.fixed_size)  # 做多
            elif trend_status == -1:
                if bar.close_price < self.yesterday_low:
                    self.short(bar.close_price * 0.995, self.fixed_size)  # 做空

        elif self.pos > 0:  # 有多头仓位
            if bar.close_price < self.long_stop_loss:  # 如果当前价格小于多头止损线
                if trend_status == -1:
                    self.sell(bar.close_price * 0.995,
                              abs(self.pos))  # 先平多头仓位,再反手开空
                    self.short(bar.close_price * 0.995, self.fixed_size)  # 做空
                else:
                    self.sell(bar.close_price * 0.995, abs(self.pos))  # 止
            else:
                # 继续做多
                if trend_status == 1:
                    if bar.close_price > self.yesterday_high:
                        self.buy(bar.close_price * 1.005,
                                 self.fixed_size)  # 做多

        elif self.pos < 0:  # 有空头的仓位
            if bar.close_price > self.short_stop_loss:  # 如果当前价格大于空头止损线
                if trend_status == 1:
                    self.cover(bar.close_price * 1.005,
                               abs(self.pos))  # 先平空头仓位, 然后反手开多
                    self.buy(bar.close_price * 1.005,
                             self.fixed_size)  # 做多按照开仓的资金来计算
                else:
                    self.cover(bar.close_price * 1.005, abs(self.pos))
            else:
                # 继续做空
                if trend_status == -1:
                    if bar.close_price < self.yesterday_low:
                        self.short(bar.close_price * 0.995, self.fixed_size)

        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
Exemplo n.º 5
0
class DeviationStrategy(CtaTemplate):
    """"""
    author = "yunya"

    exchange = "BYBIT"
    xminute_window = 15
    short_length = 30
    medium_length = 60
    long_length = 120
    entry_window = 28
    exit_window = 7
    atr_window = 4
    trading_size = 1
    # risk_level = 0.2

    ema_initde = 0
    # 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 = [
        "ema_initde", "entry_up", "entry_down", "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 = BarGenerator(self.on_bar,
                               self.xminute_window,
                               self.on_xminute_bar,
                               interval=Interval.MINUTE)
        self.am = ArrayManager(self.long_length + 100)

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar_exchange(days=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_xminute_bar(self, bar: BarData):
        """"""
        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)

        short_ema = self.am.ema(self.short_length, True)
        mdeium_ema = self.am.ema(self.medium_length, True)
        long_ema = self.am.ema(self.long_length, True)

        short_mdeium_array = short_ema - mdeium_ema
        mdeium__long_array = mdeium_ema - long_ema

        current_short_mdeium = short_mdeium_array[-1]
        last_short_mdeium = short_mdeium_array[-2]

        current_mdeium_long = mdeium__long_array[-1]
        last_mdeium_long = mdeium__long_array[-2]

        con1 = current_short_mdeium > current_mdeium_long
        con2 = last_short_mdeium <= last_mdeium_long
        con3 = current_short_mdeium < current_mdeium_long
        con4 = last_short_mdeium >= last_mdeium_long

        if con1 and con2:
            self.ema_initde = 1

        elif con3 and con4:
            self.ema_initde = -1

        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

            if self.ema_initde > 0:
                self.buy(self.entry_up, self.trading_size, True)

            elif self.ema_initde < 0:
                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

    def load_bar_exchange(self, days: int):
        """"
        判断是属于那个交易所,使用不同的初始化方式
        """
        if self.exchange == Exchange.HUOBI:
            self.load_bar(days=days, use_database=True)
            self.write_log(f"{self.exchange}交易所,从本地获取{days}数据初始化!")

        elif self.exchange == Exchange.OKEX:
            self.load_bar(days=days, use_database=True)
            self.write_log(f"{self.exchange}交易所,从本地获取{days}数据初始化!")
        else:
            self.load_bar(days=days)
            self.write_log(f"{self.exchange}交易所,从交易获取{days}数据初始化!")