Example #1
0
class Ma1(CtaTemplate):
    author = "李鹏"
    fast_window = 10
    slow_window = 20
    fixed_size = 1
    fast_ma1 = 0.0
    fast_ma2 = 0.0
    slow_ma1 = 0.0
    slow_ma2 = 0.0

    parameters = ["fast_window", "slow_window", "fixed_size"]
    variables = ["fast_ma1", "fast_ma2", "slow_ma1", "slow_ma2"]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        super(Ma1, self).__init__(cta_engine, strategy_name, vt_symbol, setting)
        # K 线生成器,用来生成分钟K线 小时K线 日K线 或者周K线 主要是根据tick线生成K线
        self.bg = BarGenerator(self.on_bar)
        # K线序列管理器
        self.am = ArrayManager()

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

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

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

    def on_bar(self, bar: BarData):
        # 默认的分钟K线更新,除了tick级别和分钟K线级别是这两个,其他上层级别可自己定义
        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return
        fast_ma = am.sma(self.fast_window, array=True)
        # 获取最新的快速均线值,因为每根K线都是在形成后才调用的这个函数,所以不用刻意的向前跳
        self.fast_ma1 = fast_ma[-1]
        self.fast_ma2 = fast_ma[-2]
        slow_ma = am.sma(self.slow_window, array=True)
        self.slow_ma1 = slow_ma[-1]
        self.slow_ma2 = slow_ma[-2]
        # 上穿和下穿的标志
        cross_over = self.fast_ma1 > self.slow_ma1 and self.fast_ma2 < self.slow_ma2
        cross_below = self.fast_ma1 < self.slow_ma1 and self.fast_ma2 > self.slow_ma2
        if cross_over:
            if self.pos == 0:
                # 当前空仓就多头开仓
                self.buy(bar.close_price, self.fixed_size)  # 多头开仓,买开
            elif self.pos < 0:
                # 当前空头持仓,就平掉空仓,再多头开仓
                self.cover(bar.close_price, self.fixed_size)  # 空头平仓,买平
                self.buy(bar.close_price, self.fixed_size)  # 买开
        if cross_below:
            if self.pos == 0:
                self.short(bar.close_price, self.fixed_size)
            elif self.pos > 0:
                self.sell(bar.close_price, self.fixed_size)
                self.short(bar.close_price, self.fixed_size)
Example #2
0
 def to_1m_bar(self):
     '''
     这里用的vnpy的BarGenerator,从tick数据生成1m bar数据
     '''
     bars = []
     def on_bar(bar):
         bars.append(bar)
     bargenerator = BarGenerator(on_bar=on_bar)
     for tick in self.to_vnpy_tick():
         bargenerator.update_tick(tick)
     return bars
