def calculate_adaptive_channel(am: ArrayManager, n: int, dev: float):
    """"""
    ma = am.sma(n)
    std = am.std(n)
    
    boll_up = ma + std * dev
    boll_down =  ma - std * dev

    kk_up = ma + atr * dev 
    kk_down =  ma - atr * dev

    donchian_up = am.high[-n:].max()
    donchian_down = am.low[-n:].min()

    channel_up =  max(boll_up, kk_up, donchian_up)
    channel_down = min(boll_down, kk_down, donchian_down)

    return channel_up, channel_down
Example #2
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("c", self.fast_window)
        slow_ma = self.am.sma("c", 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)
class StatisticalArbitrageStrategy(SpreadStrategyTemplate):
    """"""

    author = "用Python的交易员"

    boll_window = 20
    boll_dev = 2
    max_pos = 10
    payup = 10
    interval = 5

    spread_pos = 0.0
    boll_up = 0.0
    boll_down = 0.0
    boll_mid = 0.0

    parameters = ["boll_window", "boll_dev", "max_pos", "payup", "interval"]
    variables = ["spread_pos", "boll_up", "boll_down", "boll_mid"]

    def __init__(self, strategy_engine, strategy_name: str, spread: SpreadData,
                 setting: dict):
        """"""
        super().__init__(strategy_engine, strategy_name, spread, setting)

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

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

        self.load_bar(1)

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

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

        self.put_event()

    def on_spread_data(self):
        """
        Callback when spread price is updated.
        """
        tick = self.get_spread_tick()
        self.on_spread_tick(tick)

    def on_spread_tick(self, tick: TickData):
        """
        Callback when new spread tick data is generated.
        """
        self.bg.update_tick(tick)

    def on_spread_bar(self, bar: BarData):
        """
        Callback when spread bar data is generated.
        """
        self.stop_all_algos()

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

        self.boll_mid = self.am.sma(self.boll_window)
        self.boll_up, self.boll_down = self.am.boll(self.boll_window,
                                                    self.boll_dev)

        if not self.spread_pos:
            if bar.close_price >= self.boll_up:
                self.start_short_algo(bar.close_price - 10,
                                      self.max_pos,
                                      payup=self.payup,
                                      interval=self.interval)
            elif bar.close_price <= self.boll_down:
                self.start_long_algo(bar.close_price + 10,
                                     self.max_pos,
                                     payup=self.payup,
                                     interval=self.interval)
        elif self.spread_pos < 0:
            if bar.close_price <= self.boll_mid:
                self.start_long_algo(bar.close_price + 10,
                                     abs(self.spread_pos),
                                     payup=self.payup,
                                     interval=self.interval)
        else:
            if bar.close_price >= self.boll_mid:
                self.start_short_algo(bar.close_price - 10,
                                      abs(self.spread_pos),
                                      payup=self.payup,
                                      interval=self.interval)

        self.put_event()

    def on_spread_pos(self):
        """
        Callback when spread position is updated.
        """
        self.spread_pos = self.get_spread_pos()
        self.put_event()

    def on_spread_algo(self, algo: SpreadAlgoTemplate):
        """
        Callback when algo status is updated.
        """
        pass

    def on_order(self, order: OrderData):
        """
        Callback when order status is updated.
        """
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback when new trade data is received.
        """
        pass

    def stop_open_algos(self):
        """"""
        if self.buy_algoid:
            self.stop_algo(self.buy_algoid)

        if self.short_algoid:
            self.stop_algo(self.short_algoid)

    def stop_close_algos(self):
        """"""
        if self.sell_algoid:
            self.stop_algo(self.sell_algoid)

        if self.cover_algoid:
            self.stop_algo(self.cover_algoid)
Example #4
0
class StatisticalArbitrageGridStrategy(SpreadStrategyTemplate):
    """
    算法逻辑是在统计算法基础上增加加仓位逻辑
    """

    author = "yunya"

    boll_window = 60
    boll_dev = 4.0
    fixed_pos = 10
    max_pos = 4
    price_proportion = 2.0
    pay_up = 5
    increase_price = 0.0  # 超价
    interval = 5

    spread_pos = 0
    boll_up = 0
    boll_down = 0
    boll_mid = 0
    grid_count = 0
    buy_grid_count = 0
    short_grid_count = 0
    long_price = 0
    short_price = 0

    parameters = [
        "boll_window", "boll_dev", "fixed_pos", "max_pos", "price_proportion",
        "pay_up", "interval", "increase_price"
    ]
    variables = [
        "spread_pos",
        "boll_up",
        "boll_down",
        "boll_mid",
        "grid_count",
        "buy_grid_count",
        "short_grid_count",
        "long_price",
        "short_price",
    ]

    def __init__(self, strategy_engine, strategy_name: str, spread: SpreadData,
                 setting: dict):
        """"""
        super().__init__(strategy_engine, strategy_name, spread, setting)

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

    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("策略启动")

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

    def on_spread_data(self):
        """
        Callback when spread price is updated.
        收到差价推送后,合成价差TICK数据
        """
        #这里的价差tick
        tick = self.get_spread_tick()
        self.on_spread_tick(tick)

    def on_spread_tick(self, tick: TickData):
        """
        Callback when new spread tick data is generated.
        """
        self.bg.update_tick(tick)

    def on_spread_bar(self, bar: BarData):
        """
        Callback when spread bar data is generated.
        """
        # 把老算法先停止,
        self.stop_all_algos()

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

        self.boll_mid = self.am.sma(self.boll_window)
        self.boll_up, self.boll_down = self.am.boll(self.boll_window,
                                                    self.boll_dev)

        if not self.spread_pos:
            if bar.close_price >= self.boll_up:
                self.start_short_algo(bar.close_price - self.increase_price,
                                      self.fixed_pos,
                                      payup=self.pay_up,
                                      interval=self.interval)
            elif bar.close_price <= self.boll_down:
                self.start_long_algo(bar.close_price + self.increase_price,
                                     self.fixed_pos,
                                     payup=self.pay_up,
                                     interval=self.interval)
        elif self.spread_pos < 0:
            if bar.close_price <= self.boll_mid:
                self.start_long_algo(bar.close_price + self.increase_price,
                                     abs(self.spread_pos),
                                     payup=self.pay_up,
                                     interval=self.interval)
                self.buy_grid_count = 0
            else:
                # 加仓
                grid_count = self.buy_grid_count < self.max_pos
                bar_change = bar.close_price > self.long_price * (
                    1 + self.price_proportion / 1000)

                if grid_count and bar_change:
                    if bar.close_price >= self.boll_up:
                        self.start_short_algo(bar.close_price -
                                              self.increase_price,
                                              self.fixed_pos,
                                              payup=self.pay_up,
                                              interval=self.interval)
        else:
            if bar.close_price >= self.boll_mid:
                self.start_short_algo(bar.close_price - self.increase_price,
                                      abs(self.spread_pos),
                                      payup=self.pay_up,
                                      interval=self.interval)
                self.short_grid_count = 0
            else:
                # 加仓
                grid_count = self.short_grid_count < self.max_pos
                bar_change = bar.close_price < self.short_price * (
                    1 - self.price_proportion / 1000)
                if grid_count and bar_change:
                    if bar.close_price <= self.boll_down:
                        self.start_long_algo(bar.close_price +
                                             self.increase_price,
                                             self.fixed_pos,
                                             payup=self.pay_up,
                                             interval=self.interval)

    def on_spread_pos(self):
        """
        Callback when spread position is updated.
        """
        self.spread_pos = self.get_spread_pos()
        self.put_event()

    def on_spread_algo(self, algo: SpreadAlgoTemplate):
        """
        Callback when algo status is updated.
        """
        pass

    def on_order(self, order: OrderData):
        """
        Callback when order status is updated.
        """
        if order.status == Status.ALLTRADED:
            if order.direction == Direction.LONG:
                self.buy_grid_count += 1
            else:
                self.short_grid_count += 1

    def on_trade(self, trade: TradeData):
        """
        Callback when new trade data is received.
        """
        if trade.direction == Direction.LONG:
            self.long_price = trade.price
        else:
            self.short_price = trade.price
Example #5
0
class StatisticalArbitrageStrategy(SpreadStrategyTemplate):
    """"""

    author = "用Python的交易员"

    open_window = 1
    boll_window = 40
    boll_dev = 4.9
    fixed_pos = 10
    payup = 10.0
    increase_price = 0.0  # 超价
    interval = 5

    spread_pos = 0.0
    boll_up = 0.0
    boll_down = 0.0
    boll_mid = 0.0

    parameters = [
        "boll_window", "boll_dev", "fixed_pos", "payup", "interval",
        "increase_price"
    ]
    variables = ["spread_pos", "boll_up", "boll_down", "boll_mid"]

    def __init__(self, strategy_engine, strategy_name: str, spread: SpreadData,
                 setting: dict):
        """"""
        super().__init__(strategy_engine, strategy_name, spread, setting)

        self.bg = BarGenerator(self.on_open_spread_bar, self.open_window,
                               self.on_open_spread_bar)
        self.am = ArrayManager()

        self.spread_pos = 0.0
        self.boll_up = 0.0
        self.boll_down = 0.0
        self.boll_mid = 0.0

    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("策略停止")

        self.put_event()

    def on_spread_data(self):
        """
        Callback when spread price is updated.
        收到差价推送后,合成价差TICK数据
        """
        #这里的价差tick
        tick = self.get_spread_tick()
        self.on_spread_tick(tick)

    def on_spread_tick(self, tick: TickData):
        """
        Callback when new spread tick data is generated.
        """
        self.bg.update_tick(tick)

    def on_spread_bar(self, bar: BarData):
        """
        Callback when new spread bar data is generated.
        """
        self.bg.update_bar(bar)

    def on_open_spread_bar(self, bar: BarData):
        """
        Callback when spread bar data is generated.

        目前的策略逻辑:
        1、当价差价格大于布林上轨,以当前收盘加低10的价格下单(以市价下单保证成交),当价格跌破中轨时平仓 (做空)
        2、当价差价格小于布林下轨,以当前收盘价加10的价格下单,当价格高于中轨时平仓 (做多)

        策略优化方向:
        1、把目前在分钟价差K线逻辑移到 tick逻辑中实盘,增加细腻度
        2、仓位分为四次加减仓,第一次上穿时,开一份,第二次上穿的价格要高于第一次一定比较时,开第二份,一直到满四份。
        (这两个参数,一个是份数,一个是跨度(格距)),目的解决如果出现单边短时趋势抗单时爆仓(最后都会回归中轨)
        3、回到中轨全部平仓位

        """
        # 把老算法先停止,
        self.stop_all_algos()

        self.am.update_bar(bar)

        if not self.am.inited:
            return

        self.boll_mid = self.am.sma(self.boll_window)
        self.boll_up, self.boll_down = self.am.boll(self.boll_window,
                                                    self.boll_dev)

        if not self.spread_pos:
            if bar.close_price >= self.boll_up:
                self.start_short_algo(bar.close_price - self.increase_price,
                                      self.fixed_pos,
                                      payup=self.payup,
                                      interval=self.interval)
            elif bar.close_price <= self.boll_down:
                self.start_long_algo(bar.close_price + self.increase_price,
                                     self.fixed_pos,
                                     payup=self.payup,
                                     interval=self.interval)
        elif self.spread_pos < 0:
            if bar.close_price <= self.boll_mid:
                self.start_long_algo(bar.close_price + self.increase_price,
                                     abs(self.spread_pos),
                                     payup=self.payup,
                                     interval=self.interval)
        else:
            if bar.close_price >= self.boll_mid:
                self.start_short_algo(bar.close_price - self.increase_price,
                                      abs(self.spread_pos),
                                      payup=self.payup,
                                      interval=self.interval)
        self.put_event()

    def on_spread_pos(self):
        """
        Callback when spread position is updated.
        """
        self.spread_pos = self.get_spread_pos()
        self.put_event()

    def on_spread_algo(self, algo: SpreadAlgoTemplate):
        """
        Callback when algo status is updated.
        """
        pass

    def on_order(self, order: OrderData):
        """
        Callback when order status is updated.
        """
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback when new trade data is received.
        """
        pass
Example #6
0
class MultiTimeframeStrategy(CtaTemplate):
    """"""
    author = "中科云集"

    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("c", self.fast_window)
        self.slow_ma = self.am15.sma("c", 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