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)
Exemplo n.º 2
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
Exemplo n.º 3
0
    def show(self):
        bars = self.barDatas
        if (bars[0].datetime > bars[-1].datetime):
            bars = bars.__reversed__()

        data = []
        index = []
        am = ArrayManager(self.window_size * 2)

        ### 初始化columns
        columns = ['Open', 'High', 'Low', 'Close', "Volume"]

        if self.open_boll:
            columns.append("boll_up")
            columns.append("boll_down")
        if (self.open_obv):
            columns.append("obv")
        if (self.open_rsi):
            columns.append("rsi")

        for bar in bars:
            index.append(bar.datetime)
            list = [
                bar.open_price, bar.high_price, bar.low_price, bar.close_price,
                bar.volume
            ]
            am.update_bar(bar)

            #添加布林指标数据
            if self.open_boll:
                if am.count >= self.window_size:
                    up, down = am.boll(self.window_size, 3.4)
                    list.append(up)
                    list.append(down)
                else:
                    list.append(bar.close_price)
                    list.append(bar.close_price)

            if self.open_obv:
                if am.count >= self.window_size:
                    obv = am.obv(self.window_size)
                    list.append(obv)
                else:
                    list.append(bar.volume)

            if self.open_rsi:
                if am.count >= self.window_size:
                    rsi = am.rsi(self.window_size)
                    list.append(rsi)
                else:
                    list.append(50)

            data.append(list)

        trades = pd.DataFrame(data, index=index, columns=columns)

        apds = []

        # 添加布林指标数据
        if self.open_boll:
            apds.append(
                mpf.make_addplot(trades['boll_up'], linestyle='dashdot'))
            apds.append(
                mpf.make_addplot(trades['boll_down'], linestyle='dashdot'))

        if self.open_obv:
            apds.append(
                mpf.make_addplot(trades['obv'],
                                 panel='lower',
                                 color='g',
                                 secondary_y=True))
        if self.open_rsi:
            apds.append(
                mpf.make_addplot(trades['rsi'],
                                 panel='lower',
                                 color='b',
                                 secondary_y=True))

        mpf.plot(trades,
                 type='candle',
                 volume=True,
                 mav=(5),
                 figscale=1.3,
                 style='yahoo',
                 addplot=apds)
Exemplo n.º 4
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