Example #3
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)
Example #4
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)
Example #5
0
class GridTradingStrategy(SpreadStrategyTemplate):
    """

    """
    author = "用Python的交易员"

    pay_up = 0.0
    grid_start = 0.0  # 开始位置
    grid_price = 20.0  # 网格距离
    grid_volume = 1.0
    max_pos = 25

    current_grid = 0.0
    spread_pos = 0.0
    max_target = 0.0
    min_target = 0.0

    parameters = [
        "pay_up", "grid_start", "grid_price", "grid_volume", "max_pos"
    ]
    variables = ["spread_pos", "current_grid", "max_target", "min_target"]

    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)

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

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

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

    def on_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):
        """"""
        if not self.trading:
            self.write_log("启动策略")
            return

        self.stop_all_algos()
        # 计算当前网格位置
        self.price_change = bar.close_price - self.grid_start  # 计算价格相比初始位置的变动
        self.current_grid = self.price_change / self.grid_price  # 计算网格水平

        # 计算当前最大、最小持仓
        self.max_target = ceil(-self.current_grid) * self.grid_volume  # 取最大值
        self.max_target = min(self.max_target, self.max_pos)
        self.max_target = max(self.max_target, -self.max_pos)

        self.min_target = floor(-self.current_grid) * self.grid_volume  # 取最小值
        self.min_target = min(self.min_target, self.max_pos)
        self.min_target = max(self.min_target, -self.max_pos)

        # 做多,检查最小持仓,和当前持仓的差值
        long_volume = self.min_target - self.spread_pos
        if long_volume > 0:
            long_price = bar.close_price + self.pay_up
            self.start_long_algo(price=long_price,
                                 volume=abs(long_volume),
                                 payup=5,
                                 interval=5)

        # 做空,检查最大持仓,和当前持仓的差值
        short_volume = self.max_target - self.spread_pos
        if short_volume < 0:
            short_price = bar.close_price - self.pay_up
            self.start_short_algo(price=short_price,
                                  volume=abs(short_volume),
                                  payup=5,
                                  interval=5)

        # 更新图形界面
        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 TrendFollowingStrategy(StrategyTemplate):
    """"""

    author = "用Python的交易员"

    atr_window = 22
    atr_ma_window = 10
    rsi_window = 5
    rsi_entry = 16
    trailing_percent = 0.8
    fixed_size = 1

    atr_value = 0
    atr_ma = 0
    rsi_value = 0
    rsi_buy = 0
    rsi_sell = 0
    intra_trade_high = 0
    intra_trade_low = 0

    parameters = [
        "atr_window", "atr_ma_window", "rsi_window", "rsi_entry",
        "trailing_percent", "fixed_size"
    ]
    variables = ["atr_value", "atr_ma", "rsi_value", "rsi_buy", "rsi_sell"]

    def __init__(self, strategy_engine: StrategyEngine, strategy_name: str,
                 vt_symbols: List[str], setting: dict):
        """"""
        super().__init__(strategy_engine, strategy_name, vt_symbols, setting)

        self.vt_symbol = vt_symbols[0]
        self.bg = BarGenerator(self.on_bar)
        self.am = ArrayManager()

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

        self.rsi_buy = 50 + self.rsi_entry
        self.rsi_sell = 50 - self.rsi_entry

        self.load_bars(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.
        """
        bars = {bar.vt_symbol: bar}
        self.on_bars(bars)

    def on_bars(self, bars: Dict[str, BarData]):
        """"""
        self.cancel_all()

        bar = bars[self.vt_symbol]
        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return

        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()
        self.rsi_value = am.rsi(self.rsi_window)

        pos = self.get_pos(self.vt_symbol)

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

            if self.atr_value > self.atr_ma:
                if self.rsi_value > self.rsi_buy:
                    self.buy(self.vt_symbol, bar.close_price + 5,
                             self.fixed_size)
                elif self.rsi_value < self.rsi_sell:
                    self.short(self.vt_symbol, bar.close_price - 5,
                               self.fixed_size)

        elif 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_percent / 100)

            if bar.close_price <= long_stop:
                self.sell(self.vt_symbol, bar.close_price - 5, abs(pos))

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

            short_stop = self.intra_trade_low * (1 +
                                                 self.trailing_percent / 100)

            if bar.close_price >= short_stop:
                self.cover(self.vt_symbol, bar.close_price + 5, abs(pos))

        self.put_event()
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)
class MACDSignal:
    """"""
    def __init__(self, strategy: StrategyTemplate, vt_symbol: str):
        """"""

        self.portfolio = strategy
        self.vt_symbol = vt_symbol

        self.fast_period = self.portfolio.fast_period
        self.slow_period = self.portfolio.slow_period
        self.signal_period = self.portfolio.signal_period
        self.trailing_percent = self.portfolio.trailing_percent
        self.fixed_size = self.portfolio.fixed_size
        self.bar_interval = self.portfolio.bar_interval
        self.bar_frequency = self.portfolio.bar_frequency

        self.macd_value = 0
        self.intra_trade_high = 0
        self.intra_trade_low = 0

        self.bg = BarGenerator(self.on_bar, self.bar_interval,
                               self.on_5min_bar, self.bar_frequency)
        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:
            return

        self.portfolio.cancel_all()
        am = self.am
        macd, macd_signal, _ = am.macd(self.fast_period,
                                       self.slow_period,
                                       self.signal_period,
                                       array=True)

        long_trend = (macd[-2] < macd_signal[-2]) and (macd[-1] >
                                                       macd_signal[-1])
        short_trend = (macd[-2] > macd_signal[-2]) and (macd[-1] <
                                                        macd_signal[-1])

        symbol_pos = self.portfolio.get_pos(self.vt_symbol)
        if symbol_pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            if long_trend:

                open_order = self.portfolio.buy(self.vt_symbol,
                                                bar.close_price + 5,
                                                self.fixed_size)

            elif short_trend:

                open_order = self.portfolio.short(self.vt_symbol,
                                                  bar.close_price - 5,
                                                  self.fixed_size)

        elif symbol_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_percent / 100)
            # if bar.close_price <= long_stop:
            #     close_order = self.portfolio.sell(self.vt_symbol, bar.close_price - 5, abs(symbol_pos))
            #     self.limit_orders.append(close_order)
            if short_trend:

                close_order = self.portfolio.sell(self.vt_symbol,
                                                  bar.close_price - 5,
                                                  abs(symbol_pos))

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

            short_stop = self.intra_trade_low * (1 +
                                                 self.trailing_percent / 100)
            # if bar.close_price >= short_stop:
            #     close_order = self.portfolio.cover(self.vt_symbol, bar.high_price + 5, abs(symbol_pos))
            #     self.limit_orders.append(close_order)
            if long_trend:
                close_order = self.portfolio.cover(self.vt_symbol,
                                                   bar.high_price + 5,
                                                   abs(symbol_pos))
Example #9
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
class DualThrustStrategy(CtaTemplate):
    """"""

    author = "中科云集"

    fixed_size = 1
    k1 = 0.4
    k2 = 0.6

    bars = []

    day_open = 0
    day_high = 0
    day_low = 0

    range = 0
    long_entry = 0
    short_entry = 0
    exit_time = time(hour=14, minute=55)

    long_entered = False
    short_entered = False

    parameters = ["k1", "k2", "fixed_size"]
    variables = ["range", "long_entry", "short_entry", "exit_time"]

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

        self.bg = BarGenerator(self.on_bar)
        self.am = ArrayManager()
        self.bars = []

    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.bars.append(bar)
        if len(self.bars) <= 2:
            return
        else:
            self.bars.pop(0)
        last_bar = self.bars[-2]

        if last_bar.datetime.date() != bar.datetime.date():
            if self.day_high:
                self.range = self.day_high - self.day_low
                self.long_entry = bar.open_price + self.k1 * self.range
                self.short_entry = bar.open_price - self.k2 * self.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
        else:
            self.day_high = max(self.day_high, bar.high_price)
            self.day_low = min(self.day_low, bar.low_price)

        if not self.range:
            return

        if bar.datetime.time() < self.exit_time:
            if self.pos == 0:
                if bar.close_price > self.day_open:
                    if not self.long_entered:
                        self.buy(self.long_entry, self.fixed_size, stop=True)
                else:
                    if not self.short_entered:
                        self.short(self.short_entry,
                                   self.fixed_size,
                                   stop=True)

            elif self.pos > 0:
                self.long_entered = True

                self.sell(self.short_entry, self.fixed_size, stop=True)

                if not self.short_entered:
                    self.short(self.short_entry, self.fixed_size, stop=True)

            elif self.pos < 0:
                self.short_entered = True

                self.cover(self.long_entry, self.fixed_size, stop=True)

                if not self.long_entered:
                    self.buy(self.long_entry, self.fixed_size, stop=True)

        else:
            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.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
class BollChannelStrategy(CtaTemplate):
    """"""

    author = "中科云集"

    boll_window = 18
    boll_dev = 3.4
    cci_window = 10
    atr_window = 30
    sl_multiplier = 5.2
    fixed_size = 1

    boll_up = 0
    boll_down = 0
    cci_value = 0
    atr_value = 0

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

    parameters = [
        "boll_window", "boll_dev", "cci_window", "atr_window", "sl_multiplier",
        "fixed_size"
    ]
    variables = [
        "boll_up", "boll_down", "cci_value", "atr_value", "intra_trade_high",
        "intra_trade_low", "long_stop", "short_stop"
    ]

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

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

        self.boll_up, self.boll_down = am.boll(self.boll_window, self.boll_dev)
        self.cci_value = am.cci(self.cci_window)
        self.atr_value = am.atr(self.atr_window)

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

            if self.cci_value > 0:
                self.buy(self.boll_up, self.fixed_size, True)
            elif self.cci_value < 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

            self.long_stop = self.intra_trade_high - self.atr_value * self.sl_multiplier
            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)

            self.short_stop = self.intra_trade_low + self.atr_value * self.sl_multiplier
            self.cover(self.short_stop, abs(self.pos), 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
class MarketMakerStrategy(CtaTemplate):
    """基于Tick的交易策略"""

    author = u'czhu'

    # 策略参数
    input_ss = 2
    tickSize = 30

    # 策略变量
    posPrice = 0  # 持仓价格
    poss = 0  # 持仓数量

    # 参数列表,保存了参数的名称
    parameters = ['tickSize', 'input_ss']

    # 同步列表,保存了需要保存到数据库的变量名称
    variables = ['poss', 'posPrice']

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

        self.bg = BarGenerator(self.on_bar)

        # 创建Array队列
        self.tickArray = TickArrayManager(self.tickSize)

        self.entrust = 0
        self.min_diff = 0.001

        self.ask_price = 0
        self.bid_price = 0

        self.order_time = 0

    def on_init(self):
        self.write_log(u'%s策略初始化' % self.strategy_name)
        # tick级别交易,不需要过往历史数据
        self.load_tick(0)

    # ----------------------------------------------------------------------
    def on_start(self):
        self.entrust = 0
        self.write_log(u'%s策略启动' % self.strategy_name)

    # ----------------------------------------------------------------------
    def on_stop(self):
        self.write_log(u'%s策略停止' % self.strategy_name)

    # ----------------------------------------------------------------------
    def on_tick(self, tick: TickData):

        # 首先检查是否是实盘运行还是数据预处理阶段
        if not self.inited or not self.trading:
            return

        self.bg.update_tick(tick)

        if self.entrust != 0:
            return

        if self.poss == 0:
            ta = self.tickArray
            ta.update_tick(tick)
            if not ta.inited:
                return

            # 如果空仓,分析过去30个对比,ask卖方多下空单,bid买方多下多单
            if ta.askbidvolumedif() > 0:
                price = tick.ask_price_2
                self.bid_price = tick.bid_price_2
                ref = self.short(price, self.input_ss, False)
                self.write_log(u'开空单{},价:{}'.format(ref[-5:-3], price))

            elif ta.askbidvolumedif() <= 0:
                price = tick.bid_price_2
                self.ask_price = tick.ask_price_2
                ref = self.buy(price, self.input_ss, False)
                self.write_log(u'开多单{},价:{}'.format(ref[-5:-3], price))

            self.entrust = 1

            # re-init TA
            ta.re_init()

    def on_bar(self, bar: BarData):
        if self.entrust == 1 and self.poss == 0:
            self.order_time += 1
            if self.order_time > 2:  # 2分钟未完成的订单, 取消
                self.write_log("\t取消超时未完成的开仓单")
                self.cancel_all()
                sleep(10)
                self.order_time = 0
                self.entrust = 0
        else:
            self.order_time = 0

        self.put_event()

    def on_order(self, order: OrderData):
        # if order.offset == Offset.OPEN:
        #     msg = u'{}{},{}张,价:{}'.format(order.offset.value, order.direction.value, order.volume, order.price)
        # else:
        #     if order.direction == Direction.LONG:
        #         direc = '空'
        #     else:
        #         direc = '多'
        #     msg = f'{order.offset.value}{direc},{order.volume}张,价:{order.price}'
        # self.write_log(f'\t报单更新,{order.orderid},{order.status.value},{msg}')

        if order.status == Status.SUBMITTING:
            self.entrust = 1
        elif order.status in [Status.NOTTRADED, Status.PARTTRADED]:
            # if order.offset == Offset.OPEN:
            #     sleep(20)
            #     self.write_log("取消开单")
            #     self.cancel_all()
            #     self.entrust = 0
            pass
        elif order.status == Status.ALLTRADED:
            if order.direction == Direction.LONG:
                self.poss += self.input_ss
            elif order.direction == Direction.SHORT:
                self.poss -= self.input_ss

            self.entrust = 0
            # sendWxMsg(order.symbol + msg, '')
        elif order.status == Status.CANCELLED:
            self.write_log(f'\t报单更新,{order.orderid[-3:]},{order.status.value}')
            self.entrust = 0
            self.poss = 0
            sleep(10)  # 10s
        elif order.status == Status.REJECTED:
            self.write_log(f'\t报单更新,{order.orderid[-3:]},{order.status.value}')
            # if order.offset == Offset.CLOSE:  # 平仓单异常
            #     self.write_log("取消多余的平仓单")
            #     self.cancel_all()
            sleep(10)  # 10s
        else:
            self.write_log(f'\t报单更新,{order.orderid[-3:]},{order.status.value}')
            pass

        self.put_event()

    def on_trade(self, trade: TradeData):
        # 同步数据到数据库
        if self.entrust == 0:
            if trade.offset == Offset.OPEN:
                msg = f'{trade.offset.value}{trade.direction.value},{trade.volume}张,成交价:{trade.price}'
                self.entrust = 1
                self.write_log(f'交易完成,{trade.orderid[-3:]},{msg}')
                if trade.direction == Direction.LONG:
                    price = self.ask_price
                    price = round_to(price, self.min_diff)
                    ref = self.sell(price, self.input_ss, False)
                    self.write_log(u'平多单{},价:{}'.format(ref[-5:-3], price))
                elif trade.direction == Direction.SHORT:
                    price = self.bid_price
                    price = round_to(price, self.min_diff)
                    ref = self.cover(price, self.input_ss, False)
                    self.write_log(u'平空单{},价:{}'.format(ref[-5:-3], price))
            else:
                if trade.direction == Direction.LONG:
                    direc = '空'
                else:
                    direc = '多'
                msg = f'{trade.offset.value}{direc},{trade.volume}张,成交价:{trade.price}'
                self.write_log(f'交易完成,{trade.orderid[-3:]},{msg}')

        self.put_event()
Example #13
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
Example #14
0
class DemoStrategy(CtaTemplate):
    """
    策略学习
    """
    author = "蒋越希"

    # 定义界面可以配置的参数
    fast_window = 10
    slow_window = 20
    parameters = [
        # 快速窗口
        "fast_window",
        # 慢速窗口
        "slow_window"
    ]

    # 定义变量
    fast_ma0 = 0.0
    fast_ma1 = 0.0
    slow_ma0 = 0.0
    slow_ma1 = 0.0
    variables = [
        "fast_ma0",
        "fast_ma1",
        "slow_ma0",
        "slow_ma1",
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        super(DemoStrategy, self).__init__(cta_engine, strategy_name, vt_symbol, setting)
        # 在on_window_bar参数里合成K线
        self.bg = BarGenerator(self.on_bar, window=5, on_window_bar=self.on_5min_bar, interval=Interval.MINUTE)
        self.am = ArrayManager()

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

    def on_start(self):
        """
        启动
        :return: 
        """
        self.write_log("启动")

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

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

    def on_5min_bar(self, bar: BarData):
        """
        5分钟K线
        :param bar: 
        :return: 
        """
        am = self.am

        am.update_bar(bar)
        if not am.inited:
            return
        # 快移动均线
        fast_ma = am.sma(self.fast_window, array=True)
        self.fast_ma0 = fast_ma[-1]
        self.fast_ma1 = fast_ma[-2]
        # 慢速移动均线
        slow_ma = am.sma(self.slow_window, array=True)
        self.slow_ma0 = slow_ma[-1]
        self.slow_ma1 = slow_ma[-2]

        # 判断均线交叉
        # 金叉
        cross_over = (self.fast_ma0 >= self.slow_ma0) and (self.fast_ma1 < self.slow_ma1)
        # 死叉
        cross_below = (self.fast_ma0 <= self.slow_ma0) and (self.fast_ma1 > self.slow_ma1)

        if cross_over:
            price = bar.close_price + 5
            if not self.pos:
                # 如果没有仓位

                # 买入开仓(看涨)
                self.buy(price, 1)
            elif self.pos < 0:
                # 买入平仓
                self.cover(price, 1)
                self.buy(price, 1)
            elif self.pos > 0:
                # 如果是 多, 不操作
                pass
        elif cross_below:
            price = bar.close_price - 5
            if not self.pos:
                # 做空 卖出开仓(看跌)
                self.short(price, 1)
            elif self.pos > 0:
                self.sell(price, 1)
                self.short(price, 1)

        self.put_event()

    def on_bar(self, bar: BarData):
        """
        K 线更新
        :param bar: 
        :return: 
        """
        self.bg.update_bar(bar)
class DoubleMaStrategy(CtaTemplate):
    author = "中科云集"

    fast_window = 10
    slow_window = 20

    fast_ma0 = 0.0
    fast_ma1 = 0.0

    slow_ma0 = 0.0
    slow_ma1 = 0.0

    parameters = ["fast_window", "slow_window"]
    variables = ["fast_ma0", "fast_ma1", "slow_ma0", "slow_ma1"]

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

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

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

        self.put_event()

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

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

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

        fast_ma = am.sma("c", self.fast_window, array=True)
        self.fast_ma0 = fast_ma[-1]
        self.fast_ma1 = fast_ma[-2]

        slow_ma = am.sma("c", self.slow_window, array=True)
        self.slow_ma0 = slow_ma[-1]
        self.slow_ma1 = slow_ma[-2]

        cross_over = self.fast_ma0 > self.slow_ma0 and self.fast_ma1 < self.slow_ma1
        cross_below = self.fast_ma0 < self.slow_ma0 and self.fast_ma1 > self.slow_ma1

        if cross_over:
            if self.pos == 0:
                self.buy(bar.close_price, 1)
            elif self.pos < 0:
                self.cover(bar.close_price, 1)
                self.buy(bar.close_price, 1)

        elif cross_below:
            if self.pos == 0:
                self.short(bar.close_price, 1)
            elif self.pos > 0:
                self.sell(bar.close_price, 1)
                self.short(bar.close_price, 1)

        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
class KingKeltnerStrategy(CtaTemplate):
    """"""

    author = '中科云集'

    kk_length = 11
    kk_dev = 1.6
    trailing_percent = 0.8
    fixed_size = 1

    kk_up = 0
    kk_down = 0
    intra_trade_high = 0
    intra_trade_low = 0

    long_vt_orderids = []
    short_vt_orderids = []
    vt_orderids = []

    parameters = ['kk_length', 'kk_dev', 'fixed_size']
    variables = ['kk_up', 'kk_down']

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

        self.bg = BarGenerator(self.on_bar, 5, self.on_5min_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_5min_bar(self, bar: BarData):
        """"""
        for orderid in self.vt_orderids:
            self.cancel_order(orderid)
        self.vt_orderids.clear()

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

        self.kk_up, self.kk_down = am.keltner(self.kk_length, self.kk_dev)

        if self.pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price
            self.send_oco_order(self.kk_up, self.kk_down, self.fixed_size)

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

            vt_orderids = self.sell(self.intra_trade_high * (1 - self.trailing_percent / 100),
                                    abs(self.pos), True)
            self.vt_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)

            vt_orderids = self.cover(self.intra_trade_low * (1 + self.trailing_percent / 100),
                                     abs(self.pos), True)
            self.vt_orderids.extend(vt_orderids)

        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 self.pos != 0:
            if self.pos > 0:
                for short_orderid in self.short_vt_orderids:
                    self.cancel_order(short_orderid)

            elif self.pos < 0:
                for buy_orderid in self.long_vt_orderids:
                    self.cancel_order(buy_orderid)

            for orderid in (self.long_vt_orderids + self.short_vt_orderids):
                if orderid in self.vt_orderids:
                    self.vt_orderids.remove(orderid)

        self.put_event()

    def send_oco_order(self, buy_price, short_price, volume):
        """"""
        self.long_vt_orderids = self.buy(buy_price, volume, True)
        self.short_vt_orderids = self.short(short_price, volume, True)

        self.vt_orderids.extend(self.long_vt_orderids)
        self.vt_orderids.extend(self.short_vt_orderids)

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Example #17
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 #18
0
class TurtleSignalStrategy(CtaTemplate):
    """"""
    author = "中科云集"

    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)
Example #19
0
class AtrRsiStrategy(CtaTemplate):
    """"""

    author = "中科云集"

    atr_length = 22
    atr_ma_length = 10
    rsi_length = 5
    rsi_entry = 16
    trailing_percent = 0.8
    fixed_size = 1

    atr_value = 0
    atr_ma = 0
    rsi_value = 0
    rsi_buy = 0
    rsi_sell = 0
    intra_trade_high = 0
    intra_trade_low = 0

    parameters = ["atr_length", "atr_ma_length", "rsi_length",
                  "rsi_entry", "trailing_percent", "fixed_size"]
    variables = ["atr_value", "atr_ma", "rsi_value", "rsi_buy", "rsi_sell"]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(AtrRsiStrategy, 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.rsi_buy = 50 + self.rsi_entry
        self.rsi_sell = 50 - self.rsi_entry

        self.load_bar(10)

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

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

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

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

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

        atr_array = am.atr(self.atr_length, array=True)
        self.atr_value = atr_array[-1]
        self.atr_ma = atr_array[-self.atr_ma_length:].mean()
        self.rsi_value = am.rsi(self.rsi_length)

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

            if self.atr_value > self.atr_ma:
                if self.rsi_value > self.rsi_buy:
                    self.buy(bar.close_price + 5, self.fixed_size)
                elif self.rsi_value < self.rsi_sell:
                    self.short(bar.close_price - 5, self.fixed_size)

        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_percent / 100)
            self.sell(long_stop, abs(self.pos), stop=True)

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

            short_stop = self.intra_trade_low * \
                (1 + self.trailing_percent / 100)
            self.cover(short_stop, abs(self.pos), stop=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
Example #20
0
class GridSpreadStrategy(SpreadStrategyTemplate):
    author = "Billy"

    grid_start = 0.0
    grid_price = 5.0
    grid_volume = 1.0
    pay_up = 10

    price_change = 0.0
    current_grid = 0.0
    max_target = 0.0
    min_target = 0.0

    parameters = ["grid_start", "grid_price", "grid_volume", "pay_up"]
    variables = ["price_change", "current_grid", "max_target", "min_target"]

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

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

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

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

    def on_spread_data(self):
        self.spread_pos = self.get_spread_pos()

        tick = self.spread.to_tick()
        self.bg.update_tick(tick)

        # mid_price = (self.spread.bid_price + self.spread.ask_price) / 2
        # self.price_change = mid_price - self.grid_start                                  # 计算价格相对初始位置的变动

    def on_bar(self, bar: BarData):
        self.stop_all_algos()

        # 计算当前网格位置
        self.price_change = Decimal(str(bar.close_price)) - self.grid_start
        self.current_grid = self.price_change / Decimal(str(
            self.grid_price))  # 计算网格水平

        self.max_target = ceil(
            -self.current_grid) * self.grid_volume  # 计算当前最大持仓
        self.min_target = floor(
            -self.current_grid) * self.grid_volume  # 计算当前最小持仓

        # 做多,检查最小持仓和当前持仓的差值
        long_volume = self.min_target - self.spread_pos
        if long_volume > 0:
            long_price = bar.close_price + self.pay_up
            self.start_long_algo(long_price, long_volume, 5, 5)

        # 做空,检查最大持仓和当前持仓的差值
        short_volume = self.max_target - self.spread_pos
        if short_volume < 0:
            short_price = bar.close_price - self.pay_up
            self.start_short_algo(short_price, abs(short_volume), 5, 5)

        self.put_event()

    def on_spread_pos(self):
        self.spread_pos = self.get_spread_pos()
        self.put_event()

    def on_spread_algo(self, algo: SpreadAlgoTemplate):
        pass

    def on_order(self, order: OrderData):
        pass

    def on_trade(self, trade: TradeData):
        self.put_event()
class TredningFollowingSignal:
    """"""
    def __init__(self, strategy: StrategyTemplate, vt_symbol: str):
        """"""

        self.portfolio = strategy
        self.vt_symbol = vt_symbol

        self.atr_window = self.portfolio.atr_window
        self.atr_ma_window = self.portfolio.atr_ma_window
        self.rsi_window = self.portfolio.rsi_window
        self.rsi_entry = self.portfolio.rsi_entry
        self.trailing_percent = self.portfolio.trailing_percent
        self.fixed_size = self.portfolio.fixed_size

        self.atr_value = 0
        self.atr_ma = 0
        self.rsi_value = 0
        self.rsi_buy = 50 + self.rsi_entry
        self.rsi_sell = 50 - self.rsi_entry
        self.intra_trade_high = 0
        self.intra_trade_low = 0

        self.limit_orders = []
        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:
            return

        self.portfolio.cancel_all()
        am = self.am
        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()
        self.rsi_value = am.rsi(self.rsi_window)

        symbol_pos = self.portfolio.get_pos(self.vt_symbol)
        if symbol_pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            if self.atr_value > self.atr_ma:
                if self.rsi_value > self.rsi_buy:
                    open_order = self.portfolio.buy(self.vt_symbol,
                                                    bar.close_price + 5,
                                                    self.fixed_size)
                    self.limit_orders.append(open_order)
                elif self.rsi_value < self.rsi_sell:
                    open_order = self.portfolio.short(self.vt_symbol,
                                                      bar.close_price - 5,
                                                      self.fixed_size)
        elif symbol_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_percent / 100)
            if bar.close_price <= long_stop:
                close_order = self.portfolio.sell(self.vt_symbol,
                                                  bar.close_price - 5,
                                                  abs(symbol_pos))
                self.limit_orders.append(close_order)
        elif symbol_pos < 0:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.intra_trade_high = bar.high_price

            short_stop = self.intra_trade_low * (1 +
                                                 self.trailing_percent / 100)
            if bar.close_price >= short_stop:
                close_order = self.portfolio.cover(self.vt_symbol,
                                                   bar.high_price + 5,
                                                   abs(symbol_pos))
                self.limit_orders.append(close_order)