Exemplo n.º 1
0
class MaSignal(CtaSignal):
    """"""

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

        self.fast_window = fast_window
        self.slow_window = slow_window

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

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

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

    def on_5min_bar(self, bar: BarData):
        """"""
        self.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

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

        if fast_ma > slow_ma:
            self.set_signal_pos(1)
        elif fast_ma < slow_ma:
            self.set_signal_pos(-1)
        else:
            self.set_signal_pos(0)
Exemplo n.º 2
0
class KingKeltnerStrategy(CtaTemplate):
    """"""

    author = '用Python的交易员'

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

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

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

        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
Exemplo n.º 3
0
class CtaTemplate_6(CtaTemplate_5):
    """
    add bar manager
    """

    className = 'CtaTemplate_6'
    author = u'rxg'

    # 基本变量
    initDays = 20  # 初始化数据所用的天数
    kLineCycle = 6  #Bar line cycle
    KLineSeconds = 60  #生成X秒的K线
    marketTradeValue = 0  #策略的交易市值
    arraySize = 100

    parameters = CtaTemplate_5.parameters + \
                [
                 'className',
                 'author',
                 'kLineCycle',
                 'initDays',
                 'debugMode',
                 'KLineSeconds',
                 'arraySize'
                 ]

    varList = CtaTemplate_5.variables + \
                [
                ]

    #----------------------------------------------------------------------
    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)
        print("-----")
        print(self.kLineCycle)
        self.bm = BarGenerator(self.on_bar, self.kLineCycle,
                               self.onXminBar)  # 创建K线合成器对象

        self.bm.xsec = self.KLineSeconds  #按指定X秒生成K线

        self.am = ArrayManager(size=self.arraySize)
        # self.am = getSharedArrayManager(self.vt_symbol, self.kLineCycle,
        #                                 self.KLineSeconds, self.arraySize)

        self.bm60 = BarGenerator(self.on_bar, 60, self.on60MinBar)
        self.am60 = ArrayManager(size=100)
        # self.am60 = getSharedArrayManager(self.vt_symbol, 60,
        #                                 self.KLineSeconds, 100)

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

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

        if hasattr(self, 'signal'):
            if hasattr(self.signal, 'am'):
                if not self.signal.am.inited:
                    self.write_log(u'%s策略信号加载初始数据不足' % self.strategy_name)
                    print(u'%s策略信号加载初始数据不足 ' % self.strategy_name,
                          self.initDays)

        if not self.am.inited:
            print(u'%s策略加载初始数据不足 ' % self.strategy_name, self.kLineCycle,
                  self.initDays)

        if not self.am60.inited:
            print(u'%s策略加载60 Min Bar 初始数据不足  ' % self.strategy_name,
                  self.initDays)

        self.put_event()

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

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

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

    #----------------------------------------------------------------------
    def on_bar(self, bar: BarData):
        '''处理分钟数据'''
        super(CtaTemplate_6, self).on_bar(bar)
        self.bm.update_bar(bar)
        self.bm60.update_bar(bar)

    #----------------------------------------------------------------------
    def onXminBar(self, bar):
        """收到X分钟K线"""
        # 保存K线数据
        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return

    def on60MinBar(self, bar):
        """收到X分钟K线"""
        self.am60.update_bar(bar)
        if not self.am60.inited:
            return

    #----------------------------------------------------------------------
    def getVolatility(self, volatilityTime=60):
        """收到X分钟K线"""
        # 保存K线数据
        return (self.am.atr(50) / self.lastPrice) * (
            (volatilityTime / self.kLineCycle)**0.5)
Exemplo n.º 4
0
class TSMyoCLFXCStrategy(CtaTemplate):
    """"""

    author = "TheSuperMyo"

    # 日内交易
    exit_time = time(hour=14, minute=56)
    # 针对不同交易时间的市场
    open_time_night = time(hour=21, minute=0)  # 商品夜盘
    open_time_day_1 = time(hour=9, minute=0)  # 商品
    open_time_day_2 = time(hour=9, minute=30)  # 股指

    close_time_day = time(hour=15, minute=0)  # 商品/股指(除了利率期货)
    close_time_night_1 = time(hour=23, minute=0)  # 其他夜盘商品
    close_time_night_2 = time(hour=1, minute=0)  # 工业金属
    close_time_night_3 = time(hour=2, minute=30)  # 黄金/白银/原油

    break_time_start_1 = time(hour=10, minute=15)  # 商品茶歇
    break_time_start_2 = time(hour=11, minute=30)  # 全体午休
    break_time_end_1 = time(hour=10, minute=30)  # 商品茶歇
    break_time_end_2 = time(hour=13, minute=0)  # 股指下午
    break_time_end_3 = time(hour=13, minute=30)  # 商品下午

    fit_bar = 15  # K线周期
    clfx_len = 15  # 计算上下轨的周期
    rsi_filter = 25
    rsi_len = 10

    trailing_stop = 0.45  # 跟踪止损
    fixed_size = 1  # 固定手数

    SAR_stop_long = 0
    SAR_stop_short = 0
    AF = 0

    long_entry = 0
    short_entry = 0
    long_exit = 0
    short_exit = 0
    hold_high = 0
    hold_low = 0

    parameters = ['rsi_len', 'rsi_filter', 'fit_bar', 'fixed_size']
    variables = [
        'SAR_stop_long', 'SAR_stop_short', 'AF', 'hold_high', 'hold_low'
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(TSMyoCLFXCStrategy, self).__init__(cta_engine, strategy_name,
                                                 vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar, self.fit_bar, self.on_fit_bar)
        self.am = TSMArrayManager()
        # 策略自身订单管理
        self.active_orderids = []
        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 tick_filter(self, tick: TickData):
        """
        过滤异常时间的tick
        """
        tick_time = tick.datetime.time()
        if tick_time < self.open_time_day_2:
            return False
        if tick_time > self.break_time_start_2 and tick_time < self.break_time_end_2:
            return False
        if tick_time > self.close_time_day:
            return False

        return True

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

    def on_bar(self, bar: BarData):
        """
        1.根据信号挂单
        2.计算SAR系统止损点位
        """
        self.bg.update_bar(bar)

        self.cancel_all()

        if self.pos == 0:
            if self.long_entry:
                # 入场开多,收盘价
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.buy(bar.close_price, self.fixed_size, False,
                                    True)
                self.active_orderids.extend(orderids)

            if self.short_entry:
                # 入场开空,收盘价
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.short(bar.close_price, self.fixed_size, False,
                                      True)
                self.active_orderids.extend(orderids)

        if self.pos > 0:
            old_high = self.hold_high
            self.hold_high = max(self.hold_high, bar.high_price)
            if old_high - self.hold_high != 0:
                self.AF += 0.01
                self.AF = min(self.AF, 0.1)

            self.SAR_stop_long = self.SAR_stop_long + (
                self.hold_high - self.SAR_stop_long) * self.AF
            #self.stop_long = self.hold_high*(1-self.trailing_stop/100)

            # 停止单平多
            if self.active_orderids:
                self.write_log("撤单不干净,无法挂单")
                return
            orderids = self.sell(self.SAR_stop_long, self.fixed_size, True,
                                 True)
            self.active_orderids.extend(orderids)

        if self.pos < 0:
            old_low = self.hold_low
            self.hold_low = min(self.hold_low, bar.low_price)
            if old_low - self.hold_low != 0:
                self.AF += 0.01
                self.AF = min(self.AF, 0.1)

            self.SAR_stop_short = self.SAR_stop_short - (
                self.SAR_stop_short - self.hold_low) * self.AF

            # 停止单平空
            if self.active_orderids:
                self.write_log("撤单不干净,无法挂单")
                return
            orderids = self.cover(self.SAR_stop_short, self.fixed_size, True,
                                  True)
            self.active_orderids.extend(orderids)

    def on_fit_bar(self, bar: BarData):
        """
        1.计算分型通道上下轨并产生信号
        """
        # self.cta_engine.output(f"{bar.datetime.time()}")
        # self.write_log(f"{bar.datetime.time()}")

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

        up, down = am.clfxc(self.clfx_len, False)
        rsi_value = am.rsi(self.rsi_len, False)
        rsi_flag = 0
        if abs(rsi_value - 50) > self.rsi_filter:
            rsi_flag = 1

        if self.pos == 0 and rsi_flag == 1:
            if bar.close_price > up:
                # 向上突破,开多信号
                self.long_entry = 1
                self.short_entry = 0
                self.long_exit = 0
                self.short_exit = 0
                # 抛物线初始止损点
                self.SAR_stop_long = bar.low_price

            if bar.close_price < down:
                # 向下突破,开空信号
                self.long_entry = 0
                self.short_entry = 1
                self.long_exit = 0
                self.short_exit = 0
                # 抛物线初始止损点
                self.SAR_stop_short = bar.high_price

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        # 移除已成交或已撤销的订单
        if not order.is_active() and order.vt_orderid in self.active_orderids:
            self.active_orderids.remove(order.vt_orderid)

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        # 邮寄提醒
        self.send_email(
            f"{trade.vt_symbol}在{trade.time}成交,价格{trade.price},方向{trade.direction}{trade.offset},数量{trade.volume}"
        )
        self.long_entry = 0
        self.short_entry = 0
        self.long_exit = 0
        self.short_exit = 0
        if self.pos == 0:
            self.SAR_stop_long = 0
            self.SAR_stop_short = 0
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        # 刚刚生成的本地停止单
        if stop_order.status == StopOrderStatus.WAITING:
            return
        # 撤销的本地停止单,从活跃列表移除
        if stop_order.status == StopOrderStatus.CANCELLED:
            if stop_order.stop_orderid in self.active_orderids:
                self.active_orderids.remove(stop_order.stop_orderid)
        # 触发的本地停止单,停止单移除,限价单加入
        if stop_order.status == StopOrderStatus.TRIGGERED:
            if stop_order.stop_orderid in self.active_orderids:
                self.active_orderids.remove(stop_order.stop_orderid)
                self.active_orderids.extend(stop_order.vt_orderids)
            # 撤掉其他停止单
            for other_orderids in self.active_orderids:
                if other_orderids.startswith(STOPORDER_PREFIX):
                    self.cancel_order(other_orderids)
Exemplo n.º 5
0
class CincoYStrategy(CtaTemplate):
    """"""

    author = "tonywang_efun"

    fixed_size = 2
    bar_window = 13
    boll_window = 38
    boll_dev = 2.2
    rsi_window = 8
    rsi_long = 76
    rsi_short = 18
    trailing_long = 2.8
    trailing_short = 2.6
    stop_long_percent = 3.0
    stop_short_percent = 3.0

    boll_up = 0
    boll_down = 0
    rsi_value = 0
    trading_size = 0
    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0
    short_percent_stop = 0
    long_percent_stop = 0

    parameters = [
        "fixed_size", "bar_window", "boll_window", "boll_dev", "rsi_window",
        "rsi_long", "rsi_short", "trailing_long", "trailing_short",
        "stop_long_percent", "stop_short_percent"
    ]

    variables = [
        "boll_up", "boll_down", "rsi_value", "trading_size",
        "intra_trade_high", "intra_trade_low", "long_stop", "short_stop"
    ]

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

        self.bg = BarGenerator(self.on_bar, self.bar_window, self.on_xmin_bar)
        self.am = ArrayManager()

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

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

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

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

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

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

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

        self.boll_up, self.boll_down = self.am.boll(self.boll_window,
                                                    self.boll_dev)
        self.rsi_value = self.am.rsi(self.rsi_window)
        boll_width = self.boll_up - self.boll_down

        if not self.pos:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price
            self.long_stop = 0
            self.short_stop = 0
            self.long_percent_stop = 0
            self.short_percent_stop = 0

            # print(self.boll_up, self.boll_down, self.intra_trade_high, self.intra_trade_low)

            if self.rsi_value >= self.rsi_long:
                self.buy(self.boll_up, self.fixed_size, stop=True)

            if self.rsi_value <= self.rsi_short:
                self.short(self.boll_down, self.fixed_size, stop=True)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.long_stop = self.intra_trade_high - self.trailing_long * boll_width
            self.long_percent_stop = self.intra_trade_high * (
                1 - self.stop_long_percent / 100)

            self.sell(max(self.long_stop, self.long_percent_stop),
                      abs(self.pos),
                      stop=True)

        else:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.short_stop = self.intra_trade_low + self.trailing_short * boll_width
            self.short_percent_stop = self.intra_trade_low * (
                1 + self.stop_short_percent / 100)

            self.cover(min(self.short_stop, self.short_percent_stop),
                       abs(self.pos),
                       stop=True)

        self.put_event()

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

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

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Exemplo n.º 6
0
class FixedHedgeStrategy(CtaTemplate):
    """"""
    author = "option underlying Fixed hedge"
    nick_name = 'fixed_hedge'
    is_log = False

    base_price = 0
    entry_range = 0.05

    hedge_range_param = 100
    hedge_multiple_param = 50

    hedge_range = 0.0
    hedge_multiple = 0.0
    hedge_size = 10

    last_trade_dt = None

    parameters = ['hedge_range_param', 'hedge_multiple_param', 'hedge_size']
    variables = []

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

        self.bg5 = BarGenerator(self.on_bar, 5, self.on_5min_bar)
        self.am5 = ArrayManager(size=20)

        self.hedge_range = self.hedge_range_param / 1000
        self.hedge_multiple = self.hedge_multiple_param / 100

        self.hedge_size = round(self.hedge_range / 0.1 * 30)
        setting['hedge_size'] = self.hedge_size
        print("params:", self.hedge_range, self.hedge_multiple,
              self.hedge_size, self.strategy_name)

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

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

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

    def on_tick(self, tick: TickData):
        pass

    def on_bar(self, bar: BarData):
        self.bg5.update_bar(bar)

    def on_5min_bar(self, bar: BarData):
        """"""
        self.log(bar.datetime, bar.open_price, bar.high_price, bar.low_price,
                 bar.close_price)

        self.cancel_all()

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

        if not self.base_price:
            self.base_price = round(bar.open_price, 2)
        else:
            up = self.base_price + self.hedge_range
            down = self.base_price - self.hedge_range
            self.log('base:', self.base_price, 'up:', up, 'down:', down,
                     'pos:', self.pos)

            if self.pos == 0:
                self.buy(up, self.hedge_size * self.hedge_multiple, True)
                self.short(down, self.hedge_size * self.hedge_multiple, True)
            elif self.pos > 0:
                # 条件触发用本地单
                self.sell(down, self.hedge_size * self.hedge_multiple, True)
                # self.short(down, self.hedge_size * self.hedge_multiple, True)
                self.buy(up, self.hedge_size * self.hedge_multiple, True)

                # 多单止盈用限价单
                self.sell(up, self.hedge_size * self.hedge_multiple, False)
            elif self.pos < 0:
                # 条件触发用本地单
                self.cover(up, self.hedge_size * self.hedge_multiple, True)
                # self.buy(up, self.hedge_size * self.hedge_multiple, True)
                self.short(down, self.hedge_size * self.hedge_multiple, True)

                # 空单止盈用限价单
                self.cover(down, self.hedge_size * self.hedge_multiple, False)

    def on_order(self, order: OrderData):
        pass

    def on_trade(self, trade: TradeData):
        self.log("Trade:", trade.datetime, trade.direction, trade.offset,
                 trade.price, trade.volume)
        if trade.datetime != self.last_trade_dt:
            if trade.direction == Direction.LONG:
                self.base_price += self.hedge_range * self.hedge_multiple
            elif trade.direction == Direction.SHORT:
                self.base_price -= self.hedge_range * self.hedge_multiple
        else:
            # 如果平仓后跟着开仓,说明前一次基线调错了,补回来后还要相应移动1档
            # self.log('trades at the same time')
            if trade.direction == Direction.LONG and trade.offset == Offset.OPEN:
                self.base_price += self.hedge_range * self.hedge_multiple * 2
            elif trade.direction == Direction.SHORT and trade.offset == Offset.OPEN:
                self.base_price -= self.hedge_range * self.hedge_multiple * 2

        self.last_trade_dt = trade.datetime

    def on_stop_order(self, stop_order: StopOrder):
        pass

    def log(self, *arg, **kwargs):
        if self.is_log:
            print(*arg, **kwargs)
Exemplo n.º 7
0
class TrendModelDoubleRsi(CtaTemplate):
    """"""
    author = "yiran"

    s_window = 5
    l_window = 15

    rsi_window = 11
    long_threshold_l_window = 50
    long_threshold_s_window = 80
    fixed_size = 1

    fast_ma_macd = 9
    slow_ma_macd = 26
    signal_macd = 4
    true_range_window = 4
    true_range_influence_multiplier = 0.5

    cross_over_record_max_num = 50
    cross_over_slice_window = 4
    trail_bar_window = 6

    mdif = 0
    cross_above_0 = False
    cross_under_0 = False
    cross_over_record_array = np.zeros(shape=(4, cross_over_record_max_num))
    cross_over_slice_window_highest = 0
    cross_over_slice_window_lowest = 0
    last_cross_over_interval = 0
    last_cross_over_side = 0

    bar_num = 0
    bar_num_after_crossover = 0

    start_time = time(hour=10)
    exit_time = time(hour=14, minute=55)

    long_order_record = []
    short_order_record = []

    rsi_value_l_window = -9999
    rsi_value_s_window = -9999
    exit_return = 0.02
    exit_loss = 0.02

    long_entered = False
    short_entered = False
    intra_trade_high = 0
    intra_trade_low = 0
    trailing_percent = 0.8
    parameters = [
        's_window', 'l_window', "rsi_window", "long_threshold_l_window",
        "long_threshold_s_window", 'exit_return', 'exit_loss', "fixed_size"
    ]

    variables = ["rsi_value_l_window ", "rsi_value_s_window", "ma_trend"]

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

        self.rsi_long_l = self.long_threshold_l_window
        self.rsi_long_s = self.long_threshold_s_window
        self.rsi_short_l = 100 - self.long_threshold_l_window
        self.rsi_short_s = 100 - self.long_threshold_s_window

        self.bg5 = BarGenerator(self.on_bar, self.s_window, self.on_5min_bar)
        self.am5 = ArrayManager()

        self.bg15 = BarGenerator(self.on_bar, self.l_window, self.on_15min_bar)
        self.am15 = ArrayManager()
        self.long_order_record = []
        self.short_order_record = []

    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

        self.rsi_value_s_window = self.am5.rsi(self.rsi_window)

        if self.long_threshold_l_window != -9999:
            self.long_entered = (self.rsi_value_s_window >
                                 self.rsi_long_s) and (self.rsi_value_l_window
                                                       > self.rsi_long_l)
            self.short_entered = (
                self.rsi_value_s_window < self.rsi_short_s) and (
                    self.rsi_value_l_window < self.rsi_short_l)
        else:
            return

        if self.start_time <= bar.datetime.time() < self.exit_time:
            time_constraint = self.last_cross_over_interval <= self.cross_over_record_max_num
            if self.pos == 0 and time_constraint:

                if self.long_entered:
                    self.buy(bar.close_price + 5, self.fixed_size)
                    self.long_order_record.append(bar.close_price + 5)
                elif self.short_entered:
                    self.short(bar.close_price - 5, self.fixed_size)
                    self.short_order_record.append(bar.close_price - 5)
            elif self.pos > 0:
                buy_order_price = self.long_order_record[-1]
                if bar.close_price >= buy_order_price * (1 + self.exit_return):
                    self.sell(bar.close_price * 0.99, abs(self.pos))
                elif bar.close_price <= buy_order_price * (1 - self.exit_loss):
                    self.sell(bar.close_price * 0.99, abs(self.pos))
            elif self.pos < 0:
                sell_order_price = self.short_order_record[-1]
                if bar.close_price >= sell_order_price * (1 + self.exit_loss):
                    self.cover(bar.close_price * 1.01, abs(self.pos))
                elif bar.close_price <= sell_order_price * (1 -
                                                            self.exit_return):
                    self.cover(bar.close_price * 1.01, abs(self.pos))
        elif bar.datetime.time() > self.exit_time:
            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_15min_bar(self, bar: BarData):
        """"""
        self.am15.update_bar(bar)
        self.bar_num += 1
        if not self.am15.inited:
            return
        self.rsi_value_l_window = self.am15.rsi(self.rsi_window)
        am = self.am15
        self.mdif, signal, hist = am.macd(self.fast_ma_macd,
                                          self.slow_ma_macd,
                                          self.signal_macd,
                                          array=True)
        self.long_close_stop_order_price = am.low[-self.trail_bar_window:].min(
        )
        self.short_close_stop_order_price = am.high[-self.
                                                    trail_bar_window:].max()

        if self.mdif[-2] < 0 < self.mdif[-1]:
            self.cross_above_0 = True
        elif self.mdif[-2] > 0 > self.mdif[-1]:
            self.cross_under_0 = True

        if self.cross_under_0 or self.cross_above_0:
            # bar_num
            self.cross_over_record_array[
                0, :-1] = self.cross_over_record_array[0, 1:]
            # high
            self.cross_over_record_array[
                1, :-1] = self.cross_over_record_array[1, 1:]
            # low
            self.cross_over_record_array[
                2, :-1] = self.cross_over_record_array[2, 1:]
            # cross_over_side
            self.cross_over_record_array[
                3, :-1] = self.cross_over_record_array[3, 1:]

            self.cross_over_record_array[0, -1] = self.bar_num
            self.cross_over_record_array[1, -1] = am.high[-1]
            self.cross_over_record_array[2, -1] = am.low[-1]
            if self.cross_above_0:
                side = 1
            elif self.cross_under_0:
                side = -1
            self.cross_over_record_array[3, -1] = side
            self.cross_above_0, self.cross_under_0 = False, False
            self.cross_over_slice_window_highest = np.max(
                self.cross_over_record_array[1,
                                             -self.cross_over_slice_window:])
            self.cross_over_slice_window_lowest = np.min(
                self.cross_over_record_array[2,
                                             -self.cross_over_slice_window:])
            self.last_cross_over_interval = self.bar_num - \
                                            self.cross_over_record_array[0, -1]
            self.last_cross_over_side = self.cross_over_record_array[3, -1]
            true_range_influence = np.mean(
                am.trange(array=True)[-self.true_range_window:]
            ) * self.true_range_influence_multiplier
            self.long_open_stop_order_price = self.cross_over_slice_window_highest + \
                                              true_range_influence
            self.short_open_stop_order_price = self.cross_over_slice_window_lowest + \
                                               true_range_influence

    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
Exemplo n.º 8
0
class KingKeltnerStrategy(CtaTemplate):
    """"""

    author = ' use Python traders '

    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(" strategy initialization ")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log(" policy startup ")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log(" stop strategy ")

    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
Exemplo n.º 9
0
class CincoStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    boll_window = 42
    boll_dev = 2.2
    atr_window = 4
    risk_level = 200
    trailing_short = 0.7
    trailing_long = 0.65

    boll_up = 0
    boll_down = 0
    rsi_buy = 0
    rsi_sell = 0
    atr_value = 0
    trading_size = 0

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

    parameters = [
        "boll_window", "boll_dev", "risk_level", "atr_window",
        "trailing_short", "trailing_long"
    ]

    variables = [
        "boll_up", "boll_down", "atr_value", "intra_trade_high",
        "intra_trade_low", "long_stop", "short_stop"
    ]

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

        self.bg = BarGenerator(self.on_bar, 15, self.on_15min_bar)
        # self.bg = MyGenerator(self.on_bar, self.interval, self.on_15min_bar)   # 合成15分钟k线
        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)  # 推送下一根k线

    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)  # 生成bolling带上下轨
        boll_width = self.boll_up - self.boll_down  # 计算bolling带宽度
        ## 空仓时
        if self.pos == 0:
            atr_fix = am.atr(self.atr_window)  # 计算atr指标
            self.trading_size = int(
                self.risk_level /
                atr_fix)  # 根据用风险控制水平除以atr得到开仓量,吗每单固定风险,根据atr调整仓位大小

            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price
            self.long_stop = 0
            self.short_stop = 0

            self.buy(self.boll_up, self.trading_size,
                     stop=True)  # 在bolling带上轨开多仓
            self.short(self.boll_down, self.trading_size,
                       stop=True)  # 在bolling带下轨开空仓
        ## 持有多仓时
        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high,
                                        bar.high_price)  # 计算持仓以后到达过的最高价
            self.intra_trade_low = bar.low_price  # 计算当根k线最低价

            self.long_stop = (self.intra_trade_high -
                              self.trailing_long * boll_width
                              )  # 用最高价回撤bolling带宽度与参数的方式计算追踪止损位置
            self.sell(self.long_stop, abs(self.pos), stop=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.trailing_short * boll_width)  # 计算追踪止损位置
            self.cover(self.short_stop, abs(self.pos), stop=True)  # 平掉全部空仓

        self.put_event()  # 更新vntrader界面数据
        self.sync_data()  # 将策略运行数据同步保存到本地

    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
Exemplo n.º 10
0
class CincoZHCStrategy(CtaTemplate):
    """"""

    author = "tonywang_efun"

    bar_window = 14
    bar_z_window = 48
    boll_window = 38
    boll_dev = 2.3
    rsi_window = 15
    rsi_long = 58
    rsi_short = 23
    fast_window = 3
    slow_window = 13
    trailing_long = 2.6
    trailing_short = 4.0
    fixed_size = 2

    boll_up = 0
    boll_down = 0
    rsi_value = 0
    fast_ma = 0
    slow_ma = 0
    ma_trend = 0
    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0
    atr_value = 0

    parameters = [
        "bar_window", "bar_z_window", "boll_window", "boll_dev", "rsi_window",
        "rsi_long", "rsi_short", "fast_window", "slow_window", "trailing_long",
        "trailing_short", "fixed_size"
    ]

    variables = [
        "boll_up", "boll_down", "rsi_value", "fast_ma", "slow_ma", "ma_trend",
        "intra_trade_high", "intra_trade_low", "long_stop", "short_stop"
    ]

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

        self.bg = BarGenerator(self.on_bar, self.bar_window, self.on_xmin_bar)
        self.bgz = BarGenerator(self.on_bar, self.bar_z_window,
                                self.on_zmin_bar)
        self.am = ArrayManager()
        self.amz = 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_bar(tick)

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

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

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

        self.boll_up, self.boll_down = self.am.boll(self.boll_window,
                                                    self.boll_dev)
        self.rsi_value = self.am.rsi(self.rsi_window)
        boll_width = self.boll_up - self.boll_down

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

            if self.ma_trend > 0 and self.rsi_value >= self.rsi_long:
                self.buy(self.boll_up, self.fixed_size, stop=True)

            if self.ma_trend < 0 and self.rsi_value <= self.rsi_short:
                self.short(self.boll_down, self.fixed_size, stop=True)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.long_stop = self.intra_trade_high - self.trailing_long * boll_width
            self.sell(self.long_stop, abs(self.pos), stop=True)

        else:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.short_stop = self.intra_trade_low + self.trailing_short * boll_width
            self.cover(self.short_stop, abs(self.pos), stop=True)

        self.put_event()

    def on_zmin_bar(self, bar: BarData):
        """"""
        self.amz.update_bar(bar)
        if not self.amz.inited:
            return

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

        if self.fast_ma > self.slow_ma:
            self.ma_trend = 1
        elif self.fast_ma < self.slow_ma:
            self.ma_trend = -1
        else:
            self.ma_trend = 0

        self.put_event()

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

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

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Exemplo n.º 11
0
class BollingerBotStrategy(CtaTemplate):
    """基于布林通道的交易策略"""
    author = u'tonywang_efun'

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

    # 策略变量
    entryUp = 0  # 开仓上轨
    exitUp = 0  # 平仓上轨
    maFilter = 0  # 均线过滤
    maFilter1 = 0  # 上一期均线
    intraTradeHigh = 0  # 持仓期内的最高点
    longEntry = 0  # 多头开仓
    longExit = 0  # 多头平仓

    # 参数列表,保存了参数的名称
    parameters = [
        'fixedSize', 'bollLength', 'entryDev', 'exitDev', 'trailingPrcnt',
        'maLength', 'initDays'
    ]

    # 变量列表,保存了变量的名称
    variables = ['entryUp', 'exitUp', 'intraTradeHigh', 'longEntry']

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

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

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

    # ----------------------------------------------------------------------
    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):
        """收到5分钟K线"""
        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        self.cancel_all()

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

        # 计算指标数值
        self.entryUp, self.exitUp = am.boll_double_up(self.bollLength,
                                                      self.entryDev,
                                                      self.exitDev)
        ma_array = am.sma(self.maLength, True)
        self.maFilter = ma_array[-1]
        self.maFilter1 = ma_array[-2]

        # 当前无仓位,发送OCO开仓委托
        if self.pos == 0:
            self.intraTradeHigh = bar.high_price

            if bar.close_price > self.maFilter > self.maFilter1:
                self.longEntry = self.entryUp
                self.buy(self.longEntry, self.fixedSize, True)

        # 持有多头仓位
        elif self.pos > 0:
            self.intraTradeHigh = max(self.intraTradeHigh, bar.high_price)

            self.longExit = self.intraTradeHigh * (1 -
                                                   self.trailingPrcnt / 100)
            self.longExit = min(self.longExit, self.exitUp)

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

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

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

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

    # ----------------------------------------------------------------------
    def on_stop_order(self, so):
        """停止单推送"""
        pass
Exemplo n.º 12
0
class DoubleDayM30Strategy(CtaTemplate):
    """
    使用1m线合成 日线、30分钟、1分钟三种数据,并根据各自ma叠加进行卖卖的策略
    """
    author = "fsksf"
    window_mn = 30  # n分钟线
    fast_window_day = 3
    fast_window_m30 = 3
    slow_window_day = 5
    slow_window_m30 = 5

    fast_ma_day = 0.0
    fast_ma_m30 = 0.0

    slow_ma_day = 0.0
    slow_ma_m30 = 0.0
    slow_ma_m1 = 0.0

    parameters = [
        "fast_window_day", "fast_window_m30", "slow_window_day",
        "slow_window_m30", "window_mn"
    ]
    variables = ["fast_ma_day", "slow_ma_day", "fast_ma_m30", "slow_ma_m30"]

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

        self.day_bar_gen = BarGenerator(lambda x: None,
                                        interval=Interval.DAILY,
                                        window=1,
                                        on_window_bar=self.on_day_bar)
        self.m30_bar_gen = BarGenerator(self.on_bar,
                                        interval=Interval.MINUTE,
                                        window=self.window_mn,
                                        on_window_bar=self.on_m30_bar)
        self.day_am = ArrayManager(size=self.slow_window_day + 1)
        self.m30_am = ArrayManager(size=self.slow_window_m30 + 1)

    def on_m30_bar(self, bar):
        self.write_log('30分钟bar合成完毕')
        self.m30_am.update_bar(bar)

    def on_day_bar(self, bar):
        self.write_log('day bar合成完毕')
        self.day_am.update_bar(bar)

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

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

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        # if self.cta_engine.gateway_name == "BACKTESTING":
        # update window
        self.m30_bar_gen.update_bar(bar)
        self.day_bar_gen.update_bar(bar)
        self.write_log(str(self.day_am.count))
        if not (self.day_am.inited and self.m30_am.inited):
            return
        self.write_log('bar历史初始化完成')

        # 最后一个bar实时更新的,计算ma后删除
        self.day_am.update_bar(self.day_bar_gen.last_bar)
        fast_ma_day = self.day_am.sma(self.fast_window_day, array=True)
        slow_ma_day = self.day_am.sma(self.slow_window_day, array=True)
        self.day_am.remove_last_bar()

        self.m30_am.update_bar(self.m30_bar_gen.last_bar)
        fast_ma_m30 = self.m30_am.sma(self.fast_window_m30, array=True)
        slow_ma_m30 = self.m30_am.sma(self.slow_window_m30, array=True)
        self.m30_am.remove_last_bar()

        self.fast_ma_day = fast_ma_day[-1]
        self.fast_ma_m30 = fast_ma_m30[-1]

        self.slow_ma_day = slow_ma_day[-1]
        self.slow_ma_m30 = slow_ma_m30[-1]


        cross_over = fast_ma_day[-2] < slow_ma_day[-2] and fast_ma_day[-1] > slow_ma_day[-1] and \
            fast_ma_m30[-2] < slow_ma_m30[-2] and fast_ma_m30[-1] > slow_ma_m30[-1]
        cross_below = fast_ma_day[-2] > slow_ma_day[-2] and fast_ma_day[-1] < slow_ma_day[-1] and \
            fast_ma_m30[-2] > slow_ma_m30[-2] and fast_ma_m30[-1] < slow_ma_m30[-1]

        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
Exemplo n.º 13
0
class TSMyoDochSARStrategy(CtaTemplate):
    """"""

    author = "TheSuperMyo"

    # 日内交易
    exit_time = time(hour=14, minute=56)
    # 针对不同交易时间的市场
    open_time_night = time(hour=21, minute=0)  # 商品夜盘
    open_time_day_1 = time(hour=9, minute=0)  # 商品
    open_time_day_2 = time(hour=9, minute=30)  # 股指

    close_time_day = time(hour=15, minute=0)  # 商品/股指(除了利率期货)
    close_time_night_1 = time(hour=23, minute=0)  # 其他夜盘商品
    close_time_night_2 = time(hour=1, minute=0)  # 工业金属
    close_time_night_3 = time(hour=2, minute=30)  # 黄金/白银/原油

    break_time_start_1 = time(hour=10, minute=15)  # 商品茶歇
    break_time_start_2 = time(hour=11, minute=30)  # 全体午休
    break_time_end_1 = time(hour=10, minute=30)  # 商品茶歇
    break_time_end_2 = time(hour=13, minute=0)  # 股指下午
    break_time_end_3 = time(hour=13, minute=30)  # 商品下午

    fit_bar = 3  # K线周期
    offset_bar = 2  # 入场极值偏移
    setup_bar = 85  # 基础拟合分钟数
    end_window = 95  # 时间窗口分钟数

    trailing_stop = 0.45  # 跟踪止损
    fixed_size = 1  # 固定手数

    bar_counter = 0  # 每日分钟计数器

    SAR_stop_long = 0
    SAR_stop_short = 0
    AF = 0

    long_entry = 0
    short_entry = 0
    long_exit = 0
    short_exit = 0
    hold_high = 0
    hold_low = 0

    parameters = [
        'offset_bar', 'end_window', 'setup_bar', 'fit_bar', 'fixed_size'
    ]
    variables = [
        'bar_counter', 'SAR_stop_long', 'SAR_stop_short', 'AF', 'hold_high',
        'hold_low'
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(TSMyoDochSARStrategy, self).__init__(cta_engine, strategy_name,
                                                   vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar, self.fit_bar, self.on_fit_bar)
        # 股指每天240分钟
        self.am = TSMArrayManager(240)
        # 策略自身订单管理
        self.active_orderids = []
        self.bars = []

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

    def tick_filter(self, tick: TickData):
        """
        过滤异常时间的tick
        """
        tick_time = tick.datetime.time()
        if tick_time < self.open_time_day_2:
            return False
        if tick_time > self.break_time_start_2 and tick_time < self.break_time_end_2:
            return False
        if tick_time > self.close_time_day:
            return False

        return True

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

    def on_bar(self, bar: BarData):
        """
        1.分钟计数
        2.根据信号挂单
        3.计算SAR系统止损点位
        """
        self.bar_counter += 1
        self.bg.update_bar(bar)

        self.cancel_all()

        if self.pos == 0 and bar.datetime.time() < self.exit_time:
            if self.long_entry:
                # 入场开多,收盘价
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.buy(bar.close_price, self.fixed_size, False,
                                    True)
                self.active_orderids.extend(orderids)

            if self.short_entry:
                # 入场开空,收盘价
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.short(bar.close_price, self.fixed_size, False,
                                      True)
                self.active_orderids.extend(orderids)

        if self.pos > 0:
            old_high = self.hold_high
            self.hold_high = max(self.hold_high, bar.high_price)
            if old_high - self.hold_high != 0:
                self.AF += 0.01
                self.AF = min(self.AF, 0.1)

            self.SAR_stop_long = self.SAR_stop_long + (
                self.hold_high - self.SAR_stop_long) * self.AF
            #self.stop_long = self.hold_high*(1-self.trailing_stop/100)

            if bar.datetime.time() > self.exit_time:
                # 日内平仓
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.sell(bar.close_price, self.fixed_size, False,
                                     True)
                self.active_orderids.extend(orderids)
            else:
                # 停止单平多
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.sell(self.SAR_stop_long, self.fixed_size, True,
                                     True)
                self.active_orderids.extend(orderids)

        if self.pos < 0:
            old_low = self.hold_low
            self.hold_low = min(self.hold_low, bar.low_price)
            if old_low - self.hold_low != 0:
                self.AF += 0.01
                self.AF = min(self.AF, 0.1)

            self.SAR_stop_short = self.SAR_stop_short - (
                self.SAR_stop_short - self.hold_low) * self.AF

            if bar.datetime.time() > self.exit_time:
                # 日内平仓
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.cover(bar.close_price, self.fixed_size, False,
                                      True)
                self.active_orderids.extend(orderids)
            else:
                # 停止单平空
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.cover(self.SAR_stop_short, self.fixed_size,
                                      True, True)
                self.active_orderids.extend(orderids)

    def on_fit_bar(self, bar: BarData):
        """
        1.负责每日开盘的初始化
        2.计算极值并产生信号
        """
        # self.cta_engine.output(f"{bar.datetime.time()}")
        # self.write_log(f"{bar.datetime.time()}")

        am = self.am
        am.update_bar(bar)

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

        last_bar = self.bars[-2]
        # 开盘fit_min_bar
        if last_bar.datetime.date() != bar.datetime.date():
            # 初始化
            self.bar_counter = self.fit_bar
            self.long_entry = 0
            self.short_entry = 0
            self.long_exit = 0
            self.short_exit = 0
            self.SAR_stop_long = 0
            self.SAR_stop_short = 0

        if self.bar_counter < self.setup_bar:
            return

        up_array, down_array = am.donchian(
            int((self.bar_counter) / self.fit_bar))
        up = up_array[-1 - self.offset_bar]
        down = down_array[-1 - self.offset_bar]

        if self.pos == 0 and self.bar_counter < self.end_window:
            if bar.close_price > up:
                # 向上突破,开多信号
                self.long_entry = 1
                self.short_entry = 0
                self.long_exit = 0
                self.short_exit = 0
                # 抛物线初始止损点
                self.SAR_stop_long = bar.low_price

            if bar.close_price < down:
                # 向下突破,开空信号
                self.long_entry = 0
                self.short_entry = 1
                self.long_exit = 0
                self.short_exit = 0
                # 抛物线初始止损点
                self.SAR_stop_short = bar.high_price

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        # 移除已成交或已撤销的订单
        if not order.is_active() and order.vt_orderid in self.active_orderids:
            self.active_orderids.remove(order.vt_orderid)

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        # 邮寄提醒
        self.send_email(
            f"{trade.vt_symbol}在{trade.time}成交,价格{trade.price},方向{trade.direction}{trade.offset},数量{trade.volume}"
        )
        self.long_entry = 0
        self.short_entry = 0
        self.long_exit = 0
        self.short_exit = 0
        if self.pos == 0:
            self.SAR_stop_long = 0
            self.SAR_stop_short = 0
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        # 刚刚生成的本地停止单
        if stop_order.status == StopOrderStatus.WAITING:
            return
        # 撤销的本地停止单,从活跃列表移除
        if stop_order.status == StopOrderStatus.CANCELLED:
            if stop_order.stop_orderid in self.active_orderids:
                self.active_orderids.remove(stop_order.stop_orderid)
        # 触发的本地停止单,停止单移除,限价单加入
        if stop_order.status == StopOrderStatus.TRIGGERED:
            if stop_order.stop_orderid in self.active_orderids:
                self.active_orderids.remove(stop_order.stop_orderid)
                self.active_orderids.extend(stop_order.vt_orderids)
            # 撤掉其他停止单
            for other_orderids in self.active_orderids:
                if other_orderids.startswith(STOPORDER_PREFIX):
                    self.cancel_order(other_orderids)
Exemplo n.º 14
0
class MLearnStrategy(CtaTemplate):
    """"""
    author = "用Python的交易员"

    load_bar_day = 20
    sl_multiplier = 7.6
    fixed_size = 1
    db_record = 0
    bar_window = 5
    bar_size = 100
    slippage_rate = 0.002

    direction = Direction.NET
    atr_value = 0
    trade_long_price = 0
    trade_short_price = 0
    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0
    atr_window = 30

    vt_xm_orderids = []

    parameters = [
        "load_bar_day", "sl_multiplier", "fixed_size", "db_record",
        "bar_window", "bar_size", "slippage_rate"
    ]
    variables = [
        "direction", "atr_value", "trade_long_price", "trade_long_price",
        "intra_trade_high", "intra_trade_low", "long_stop", "short_stop"
    ]

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

        self.bg = BarGenerator(self.on_bar, self.bar_window, self.on_xmin_bar)
        #self.am_xm = MLP_Analyze(self.bar_size)
        self.am_xm = LSTM_Analyze(self.bar_size)

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

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

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

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

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

    def on_xmin_bar(self, bar: BarData):
        """"""
        self.cancel_order_list(self.vt_xm_orderids)
        self.am_xm.update_bar(bar)
        if not self.am_xm.inited:
            return

        self.direction = self.am_xm.trend
        self.atr_value = self.am_xm.atr(self.atr_window)
        self.trade_long_price = get_trade_long_price(bar.close_price,
                                                     self.slippage_rate)
        self.trade_short_price = get_trade_short_price(bar.close_price,
                                                       self.slippage_rate)
        vt_orderids = []
        if self.pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            if self.direction == Direction.LONG:
                vt_orderids = self.buy(self.trade_long_price, self.fixed_size)
            elif self.direction == Direction.SHORT:
                vt_orderids = self.short(self.trade_short_price,
                                         self.fixed_size)

            self.vt_xm_orderids.extend(vt_orderids)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.intra_trade_low = bar.low_price
            if self.direction == Direction.SHORT:
                vt_orderids = self.sell(self.trade_short_price, abs(self.pos))
            else:
                self.long_stop = self.intra_trade_high - self.atr_value * self.sl_multiplier
                vt_orderids = self.sell(self.long_stop, abs(self.pos), True)
            self.vt_xm_orderids.extend(vt_orderids)

        elif self.pos < 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            if self.direction == Direction.LONG:
                vt_orderids = self.cover(self.trade_long_price, abs(self.pos))
            else:
                self.short_stop = self.intra_trade_low + self.atr_value * self.sl_multiplier
                vt_orderids = self.cover(self.short_stop, abs(self.pos), True)
            self.vt_xm_orderids.extend(vt_orderids)

        if self.db_record:
            database_manager.save_bar_calc(bar, self.get_variables())

        self.put_event()

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

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        # 数据库记录成交记录,bar记录,variables值
        if self.db_record:
            database_manager.save_trade_data(trade, self.get_variables())

        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Exemplo n.º 15
0
class DoubleRsiTrailing(CtaTemplate):
    """"""
    author = "yiran"

    s_window = 5
    l_window = 15

    rsi_window = 11
    long_threshold_l_window = 50
    long_threshold_s_window = 80
    fixed_size = 1

    start_time = time(hour=10)
    exit_time = time(hour=14, minute=55)

    long_order_record = []
    short_order_record = []

    rsi_value_l_window = -9999
    rsi_value_s_window = -9999
    exit_return = 0.02
    exit_loss = 0.02

    long_entered = False
    short_entered = False
    intra_trade_high = 0
    intra_trade_low = 0
    trailing_percent = 0.8
    parameters = [
        's_window', 'l_window', "rsi_window", "long_threshold_l_window",
        "long_threshold_s_window", 'exit_return', 'exit_loss', "fixed_size"
    ]

    variables = ["rsi_value_l_window ", "rsi_value_s_window", "ma_trend"]

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

        self.rsi_long_l = self.long_threshold_l_window
        self.rsi_long_s = self.long_threshold_s_window
        self.rsi_short_l = 100 - self.long_threshold_l_window
        self.rsi_short_s = 100 - self.long_threshold_s_window

        self.bg5 = BarGenerator(self.on_bar, self.s_window, self.on_5min_bar)
        self.am5 = ArrayManager()

        self.bg15 = BarGenerator(self.on_bar, self.l_window, self.on_15min_bar)
        self.am15 = ArrayManager()
        self.long_order_record = []
        self.short_order_record = []

    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

        self.rsi_value_s_window = self.am5.rsi(self.rsi_window)

        if self.long_threshold_l_window != -9999:
            self.long_entered = (self.rsi_value_s_window >
                                 self.rsi_long_s) and (self.rsi_value_l_window
                                                       > self.rsi_long_l)
            self.short_entered = (
                self.rsi_value_s_window < self.rsi_short_s) and (
                    self.rsi_value_l_window < self.rsi_short_l)
        else:
            return

        if self.start_time <= bar.datetime.time() < self.exit_time:
            if self.pos == 0:
                self.intra_trade_high = bar.high_price
                self.intra_trade_low = bar.low_price
                if self.long_entered:
                    self.buy(bar.close_price + 5, self.fixed_size)
                    self.long_order_record.append(bar.close_price + 5)
                elif self.short_entered:
                    self.short(bar.close_price - 5, self.fixed_size)
                    self.short_order_record.append(bar.close_price - 5)
            elif self.pos > 0:
                buy_order_price = self.long_order_record[-1]
                self.intra_trade_high = max(self.intra_trade_high,
                                            bar.high_price)
                self.intra_trade_low = bar.low_price
                self.sell(self.intra_trade_high * \
                          (1 - self.trailing_percent / 100), abs(self.pos), True)

                # if bar.close_price >= buy_order_price*(1+self.exit_return):
                #     self.sell(bar.close_price * 0.99, abs(self.pos))
                # elif bar.close_price <= buy_order_price*(1-self.exit_loss):
                #     self.sell(bar.close_price * 0.99, abs(self.pos))
            elif self.pos < 0:
                self.intra_trade_high = bar.high_price
                self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
                self.cover(self.intra_trade_low * (1 + \
                           self.trailing_percent / 100), abs(self.pos), True)

                #
                # if bar.close_price >= sell_order_price*(1+self.exit_loss):
                #     self.cover(bar.close_price * 1.01, abs(self.pos))
                # elif bar.close_price <= sell_order_price*(1-self.exit_return):
                #     self.cover(bar.close_price * 1.01, abs(self.pos))
        elif bar.datetime.time() > self.exit_time:
            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_15min_bar(self, bar: BarData):
        """"""
        self.am15.update_bar(bar)
        if not self.am15.inited:
            return
        self.rsi_value_l_window = self.am15.rsi(self.rsi_window)

    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
Exemplo n.º 16
0
class TSMyoDLLTStrategy(CtaTemplate):
    """"""

    author = "TheSuperMyo"

    # 日内交易
    exit_time = time(hour=14, minute=57)
    # 针对不同交易时间的市场
    open_time_night = time(hour=21, minute=0)  # 商品夜盘
    open_time_day_1 = time(hour=9, minute=0)  # 商品
    open_time_day_2 = time(hour=9, minute=30)  # 股指

    close_time_day = time(hour=15, minute=0)  # 商品/股指(除了利率期货)
    close_time_night_1 = time(hour=23, minute=0)  # 其他夜盘商品
    close_time_night_2 = time(hour=1, minute=0)  # 工业金属
    close_time_night_3 = time(hour=2, minute=30)  # 黄金/白银/原油

    break_time_start_1 = time(hour=10, minute=15)  # 商品茶歇
    break_time_start_2 = time(hour=11, minute=30)  # 全体午休
    break_time_end_1 = time(hour=10, minute=30)  # 商品茶歇
    break_time_end_2 = time(hour=13, minute=0)  # 股指下午
    break_time_end_3 = time(hour=13, minute=30)  # 商品下午

    fit_bar = 30  # 日间K线周期
    LLT_len_slow = 20
    LLT_len_fast = 10

    trailing_stop = 2  # 跟踪止损
    fixed_size = 1  # 固定手数

    bar_counter = 0  # 每日分钟计数器
    LLT_value_slow = 0
    LLT_value_fast = 0
    cross_up = 0
    cross_down = 0

    stop_long = 0
    stop_short = 0
    hold_high = 0
    hold_low = 0

    parameters = [
        'LLT_len_slow', 'LLT_len_fast', 'fit_bar', 'trailing_stop',
        'fixed_size'
    ]
    variables = [
        'bar_counter', 'LLT_value_slow', 'LLT_value_fast', 'stop_long',
        'stop_short', 'hold_high', 'hold_low', 'cross_up', 'cross_down'
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(TSMyoDLLTStrategy, self).__init__(cta_engine, strategy_name,
                                                vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar)
        self.am = TSMArrayManager()
        # 策略自身订单管理
        self.active_orderids = []

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

    def tick_filter(self, tick: TickData):
        """
        过滤异常时间的tick
        """
        tick_time = tick.datetime.time()
        if tick_time < self.open_time_day_2:
            return False
        if tick_time > self.break_time_start_2 and tick_time < self.break_time_end_2:
            return False
        if tick_time > self.close_time_day:
            return False

        return True

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

    def on_bar(self, bar: BarData):
        self.bg.update_bar(bar)

    def on_fit_bar(self, bar: BarData):
        """
        1.分钟计数
        2.挂撤单
        """
        self.cancel_all()

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

        self.LLT_value_fast = am.LLT(self.LLT_len_fast, True)
        self.LLT_value_slow = am.LLT(self.LLT_len_slow, True)

        # 金叉
        if self.LLT_value_fast[-2] < self.LLT_value_slow[
                -2] and self.LLT_value_fast[-1] > self.LLT_value_slow[-1]:
            self.cross_up = (self.LLT_value_slow[-1] +
                             self.LLT_value_slow[-2]) / 2
            if self.pos == 0:
                # 入场开多
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.buy(bar.close_price, self.fixed_size, False,
                                    True)
                self.active_orderids.extend(orderids)
        # 死叉
        if self.LLT_value_fast[-2] > self.LLT_value_slow[
                -2] and self.LLT_value_fast[-1] < self.LLT_value_slow[-1]:
            self.cross_down = (self.LLT_value_slow[-1] +
                               self.LLT_value_slow[-2]) / 2
            if self.pos == 0:
                # 入场开空
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.short(bar.close_price, self.fixed_size, False,
                                      True)
                self.active_orderids.extend(orderids)

        if self.pos > 0:
            self.hold_high = max(self.hold_high, bar.high_price)
            self.stop_long = self.hold_high * (1 - self.trailing_stop / 100)
            self.stop_long = max(self.stop_long, self.cross_up)

            # 停止单平多
            if self.active_orderids:
                self.write_log("撤单不干净,无法挂单")
                return
            orderids = self.sell(self.stop_long, self.fixed_size, True, True)
            self.active_orderids.extend(orderids)

        if self.pos < 0:
            self.hold_low = min(self.hold_low, bar.low_price)
            self.stop_short = self.hold_low * (1 + self.trailing_stop / 100)
            self.stop_short = min(self.stop_short, self.cross_down)

            # 停止单平空
            if self.active_orderids:
                self.write_log("撤单不干净,无法挂单")
                return
            orderids = self.cover(self.stop_short, self.fixed_size, True, True)
            self.active_orderids.extend(orderids)

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        # 移除已成交或已撤销的订单
        if not order.is_active() and order.vt_orderid in self.active_orderids:
            self.active_orderids.remove(order.vt_orderid)

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        # 邮寄提醒
        self.send_email(
            f"{trade.vt_symbol}在{trade.time}成交,价格{trade.price},方向{trade.direction}{trade.offset},数量{trade.volume}"
        )
        if self.pos == 0:
            self.stop_long = 0
            self.stop_short = 0
        if self.pos > 0:
            self.hold_high = trade.price
        if self.pos < 0:
            self.hold_low = trade.price
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        # 刚刚生成的本地停止单
        if stop_order.status == StopOrderStatus.WAITING:
            return
        # 撤销的本地停止单,从活跃列表移除
        if stop_order.status == StopOrderStatus.CANCELLED:
            if stop_order.stop_orderid in self.active_orderids:
                self.active_orderids.remove(stop_order.stop_orderid)
        # 触发的本地停止单,停止单移除,限价单加入
        if stop_order.status == StopOrderStatus.TRIGGERED:
            if stop_order.stop_orderid in self.active_orderids:
                self.active_orderids.remove(stop_order.stop_orderid)
                self.active_orderids.extend(stop_order.vt_orderids)
            # 撤掉其他停止单
            for other_orderids in self.active_orderids:
                if other_orderids.startswith(STOPORDER_PREFIX):
                    self.cancel_order(other_orderids)
class MyBollChannelStrategy(CtaTemplate):
    """"""

    author = "sheepbear"

    boll_window = 18
    boll_dev = 3.4
    fixed_size = 1

    boll_up = 0
    boll_down = 0
    boll_mid = 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().__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.boll_mid = am.sma(self.boll_window)

        # Use boll mid as stop loss
        if self.pos == 0:
            self.buy(self.boll_up, self.fixed_size, True)
            self.short(self.boll_down, self.fixed_size, True)

        elif self.pos > 0:
            if bar.close_price <= self.boll_mid:
                self.sell(bar.close_price - 5, abs(self.pos))

        elif self.pos < 0:
            if bar.close_price >= self.boll_mid:
                self.cover(bar.close_price + 5, 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
Exemplo n.º 18
0
class DoubleRsiAtr(CtaTemplate):
    """"""
    author = "yiran"

    s_window = 5
    l_window = 15
    atr_window = 20
    atr_multiplier = 0.05
    rsi_window = 11
    long_threshold_l_window = 50
    long_threshold_s_window = 80
    exit_return = 0.02
    exit_loss = 0.02
    exit_return_soft_long = -0.1
    exit_loss_soft_long = -0.2
    exit_return_soft_short = 0.2
    exit_loss_soft_short = 0.1

    fixed_size = 1

    start_time = time(hour=10)
    exit_time = time(hour=14, minute=55)

    long_order_record = []
    short_order_record = []

    rsi_value_l_window = -9999
    rsi_value_s_window = -9999
    atr_value = 0

    position_hold = 0
    long_entered = False
    short_entered = False

    parameters = [
        's_window', 'l_window', 'atr_window', 'atr_multiplier',
        'exit_return_soft_long', 'exit_loss_soft_long', "rsi_window",
        'exit_return_soft_short', 'exit_loss_soft_short',
        "long_threshold_l_window", "long_threshold_s_window", 'exit_return',
        'exit_loss', "fixed_size"
    ]

    variables = ["rsi_value_l_window ", "rsi_value_s_window", "ma_trend"]

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

        self.rsi_long_l = self.long_threshold_l_window
        self.rsi_long_s = self.long_threshold_s_window
        self.rsi_short_l = 100 - self.long_threshold_l_window
        self.rsi_short_s = 100 - self.long_threshold_s_window

        self.bg5 = BarGenerator(self.on_bar, self.s_window, self.on_5min_bar)
        self.am5 = ArrayManager()

        self.bg15 = BarGenerator(self.on_bar, self.l_window, self.on_15min_bar)
        self.am15 = ArrayManager()
        self.long_order_record = []
        self.short_order_record = []
        self.atr_value_array = np.array([])

        self.atr_profit_exit_recorder = []

    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

        self.rsi_value_s_window = self.am5.rsi(self.rsi_window)
        self.atr_value = self.am5.atr(self.atr_window)

        if self.long_threshold_l_window != -9999:
            self.long_entered = (self.rsi_value_s_window >
                                 self.rsi_long_s) and (self.rsi_value_l_window
                                                       > self.rsi_long_l)
            self.short_entered = (
                self.rsi_value_s_window < self.rsi_short_s) and (
                    self.rsi_value_l_window < self.rsi_short_l)
        else:
            return

        if self.start_time <= bar.datetime.time() < self.exit_time:
            if self.pos == 0:
                self.position_hold = 0
                if self.long_entered:
                    self.buy(bar.close_price + 5, self.fixed_size)
                    self.long_order_record.append(bar.close_price + 5)
                elif self.short_entered:
                    self.short(bar.close_price - 5, self.fixed_size)
                    self.short_order_record.append(bar.close_price - 5)
            elif self.pos > 0:
                self.position_hold += 1
                buy_order_price = self.long_order_record[-1]
                initial_profit_exit_price = buy_order_price * (
                    1 + self.exit_return)
                # 波动变大+持仓周期变长,会使得止盈的点上移
                moving_profit_exit_price = buy_order_price * (
                    1 + self.exit_return_soft_long
                ) + self.atr_value * self.atr_multiplier * self.position_hold

                initial_loss_exit_price = buy_order_price * (1 -
                                                             self.exit_loss)
                # 波动变大+持仓周期变长,会使得止损的点上移
                moving_loss_exit_price = buy_order_price * (
                    1 + self.exit_loss_soft_long
                ) + self.atr_value * self.atr_multiplier * self.position_hold
                if initial_profit_exit_price < moving_profit_exit_price:
                    self.atr_profit_exit_recorder.append((1, bar.datetime))
                else:
                    self.atr_profit_exit_recorder.append((0, bar.datetime))

                if bar.close_price >= max(initial_profit_exit_price,
                                          moving_profit_exit_price):
                    self.sell(bar.close_price * 0.99, abs(self.pos))
                elif bar.close_price <= max(initial_loss_exit_price,
                                            moving_loss_exit_price):
                    self.sell(bar.close_price * 0.99, abs(self.pos))

            elif self.pos < 0:
                self.position_hold += 1
                sell_order_price = self.short_order_record[-1]
                #初始的盈利要求比较低即空头平仓的价格比较高
                initial_profit_exit_price = sell_order_price * (
                    1 - self.exit_return)
                # 随着持仓时间推移和波动率变大,对应盈利方向上的头寸止盈要求变高,即空头平仓价格下移
                moving_profit_exit_price = sell_order_price * (
                    1 + self.exit_return_soft_short
                ) - self.atr_value * self.atr_multiplier * self.position_hold
                initial_loss_exit_price = sell_order_price * (1 +
                                                              self.exit_loss)
                # 随着持仓时间推移和波动率变大,对应亏损方向上的头寸的平仓价格上升,即空头平仓价格上升
                moving_loss_exit_price = sell_order_price * (
                    1 + self.exit_loss_soft_short
                ) - self.atr_value * self.atr_multiplier * self.position_hold

                if bar.close_price >= min(initial_loss_exit_price,
                                          moving_loss_exit_price):
                    self.cover(bar.close_price * 1.01, abs(self.pos))
                elif bar.close_price <= min(initial_profit_exit_price,
                                            moving_profit_exit_price):
                    self.cover(bar.close_price * 1.01, abs(self.pos))

        # 通过设置合成Bar Data的周期可以使得持仓过夜
        elif bar.datetime.time() > self.exit_time:
            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_15min_bar(self, bar: BarData):
        """"""
        self.am15.update_bar(bar)
        if not self.am15.inited:
            return
        self.rsi_value_l_window = self.am15.rsi(self.rsi_window)

    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
Exemplo n.º 19
0
class CincoStrategyHN(CtaTemplate):
    """"""

    author = "Huang Ning"

    boll_window = 42
    boll_dev = 2.0
    trailing_long = 0.65
    trailing_short = 0.7
    atr_window = 10
    risk_level = 100

    boll_up = 0
    boll_down = 0
    trading_size = 0
    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0
    atr_value = 0

    parameters = [
        "boll_window", "boll_dev", "trailing_long", "trailing_short",
        "atr_window", "risk_level"
    ]

    variables = [
        "boll_up", "boll_down", "trading_size", "intra_trade_high",
        "intra_trade_low", "long_stop", "short_stop", "atr_value"
    ]

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

        self.bg = BarGenerator(self.on_bar, 15, self.on_15min_bar)
        self.am = ArrayManager()

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

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

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

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

    def on_bar(self, bar: BarData):
        """"""
        self.bg.update_bar(bar)

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

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

        self.boll_up, self.boll_down = self.am.boll(self.boll_window,
                                                    self.boll_dev)
        boll_width = self.boll_up - self.boll_down

        if not self.pos:
            self.atr_value = self.am.atr(self.atr_window)
            self.trading_size = int(self.risk_level / self.atr_value)

            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price
            self.long_stop = 0
            self.short_stop = 0

            self.buy(self.boll_up, self.trading_size, stop=True)
            self.short(self.boll_down, self.trading_size, stop=True)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.long_stop = self.intra_trade_high - self.trailing_long * boll_width
            self.sell(self.long_stop, abs(self.pos), stop=True)

        else:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.short_stop = self.intra_trade_low + self.trailing_short * boll_width
            self.cover(self.short_stop, abs(self.pos), stop=True)

        self.put_event()

    def on_order(self, order: OrderData):
        """"""

    def on_trade(self, trade: TradeData):
        """"""
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """"""
        self.put_event()
Exemplo n.º 20
0
class OscillatorDriveStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    boll_window = 41
    boll_dev = 2
    atr_window = 15
    trading_size = 1
    risk_level = 50
    sl_multiplier = 2.1
    dis_open = 5
    interval = 25

    boll_up = 0
    boll_down = 0
    cci_value = 0
    atr_value = 0
    long_stop = 0
    short_stop = 0

    exit_up = 0
    exit_down = 0

    parameters = [
        "boll_window", "boll_dev", "dis_open", "interval", "atr_window",
        "sl_multiplier"
    ]
    variables = [
        "boll_up", "boll_down", "atr_value", "intra_trade_high",
        "intra_trade_low", "long_stop", "short_stop"
    ]

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

        self.bg = BarGenerator(self.on_bar, self.interval, self.on_xmin_bar)
        self.am = ArrayManager()

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

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

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

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

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

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

        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.ultosc = am.ultosc()
        buy_dis = 50 + self.dis_open
        sell_dis = 50 - self.dis_open
        self.atr_value = am.atr(self.atr_window)

        if self.pos == 0:
            self.trading_size = max(int(self.risk_level / self.atr_value), 1)
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            if self.ultosc > buy_dis:
                self.buy(self.boll_up, self.trading_size, True)
            elif self.ultosc < sell_dis:
                self.short(self.boll_down, self.trading_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 Boll_kk_vix_simple_Strategy(CtaTemplate):
    """
    本策略为反向策略,币本位  Reverse 反向
    """

    author = "yunya"

    open_window = 5
    xminute_window = 15
    com_length = 450
    exit_dc_length = 10
    fast_sma_length = 45
    slow_sma_length = 110
    cci_length = 30
    cci_exit = 26
    sl_multiplier = 8.0
    fixed_size = 1

    bollkk_ema = 0
    bollkk_up = 0
    bollkk_down = 0
    bollkk_width = 0
    cci_vlue = 0
    long_stop = 0
    short_stop = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0
    long_entry = 0
    short_entry = 0
    ma_trend = 0
    exit_dc_long = 0
    exit_dc_short = 0
    intra_trade_high = 0
    intra_trade_low = 0

    parameters = [
        "open_window",
        "xminute_window",
        "com_length",
        "fast_sma_length",
        "slow_sma_length",
        "cci_length",
        "cci_exit",
        "exit_dc_length",
        "sl_multiplier",
        "fixed_size",
    ]

    variables = [
        "bollkk_ema",
        "bollkk_up",
        "bollkk_down",
        "bollkk_width",
        "cci_vlue",
        "long_stop",
        "short_stop",
        "exit_up",
        "exit_down",
        "atr_value",
        "long_entry",
        "short_entry",
        "ma_trend",
    ]

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

        self.bg_xminute = BarGenerator(on_bar=self.on_bar,
                                       window=self.xminute_window,
                                       on_window_bar=self.on_xminute_bar,
                                       interval=Interval.MINUTE)
        self.am_xminute = ArrayManager(self.com_length + 10)
        self.bg = BarGenerator(self.on_bar, self.open_window, self.on_open_bar)
        self.am = ArrayManager()

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

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

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

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

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

    def on_open_bar(self, bar: BarData):
        """
        :param bar:
        :return:
        """
        # 先使用挂单全撤的粗化订单管理
        self.cancel_all()

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

        if self.pos == 0:
            # 根据布林带宽度动态调整仓位大小
            # self.trading_size = max(int(self.risk_level / self.xminute_com_width), 1)
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price
            if self.cci_value > self.cci_exit and self.ma_trend > 0:
                self.buy(self.bollkk_up, self.fixed_size, True)

            elif self.cci_value < -self.cci_exit and self.ma_trend < 0:
                self.short(self.bollkk_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

            exit_long_stop = self.intra_trade_high - self.bollkk_width * self.sl_multiplier
            exit_long_dc = max(exit_long_stop, self.exit_dc_long)
            self.exit_up = max(exit_long_dc, self.long_stop)
            self.sell(self.exit_up, 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)

            exit_short_stop = self.intra_trade_low + self.bollkk_width * self.sl_multiplier
            exit_shout_dc = min(exit_short_stop, self.exit_dc_short)
            self.exit_down = min(exit_shout_dc, self.short_stop)
            self.cover(self.exit_down, abs(self.pos), True)

        self.put_event()
        self.sync_data()

    def on_xminute_bar(self, bar: BarData):
        """
        :param bar:
        :return:
        """
        # x分钟 多策略合合成的通道线
        self.am_xminute.update_bar(bar)

        if not self.am_xminute.inited:
            return

        bollkk_ema_value, self.bollkk_up, self.bollkk_down, = self.boll_kk_combination(
            high=self.am_xminute.high[:-1],
            close=self.am_xminute.close[:-1],
            low=self.am_xminute.low[:-1],
            com_length=self.com_length)

        # 计算开平信号
        self.current_close = self.am_xminute.close[-1]
        self.last_close = self.am_xminute.close[-2]
        self.bollkk_ema = bollkk_ema_value[-1]

        self.bollkk_width = abs(self.bollkk_up - self.bollkk_down)

        self.cci_value = self.am_xminute.cci(self.cci_length)

        self.fast_ma = self.am_xminute.sma(self.fast_sma_length)
        self.slow_ma = self.am_xminute.sma(self.slow_sma_length)

        if self.fast_ma > self.slow_ma:
            self.ma_trend = 1
        else:
            self.ma_trend = -1
        self.atr_value = self.am_xminute.atr(30)
        self.exit_dc_short, self.exit_dc_long = self.am_xminute.donchian(
            self.exit_dc_length)
        self.sync_data()
        self.put_event()

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

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

        self.sync_data()

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

    def boll_kk_combination(self, high, close, low, com_length):
        """
        通过计算收盘价与收盘价均线之间的倍数,来自动调整boll 、kk 的通过宽度
        """

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

        # 计算自适布林带
        boll_std = talib.STDDEV(close, com_length)
        boll_dev = abs(close - bollkk_ema) / boll_std

        boll_up = bollkk_ema + boll_dev * boll_std
        boll_down = bollkk_ema - boll_dev * boll_std

        # 计算自适肯特通道
        kk_atr = talib.ATR(high, low, close, com_length)
        kk_dev = abs(close - bollkk_ema) / kk_atr

        kk_up = bollkk_ema + kk_atr * kk_dev
        kk_down = bollkk_ema - kk_atr * kk_dev

        bollkk_up = max(boll_up[-1], kk_up[-1])
        bollkk_down = min(boll_down[-1], kk_down[-1])

        return bollkk_ema, bollkk_up, bollkk_down,
Exemplo n.º 22
0
class BollChannelStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

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

    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
Exemplo n.º 23
0
class GridStockCta_v1(CtaTemplate):
    """
    1、如果没有仓位,以当前价格买入一个单位
    2、获取最后一个成交 价格,计算出卖出价格和买入价格。
    3、然后价格高于卖出价,马上挂出miker卖单。
    """
    author = "yunya"

    grid_amount = 20  # 网格最大量
    grid_usdt_size = 20  # 首次使用多少USDT购买币
    grid_usdt_capital = 200  # 网格最多使用的资金量USDT
    grid_buy_price = 1.0  # 网格距离
    grid_sell_price = 1.0
    position_inited = False
    position_proportion = 1.0  # 每次加仓比例

    grid_count = 0
    cumulative_usdt_volume = 0
    buy_benchmark = 0
    sell_benchmark = 0

    buy_price = 0
    sell_price = 0
    buy_tick = 0
    short_tick = 0
    current_volume = 0
    sell_fixed_size = 0
    price_change = 0
    min_volume = 0
    len_tick_decimal = 0

    parameters = [
        "grid_amount",
        "grid_usdt_size",
        "grid_usdt_capital",
        "grid_buy_price",
        "grid_sell_price",
        "position_inited",
        "position_proportion",
    ]

    variables = [
        "grid_count", "buy_benchmark", "sell_benchmark", "grid_usdt_volume",
        "cumulative_usdt_volume", "position_inited"
    ]

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

        self.exchangematerial = ExchangeMaterial.OKEX_MATERIAL
        self.bg_open = BarGenerator(self.on_bar, 2, self.on_open_bar)
        self.am_open = ArrayManager()

        # 计算每次使用资金量
        self.cumulative_usdt_volume = 0
        self.target_pos = 0
        self.grid_usdt_volume = 0
        self.vt_orderids = []

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        contract = self.cta_engine.main_engine.get_contract(self.vt_symbol)
        self.min_volume = contract.min_volume
        self.len_tick_decimal = len(str(self.min_volume).split(".")[1])
        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("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg_open.update_tick(tick)
        self.buy_tick = tick.bid_price_1
        self.short_tick = tick.ask_price_1

    def on_bar(self, bar: BarData):
        """"""
        self.bg_open.update_bar(bar)

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

        self.am_open.update_bar(bar)

        if not self.am_open.inited:
            return

        #   判断是否动态加仓
        if self.position_inited:
            if self.position_proportion > 0 and self.grid_count > 0:
                self.grid_usdt_volume = self.grid_usdt_size * (
                    1 + (self.position_proportion / 100) * self.grid_count)
        else:
            self.grid_usdt_volume = self.grid_usdt_size
        self.current_volume = self.grid_usdt_volume / bar.close_price

        #   判断是否已有成交记录,如果没有成交记录,就买入第一单
        if not self.buy_benchmark and not self.sell_benchmark:

            # self.buy_price = bar.close_price - self.tick_price * self.pay_up
            vt_orderid = self.buy(self.buy_price, self.current_volume)

            self.vt_orderids.extend(vt_orderid)

            # 清空
            self.cumulative_usdt_volume = 0
            self.grid_count = 0
            self.current_volume = 0
        else:
            if bar.close_price < self.buy_benchmark:

                con1 = self.grid_count < self.grid_amount
                con2 = self.cumulative_usdt_volume < self.grid_usdt_capital

                if con1 or con2:
                    # 取四舍五入
                    self.current_volume = float(
                        format(self.current_volume,
                               f".{self.len_tick_decimal}f"))
                    vt_orderid = self.buy(self.buy_tick,
                                          self.current_volume,
                                          order_type=OrderType.MakerPostOnly)
                    self.vt_orderids.extend(vt_orderid)
                else:
                    self.write_log("达到最大仓位!停止加仓!")

            elif bar.close_price > self.sell_benchmark:

                # 判断 如果理论(不含手续费)self.pos 比交易所成交反馈回来的量小时,使用交易所反馈回来的量下单,同时把理论值设置为零
                if self.pos > self.current_volume * 1.2:
                    self.sell_fixed_size = self.current_volume
                else:
                    self.sell_fixed_size = self.pos

                vt_orderid = self.sell(self.sell_price,
                                       abs(self.sell_fixed_size),
                                       order_type=OrderType.MakerPostOnly)
                self.vt_orderids.extend(vt_orderid)

        self.put_event()

    def on_order(self, order: OrderData):
        """
        判断是否完全成交,如果成交获取成交数量,计数器加减
        移除成交、拒绝、撤单的订单号
        """
        if order.vt_orderid in self.vt_orderids:
            if order.status == Status.ALLTRADED:
                if order.direction == Direction.LONG:
                    self.target_pos = order.traded
                    self.grid_count += 1
                    self.cumulative_usdt_volume += self.grid_usdt_volume
                    # 买入时,实际得到币量为总买量减手续费
                    msg = f"开仓,成交量为:{self.target_pos}"
                    self.write_log(msg)
                    self.target_pos = 0
                else:
                    self.target_pos = -order.traded
                    self.grid_count -= 1
                    self.cumulative_usdt_volume -= self.grid_usdt_volume
                    msg = f"平仓,成交量为:{self.target_pos}"
                    self.write_log(msg)
                    self.target_pos = 0

            if not order.is_active():
                self.vt_orderids.remove(order.vt_orderid)
        self.sync_data()

    def on_trade(self, trade: TradeData):
        """
        获取交易价格做为基准线
        """
        if trade.direction == Direction.LONG:
            self.price_change = trade.price  # 成交最高价
            msg = f"开仓,成交价格为:{self.price_change}"
            self.write_log(msg)
        else:
            self.price_change = trade.price
            msg = f"平仓,成交价格为:{self.price_change}"
            self.write_log(msg)
        # 计算当前网格买入价格和卖出价格
        self.buy_benchmark = self.price_change * (1 -
                                                  self.grid_buy_price / 100)
        self.sell_benchmark = self.price_change * (1 +
                                                   self.grid_sell_price / 100)
        msg = f"下个网格加仓价格线为:{self.buy_benchmark},平仓位价格线为: {self.sell_benchmark}"
        self.write_log(msg)

        self.sync_data()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Exemplo n.º 24
0
class GridStockCtaStrategy(CtaTemplate):
    """
    策略逻辑:
    1、网格数量: 21  ,网格总限量资金: 3000
	2、网格操作区间: 10%
	3、网格跟踪指标 : 首次成交价格
	4、网格上限: 网格跟踪指标 * (1 + 网格操作区间)
	5、网格下限: 网格跟踪指标 * ( 1 - 网格操作区间)
	6、网格步进 :( 网格上限 - 网格下限 ) / 网格数量
	7、仓位单元 : 网格总限量 / 网格数量
	8、网格启动、停止开关:振幅超过百分比例,网格暂时停止,等待8小时后重新启动
    """
    author = "yunya"

    open_window = 2
    xminute_window = 5
    xhour_window = 1
    position_proportion = 1.0  # 每次加仓比例
    grid_amount = 20      # 网格最大量
    grid_usdt_size = 20          # 首次使用多少USDT购买币
    grid_usdt_capital = 200   # 网格最多使用的资金量USDT
    grid_buy_price = 1.0      # 网格距离
    grid_sell_price = 1.0
    pay_up = 2            # 偏移pricetick
    buy_callback = 0.5      # 买入回调幅度
    sell_callback = 0.5    # 卖出回调幅度
    grid_amplitude = 5.0    # 振幅超过比例停止策略8小时
    stop_time = 8         # 策略暂停时间

    price_change = 0      # 网格基准线(每次成交价)
    current_volume = 0   # 当前下单币的数量
    target_pos = 0
    buy_benchmark = 0
    sell_benchmark = 0
    buy_price = 0           # 买入成交价
    sell_price = 0          # 平仓成交价
    grid_usdt_volume = 0
    cumulative_usdt_volume = 0   # 累计使用金额
    grid_count = 0          # 网格次数
    intra_trade_high = 0    # 最高价
    trade_high = 0
    intra_trade_low = 0     # 最低价
    trade_low = 0
    amplitude = 0           # 振幅
    tick_price = 0
    time_stop = 0             # 计算得到的重新启动时间
    buy_fixed_size = 0
    sell_fixed_size = 0
    len_tick_decimal = 0        # 获取当前币种盘口最小下单量
    amplitude_inited = False  # 振幅标签
    first_time_inited = False   # 判断是否是首次启动,如果是首次启动,清空初始化数据
    min_volume = 0

    parameters = [
            "open_window",
            "xminute_window",
            "xhour_window",
            "position_proportion",
            "grid_amount",
            "grid_usdt_size",
            "grid_usdt_capital",
            "grid_buy_price",
            "grid_sell_price",
            "pay_up",
            "buy_callback",
            "sell_callback",
            "grid_amplitude",
            "stop_time",
    ]

    variables = [
            "price_change",
            "current_volume",
            "buy_benchmark",
            "sell_benchmark",
            "buy_price",
            "sell_price",
            "grid_usdt_volume",
            "cumulative_usdt_volume",
            "grid_count",
            "intra_trade_high",
            "trade_high",
            "intra_trade_low",
            "trade_low",
            "amplitude",
            "amplitude_inited",
            "first_time_inited",
            "min_volume"
    ]

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

        self.exchangematerial = ExchangeMaterial.OKEX_MATERIAL
        self.bg_open = BarGenerator(self.on_bar,self.open_window,self.on_open_bar)
        self.am_open = ArrayManager()

        self.bg_minute = BarGenerator(self.on_bar,self.xminute_window,self.on_mintue_bar)
        self.am_minute = ArrayManager()

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

        self.ACTIVE_STATUSES = set([Status.SUBMITTING, Status.NOTTRADED])
        # 计算每次使用资金量
        self.cumulative_usdt_volume = 0
        self.target_pos = 0
        self.grid_usdt_volume = 0
        self.amplitude = 0
        self.tick_price = 0
        self.engine_type = self.get_engine_type()  #测试还是实盘
        self.vt_orderids = []
        self.buy_vt_orderid = 0
        self.sell_vt_orderid = 0

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        contract = self.on_get_contract()
        self.min_volume = contract.min_volume
        self.len_tick_decimal = len(str(self.min_volume).split(".")[1])
        self.load_bar(5)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")
        if not self.first_time_inited:
            self.grid_count = 0
            self.current_volume = 0
            self.cumulative_usdt_volume = 0
            self.first_time_inited = True

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

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

    def on_bar(self, bar: BarData):
        """"""
        self.bg_open.update_bar(bar)
        self.bg_minute.update_bar(bar)
        self.bg_xhour.update_bar(bar)

    def on_open_bar(self, bar: BarData):
        """"""
        self.am_open.update_bar(bar)

        if not self.am_open.inited:
            return

        if self.buy_vt_orderid in self.vt_orderids:
            self.write_log(f"开多订单号:{self.buy_vt_orderid}" + "\n")

            get_order_orderid = self.on_get_order(self.buy_vt_orderid)
            self.write_log(f"查询挂单:{get_order_orderid}" + "\n")

            if get_order_orderid.status in self.ACTIVE_STATUSES:
                self.cancel_order(self.buy_vt_orderid)
                self.buy_vt_orderid = 0

        elif self.sell_vt_orderid in self.vt_orderids:
            self.write_log(f"平多订单号:{self.sell_vt_orderid}" + "\n")

            get_order_orderid = self.on_get_order(self.sell_vt_orderid)
            self.write_log(f"查询挂单:{get_order_orderid}" + "\n")

            if get_order_orderid.status in self.ACTIVE_STATUSES:
                self.cancel_order(self.sell_vt_orderid)
                self.sell_vt_orderid = 0

        # 判断 休眠时间
        if self.amplitude_inited:
            if bar.datetime > self.time_stop:
                self.amplitude_inited = False
            return

        # 根据网格次数加仓 , 根据USDT量和价格计算出可购买的币数量
        if self.position_proportion > 0 and self.grid_count > 0:
            self.grid_usdt_volume = self.grid_usdt_size * (1 + (self.position_proportion / 100) * self.grid_count)
        else:
            self.grid_usdt_volume = self.grid_usdt_size
        self.current_volume = self.grid_usdt_volume / bar.close_price

        if not self.pos or self.pos < self.min_volume:
            """
            1、如果空仓,以当前价格买入一份做为底仓
            2、总网格次数减一
            """
            self.buy_price = bar.close_price - self.tick_price * self.pay_up
            # 取四舍五入
            self.current_volume = float(format(self.current_volume, f".{self.len_tick_decimal}f"))
            USDT = bar.close_price * self.min_volume

            if self.current_volume < self.min_volume:
                msg = f"当前下单小于:{self.vt_symbol} 最小下单最,请重新设置最小下单量!最下小量为:{self.min_volume},需要约:{USDT}枚USDT"
                self.write_log(msg)
                return

            self.buy_vt_orderid = self.buy(self.buy_price, self.current_volume)
            # 把挂单信息添加到列表末尾
            self.vt_orderids.extend(self.buy_vt_orderid)

            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            # 清空
            self.cumulative_usdt_volume = 0
            self.grid_count = 0
            self.current_volume = 0

        else:
            if bar.close_price < self.buy_benchmark:
                """
                当前收盘价低于下个网格买入价格时,判断买入时机:
                1、价格在上次买入后,中间没有卖出的过程,
                2、
                """
                if self.cumulative_usdt_volume < self.grid_usdt_capital:
                    """
                    买在最低位
                    """
                    self.intra_trade_high = bar.high_price
                    self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
                    self.trade_low = self.intra_trade_low * (1 + self.buy_callback / 100)

                    if self.trade_low < self.buy_benchmark:
                        self.buy_price = self.trade_low
                    else:
                        self.buy_price = self.buy_benchmark
                    # 取四舍五入
                    self.current_volume = float(format(self.current_volume, f".{self.len_tick_decimal}f"))
                    self.buy_vt_orderid = self.buy(self.buy_price, self.current_volume)
                    self.vt_orderids.extend(self.buy_vt_orderid)

            elif bar.close_price > self.sell_benchmark:
                if self.pos > 0:
                    """
                    卖在最高位
                    """
                    self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
                    self.intra_trade_low = bar.low_price
                    self.trade_high = self.intra_trade_high * (1 - self.sell_callback / 100)

                    if self.trade_high > self.sell_benchmark:
                        self.sell_price = self.trade_high
                    else:
                        self.sell_price = self.sell_benchmark

                    # 判断 如果理论(不含手续费)self.pos 比交易所成交反馈回来的量小时,使用交易所反馈回来的量下单,同时把理论值设置为零
                    if self.pos > self.current_volume * 1.2:
                        self.sell_fixed_size = self.current_volume
                    else:
                        self.sell_fixed_size = self.pos

                    self.sell_vt_orderid = self.sell(self.sell_price, abs(self.sell_fixed_size))
                    self.vt_orderids.extend(self.sell_vt_orderid)

        # 更新图形界面
        self.put_event()

    def on_mintue_bar(self, bar: BarData):
        """
        :return:
        """
        self.am_minute.update_bar(bar)

        if not self.am_minute.inited:
            return
        # 计算振幅
        self.amplitude = (bar.high_price - bar.low_price) / bar.high_price

        # 如果振幅超过指定值,策略撤掉所有挂单,并且进入休眠状态
        if self.amplitude > self.grid_amplitude / 100:
            self.amplitude_inited = True
            self.time_stop = bar.datetime + datetime.timedelta(hours=self.stop_time)
            self.write_log(f"当前市场波动较大,"
                           f"振幅为:{self.amplitude},超过设置值,策略进入休眠,"
                           f"休眠到:{self.time_stop.strftime('%Y-%m-%d %H:%M:%S')}时重新启动策略")

    def on_xhour_bar(self, bar: BarData):
        """
        :return:
        """
        self.am_xhour.update_bar(bar)

        if not self.am_xhour.inited:
            return
        pass

    def on_order(self, order: OrderData):
        """
        判断是否完全成交,如果成交获取成交数量,计数器加减
        移除成交、拒绝、撤单的订单号
        """
        if order.vt_orderid in self.vt_orderids:
            if order.status == Status.ALLTRADED:
                if order.direction == Direction.LONG:
                    if self.buy_vt_orderid == order.vt_orderid:
                        self.target_pos = order.traded
                        self.grid_count += 1
                        self.cumulative_usdt_volume += self.grid_usdt_volume
                        # 买入时,实际得到币量为总买量减手续费
                        msg = f"开仓,成交量为:{self.target_pos}"
                        self.write_log(msg)
                        self.target_pos = 0
                        self.buy_vt_orderid = 0
                else:
                    if self.sell_vt_orderid == order.vt_orderid:
                        self.target_pos = -order.traded
                        self.grid_count -= 1
                        self.cumulative_usdt_volume -= self.grid_usdt_volume
                        msg = f"平仓,成交量为:{self.target_pos}"
                        self.write_log(msg)
                        self.target_pos = 0
                        self.sell_vt_orderid = 0
            if not order.is_active():
                self.vt_orderids.remove(order.vt_orderid)
        self.sync_data()

    def on_trade(self, trade: TradeData):
        """
        获取交易价格做为基准线
        """
        if trade.direction == Direction.LONG:
            self.price_change = trade.price  # 成交最高价
            msg = f"开仓,成交价格为:{self.price_change}"
            self.write_log(msg)
        else:
            self.price_change = trade.price
            msg = f"开仓,成交价格为:{self.price_change}"
            self.write_log(msg)
        # 计算当前网格买入价格和卖出价格
        self.buy_benchmark = self.price_change * (1 - self.grid_buy_price / 100)
        self.sell_benchmark = self.price_change * (1 + self.grid_sell_price / 100)
        msg = f"下个网格加仓价格线为:{self.buy_benchmark},平仓位价格线为: {self.sell_benchmark}"
        self.write_log(msg)

        self.sync_data()

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

    def on_get_contract(self):
        """
        :return:
        """
        return self.cta_engine.main_engine.get_contract(self.vt_symbol)

    def on_get_order(self,vt_orderid):
        """
        查询挂单数据
        :return:
        """
        return self.cta_engine.main_engine.get_order(vt_orderid)

    def on_get_trade(self,vt_orderid):
        """
        查询成交数据
        :return:
        """
        return self.cta_engine.main_engine.get_trade(vt_orderid)
Exemplo n.º 25
0
class KingKeltnerStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    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", "trailing_percent", "fixed_size"]
    variables = ["kk_up", "kk_down"]

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

        self.bg = BarGenerator(self.on_bar, 5, self.on_5min_bar)
        self.am = ArrayManager(50)
        self.long_vt_orderids = []
        self.short_vt_orderids = []
        self.vt_orderids = []

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        #if self.get_engine_type() == EngineType.LIVE:
        #self.fo = open("C:\Study\MyDiary\VNPY_TSMyo_Log\VNPY_Log.txt", "a")
        #self.write_log("开启本地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("策略停止")
        #if self.get_engine_type() == EngineType.LIVE and self.fo:
        #self.fo.close()

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

        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
            # oco单,二选一触发,同时挂上下轨突破的停止单,一个触发另一个立刻取消
            # 经常用于防止在bar中波动过大,上下轨同时触发
            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.
        """
        #if self.get_engine_type() == EngineType.LIVE and self.fo:
        #self.fo.write(str(datetime.now())+ '\t' + str(order)+'\n')

    # 配合实现OCO挂单
    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.cancel_all()
        self.put_event()
        #if self.get_engine_type() == EngineType.LIVE and self.fo:
        #self.fo.write(str(datetime.now())+ '\t' + str(trade)+'\n')

    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
Exemplo n.º 26
0
class KTrendStrategy(CtaTemplatePatch):
    '''
    简单快速趋势策略:
       开仓策略:采取模拟概率积分的方式,即 " 中长趋势线 + 短期趋势线 + 短期的日涨跌幅比例 + 日内分时高低差值" 组成
            a. 中长线趋 long_trend_ma(>=5d): 可以选择多条,采取“与“的方式,即所有选择线的趋势都是一致的,才认为趋势确定。
            b. 短期趋势 short_trend_ma(<=3d): 同中长线,可以选择多条,采取”与“的方式来确定。
            c. 短期涨跌幅比例(short_rate):只有当短期内涨跌幅超过一个比例,才认为短期确定,采用累加的方式,或最大值的方式。
            d. 概率积分:针对前面3个条件,可以进行概率假设取值,并进行累加出总的假设概率(<1.0),
               即 long_trend_ma *K_lt + short_trend_ma*K_st + short_rate*K_sr 。
            e. 日内分时高低差值(gap_rate): 当时开仓时,也不要追高/追低,要根据日内分时的最高值或最低值一定的差值才进行开仓。
            f. 开仓的数量以1手为限定
        止损策略:采取偏离开仓价格限额的方式或最大损失值的原则,即设定一定的限额,在开仓时都必须同时设置
            a. 设定固定的平仓的价格损失比例
            b. 转换为对应的价格,再加一定的滑点值,以促进及时成交;
        止赢策略:当赢利超过一定比例或固定价格偏离值时,即触发止赢策略,具体操作可复用止损策略。
        风控策略: 针对如下的风险要进行风险控制
            a. 针对行情巨大的波动,如果损失已经超过了限额,但没能成交,要能动态调整设定的价格,以便保证成交;
            b. 发送给交易所委托,跨立易日后,这些数据可能被清除,需要开盘时重新发起委托。
    '''
    # 策略作者
    author = "*****@*****.**"
    # 定义参数
    order_duo_kong = "D&K"  # 交易哪个方向向,D:只开多仓,K: 只开空仓,D&K:都可以开
    bar_data_minutes = 60  # 控制生成BAR DATA的分钟数
    long_trend_ma_num = 8  # 长线趋势线分别为5d, 10d, 20d, 40d, 80d,...., 为2表示选择5d,10d
    short_trend_ma_num = 8  # 短期趋势线别为2d, 3d. 为2表示选择1d, 2d.
    short_rate = 0.01  # 表示价格要涨跌幅要3%以上
    k_lt = 0.4  # 表示长线趋势在总的假设概率中占比为40%
    k_st = 0.4  # 表示短线趋势在总的假设概率中占比为40%
    K_sr = 0.2  # 表示短线波动幅度在总的假设概率中占比为20%
    duo_kong_probability_threshold = 0.55  # 表示只有总的概超过此值后方可进行开仓
    kai_probability_threshold = 0.7  # 表示只有总的概超过此值后方可进行开仓
    kai_ping_price_allowance = 10  # 为了即时达成交易,相对于在当前价的基础进行对应加减,以快速的进行成交

    gap_rate = 0.005  # 表示日内的开仓价格需要与日内最高或日内最低偏离1%

    ping_cang_rate = 0.01  # 移动止赢止损平仓的波动控制在+/-%左右
    kai_num_per_order = 1  # 每次交易的开平手数

    # 定义变量
    # 支持中长线趋势的移动均线
    # 支持短线趋势的移动均线

    # 当前交易日的最高、最低价格, 用于配合gap_rate的判断
    cur_day_hour = -1  # 当前交易日的小时数,用于在没有tick数据的判断当前的交易日
    cur_day_high_price = 0.0  # 当前交易日的最高价格
    cur_day_low_price = sys.float_info.max  # 当前交易日的最低价格
    trade_price = 0.0  # 持仓止赢的移动价格

    # 添加参数和变量名到对应的列表
    parameters = [
        "order_duo_kong", "bar_data_minutes", "long_trend_ma_num",
        "short_trend_ma_num", "short_rate", "k_lt", "k_st", "K_sr",
        "duo_kong_probability_threshold", "kai_probability_threshold",
        "kai_ping_price_allowance", "gap_rate", "kai_num_per_order",
        "ping_cang_rate"
    ]
    variables = [
        "trade_price", "cur_day_high_price", "cur_day_low_price",
        "cur_day_hour"
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        '''
        '''
        super(KTrendStrategy, self).__init__(cta_engine, strategy_name,
                                             vt_symbol, setting)
        # K线合成器:从Tick合成分钟K线用
        self.bg = BarGenerator(self.on_bar, self.bar_data_minutes,
                               self.on_window_bar, Interval.MINUTE)
        # 时间序列容器:计算技术指标用
        self.am = ArrayManager()

    def on_bar(self, bar: BarData):
        '''
        通过该函数收到新的1分钟K线推送
        '''
        #
        super().on_bar(bar)

        self.bg.update_bar(bar)

        #晚上8点夜盘前当前天,从夜盘开始算新的一天
        if ((self.cur_day_hour == -1)
                or ((self.cur_day_hour > 8 and self.cur_day_hour < 20)
                    and bar.datetime.hour > 20)):
            self.cur_day_high_price = 0.0
            self.cur_day_low_price = sys.float_info.max
        #获取当前交易日的最高价和最低价
        self.cur_day_hour = bar.datetime.hour
        self.cur_day_high_price = max(self.cur_day_high_price, bar.high_price)
        self.cur_day_low_price = min(self.cur_day_low_price, bar.low_price)

        #
        # if(self.pos != 0):
        #     # 平仓分析
        #     self.ping_cang_analyse_bar(bar)
        # Write Log
        if (datetime.datetime.now().minute % 5 == 0):
            now = time.strftime('%Y-%m-%d %H:%M:%S')
            msg = now + " 收到1分钟K线推送"
            self.write_log(msg)
            msg = "持仓数:" + str(self.pos) + " cur_day_hour:" + str(
                self.cur_day_hour) + " high price:" + str(
                    self.cur_day_high_price) + " low price:" + str(
                        self.cur_day_low_price)
            self.write_log(msg)

        # 同步变量到硬盘 sync_data data
        self.sync_data()
        self.put_event()

    def on_window_bar(self, bar: BarData):
        '''
        收到指定的WINDOW BAR数据
        '''
        self.write_log("收到指定Windows的BARDATA数据")
        #print(str(sys._getframe().f_lineno)+" on_bar_1d:")

        # 清空未成交委托:为了防止之前下的单子在上一个Window Bar没有成交,但是下一个Window Bar可能已经调整了价格,
        # 保证策略在当前这Window Bar开始时的整个状态是清晰和唯一的。
        self.cancel_all()

        am = self.am

        # 更新K线到时间序列容器中
        am.update_bar(bar)

        # 若缓存的K线数量尚不够计算技术指标,则直接返回
        if not am.inited:
            return

        if (self.pos == 0):
            # 开仓分析
            self.kai_cang_analyse(bar)
        #else:
        # 平仓分析
        #    self.ping_cang_analyse(bar)

        # 更新
        self.put_event()

        pass

    def trend_maker(self, ma_list):
        '''
        复用此函数来判断一组均线的走势, 头:DUO, 空:KONG, 非头空:NULL.
        '''
        trend_list = []  # 保存趋势判断,‘DUO’: 多头,'KONG': 空头, "NULL" : 非多非空

        for cur_lt in ma_list:
            #
            cur_lt_trend = []
            for i in range(len(cur_lt) - 1):
                if (not math.isnan(cur_lt[i])) and (not math.isnan(
                        cur_lt[i + 1])):
                    if (cur_lt[i + 1] > cur_lt[i]):
                        cur_lt_trend.append("DUO")
                    elif (cur_lt[i + 1] < cur_lt[i]):
                        cur_lt_trend.append("KONG")
                    else:
                        cur_lt_trend.append("NULL")

            duo_count = cur_lt_trend.count("DUO")
            kong_count = cur_lt_trend.count("KONG")
            null_count = cur_lt_trend.count("NULL")
            sub_count = duo_count + kong_count + null_count
            #print("[trend_maker]]cur_lt count - DUO: ", duo_count, "KONG: ", kong_count, "NULL: ", null_count)
            if ((duo_count) / sub_count > self.duo_kong_probability_threshold
                ):  # 多头方向的值大于一定的比例, 可认为是多头
                trend_list.append('DUO')
            elif (
                (kong_count) / sub_count > self.duo_kong_probability_threshold
            ):  # 空头方向的值大于一定的比例, 可认为是空头
                trend_list.append('KONG')
            else:
                trend_list.append('NULL')  # 否则认为是振荡

        return trend_list

    def kai_cang_order(self, buy_or_short, price):
        '''
        开仓操作,买多或卖空        
        '''
        if (buy_or_short):  # 开多仓
            self.write_log(" 开多仓")
            self.buy(price, self.kai_num_per_order)
            #print("[Kai Cang] Duo...")
        else:  # 开空仓
            self.write_log(" 开空仓")
            self.short(price, self.kai_num_per_order)
            #print("[Kai Cang] Kong...")

    def kai_cang_analyse(self, bar: BarData):
        '''
        是否开仓的策略分析, 整个策略的主要行为
        '''
        am = self.am

        # 计算各均线
        # 计算中长期均线
        lt_ma_10 = am.sma(10, array=True)
        lt_ma_20 = am.sma(20, array=True)
        lt_ma_30 = am.sma(30, array=True)
        lt_ma_40 = am.sma(40, array=True)
        lt_ma_50 = am.sma(50, array=True)
        lt_ma_60 = am.sma(60, array=True)
        lt_ma_70 = am.sma(70, array=True)
        lt_ma_80 = am.sma(80, array=True)
        lt_ma_90 = am.sma(90, array=True)
        # 计算短期均线
        st_ma_2 = am.sma(2, array=True)
        st_ma_3 = am.sma(3, array=True)
        st_ma_4 = am.sma(4, array=True)
        st_ma_5 = am.sma(5, array=True)
        st_ma_6 = am.sma(6, array=True)
        st_ma_7 = am.sma(7, array=True)
        st_ma_8 = am.sma(8, array=True)
        st_ma_9 = am.sma(9, array=True)

        # 中长线趋势判断
        #
        lt_list = [
            lt_ma_10, lt_ma_20, lt_ma_30, lt_ma_40, lt_ma_50, lt_ma_60,
            lt_ma_70, lt_ma_80, lt_ma_90
        ]
        lt_list = lt_list[0:self.long_trend_ma_num]  # 只关注部分中长期趋势
        #
        #print(str(sys._getframe().f_lineno)+" long_trend_ma_num:", len(lt_list))
        #
        lt_trend = self.trend_maker(lt_list)

        lt_probability = []  # 保存多,空,NULL的比例
        duo_count = lt_trend.count("DUO")
        kong_count = lt_trend.count("KONG")
        null_count = lt_trend.count("NULL")
        sub_count = duo_count + kong_count + null_count
        lt_probability.append(duo_count / sub_count)  # 分别计算多头所占的比例
        lt_probability.append(kong_count / sub_count)  # 分别计算空头所占的比例
        lt_probability.append(null_count / sub_count)  # 分别计算非多非空,NULL所占的比例
        #
        #print(str(sys._getframe().f_lineno)+" lt_probability Count:", duo_count, ", ", kong_count, ", ", null_count)
        #print(str(sys._getframe().f_lineno)+" lt_probability DUO:", lt_probability[0], ", ", lt_probability[1], ", ", lt_probability[2])

        # 短线趋势判断
        st_list = [
            st_ma_2, st_ma_3, st_ma_4, st_ma_5, st_ma_6, st_ma_7, st_ma_8,
            st_ma_9
        ]
        st_list = lt_list[0:self.short_trend_ma_num]  # 只关注部分短期趋势
        #
        #print(str(sys._getframe().f_lineno)+" short_trend_ma_num:", len(st_list))
        #
        st_trend = self.trend_maker(st_list)

        st_probability = []  # 保存多,空,NULL的比例
        duo_count = st_trend.count("DUO")
        kong_count = st_trend.count("KONG")
        null_count = st_trend.count("NULL")
        sub_count = duo_count + kong_count + null_count
        st_probability.append(duo_count / sub_count)  # 分别计算多头所占的比例
        st_probability.append(kong_count / sub_count)  # 分别计算空头所占的比例
        st_probability.append(null_count / sub_count)  # 分别计算非多非空,NULL所占的比例

        #print(str(sys._getframe().f_lineno)+" st_probability Count:", duo_count, ", ", kong_count, ", ", null_count)
        #print(str(sys._getframe().f_lineno)+" st_probability :", lt_probability[0], ", ", lt_probability[1], ", ", lt_probability[2])

        # 短期涨跌幅比例(short rate: sr_ma_rate)
        if (len(st_list) > 1):
            sr_ma_rate = (st_list[-1][-1] -
                          st_list[0][-1]) / st_list[0][-1]  # 累计涨跌值
        else:
            sr_ma_rate = (st_list[0][-1] - st_list[0][-2]) / st_list[0][-2]

        #print(str(sys._getframe().f_lineno)+" sr_ma_rate:", sr_ma_rate, ",short_rate:",self.short_rate)

        sr_ma_probability = sr_ma_rate / self.short_rate  # 保存幅度的比例
        duo_sr_probability = 0.0
        kong_sr_probability = 0.0

        if (sr_ma_probability > 0):
            if (sr_ma_probability >= 1.0):
                duo_sr_probability = 1.0
            else:
                duo_sr_probability = sr_ma_probability
        else:
            if (sr_ma_probability <= -1.0):
                kong_sr_probability = 1.0
            else:
                kong_sr_probability = abs(sr_ma_probability)

        #print(str(sys._getframe().f_lineno)+" sr_ma_probability:", sr_ma_probability)

        # 概率积分:针对前面3个条件,可以进行概率假设取值,并进行累加出总的假设概率
        total_duo_probability = 0.0
        total_kong_probability = 0.0

        total_duo_probability = self.k_lt * lt_probability[
            0] + self.k_st * st_probability[
                0] + self.K_sr * duo_sr_probability  # 多头的概率
        total_kong_probability = self.k_lt * lt_probability[
            1] + self.k_st * st_probability[
                1] + self.K_sr * kong_sr_probability  # 空头的概率

        #print("Probability - DUO: ", total_duo_probability, "KONG: ", total_kong_probability, " threshold:",self.kai_probability_threshold)

        if ((self.order_duo_kong.upper() == "D"
             or self.order_duo_kong.upper() == "D&K")
                and (total_duo_probability > self.kai_probability_threshold)):
            #认为是多头,要进行多头操作
            #print("DUO: high = ", self.cur_day_high_price, " close= ", bar.close_price, " Gap= ", self.gap_rate, " Rate= ",((self.cur_day_high_price - bar.close_price) /bar.close_price))
            if (((self.cur_day_high_price - bar.close_price) / bar.close_price)
                    >= self.gap_rate):
                price = bar.close_price + self.kai_ping_price_allowance
                self.kai_cang_order(True, price)
                #print("Kang DUO, price=",price)

        elif ((self.order_duo_kong.upper() == "K"
               or self.order_duo_kong.upper() == "D&K")
              and (total_kong_probability > self.kai_probability_threshold)):
            #认为是空头,要进行空头操作
            #print("KONG: low = ", self.cur_day_low_price, " close= ", bar.close_price, " Gap= ", self.gap_rate, " Rate= ",((self.cur_day_low_price - bar.close_price) /bar.close_price))

            if (((bar.close_price - self.cur_day_low_price) / bar.close_price)
                    >= self.gap_rate):
                price = bar.close_price - self.kai_ping_price_allowance
                self.kai_cang_order(False, price)
                #print("Kang KONG, price=",price)
        pass

    def ping_cang_analyse_bar(self, bar: BarData):
        if self.getWinPips() > 30:
            self.clearOrder()
        pass
Exemplo n.º 27
0
class DynamicBreakOut2Strategy(CtaTemplate):
    """基于布林通道的交易策略"""
    className = 'DynamicBreakOut2Strategy'
    author = u'ForwardCapital'

    # 策略参数
    lookBackDays = 20  #
    devDays = 30  # 计算标准差时间窗口
    initDays = 10  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量
    xMinBar = 15
    ATR_N = 2

    # 策略变量
    ATR = 0  # 布林带中轨
    entryUp = 0  # 开仓上轨
    entryDown = 0  # 开仓下轨
    exitUp = 0  # 平仓上轨
    exitDown = 0  # 平仓上轨

    shortEntry = 0
    longEntry = 0
    shortExit = 0
    longExit = 0

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

    minute = None
    timeFuncTurn = False

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

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

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

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

        # self.ctaEngine.eventEngine.register(EVENT_TIMER, self.onTimeFunc)

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

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

        self.put_event()

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

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

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

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

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

        if not self.am.inited:
            return

        # 只发平仓单,各指标已在bg.updateBar()函数内完成
        if self.pos > 0:
            self.longExit = self.exitUp
            self.sellOrderID = self.sell(self.longExit, self.fixedSize, True)

            # if not self.longExit:
            #     self.longExit = self.exitUp

            #     if self.sellOrderID:
            #         self.cancelOrder(self.sellOrderID)
            #     else:
            #         self.cancelAll()

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

        elif self.pos < 0:
            self.shortExit = self.exitDown
            self.coverOrderID = self.cover(self.shortExit, self.fixedSize,
                                           True)

            # if not self.shortExit:
            #     self.shortExit = self.exitDown
            #     if self.coverOrderID:
            #         self.cancelOrder(self.coverOrderID)
            #     else:
            #         self.cancelAll()

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

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

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

        # 计算指标数值
        volatilityArray = talib.STDDEV(self.am.close, timeperiod=self.devDays)
        self.lookBackDays = int(
            round(volatilityArray[-1] / volatilityArray[-2] *
                  self.lookBackDays))
        self.lookBackDays = min(self.lookBackDays, 55)
        self.lookBackDays = max(self.lookBackDays, 20)
        bBands = talib.BBANDS(self.am.close, timeperiod=self.lookBackDays)
        self.ATR = talib.ATR(self.am.high, self.am.low, self.am.close,
                             self.lookBackDays)[-1]
        MidLine = bBands[1][-1]
        UpBand = bBands[0][-1]
        DnBand = bBands[2][-1]

        self.entryUp = max(max(self.am.high[-self.lookBackDays:]), UpBand)
        self.entryDown = min(min(self.am.low[-self.lookBackDays:]), DnBand)
        self.exitUp = max(MidLine, self.entryUp - self.ATR_N * self.ATR)
        self.exitDown = min(MidLine, self.entryDown + self.ATR_N * self.ATR)
        print(self.entryUp, self.entryDown)
        print(self.exitUp, self.exitDown)
        # 判断是否进行交易,只发开仓单
        if not self.buyOrderID or self.buyOrderID in self.orderList:
            if self.pos == 0:
                if not self.longEntry:
                    # if (self.entryUp-self.entryDown)/self.entryUp < 0.006:
                    #     print u'%s 高低点太窄,放弃交易!' % self.vtSymbol
                    #     return
                    self.longEntry = self.entryUp

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

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

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

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

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

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

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

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

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

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

        # if self.sellOrderID:
        #     if order.orderID == self.sellOrderID.split('.')[1]:
        #         if order.status == STATUS_CANCELLED:
        #             self.sellOrderID =  self.sell(self.longExit, self.fixedSize, False)
        #             print u'###多头平仓,单号:%s' % self.sellOrderID
        #             self.sellOrderID = self.orderIDConvert(self.sellOrderID)
        # if self.coverOrderID:
        #     if order.orderID == self.coverOrderID.split('.')[1]:
        #         if order.status == STATUS_CANCELLED:
        #             self.coverOrderID =  self.cover(self.shortExit, self.fixedSize, False)
        #             print u'###空头平仓,单号:%s' % self.coverOrderID
        #             self.coverOrderID = self.orderIDConvert(self.coverOrderID)
        if order.offset in [
                Offset.CLOSE, Offset.CLOSETODAY, Offset.CLOSEYESTERDAY
        ]:
            if order.status == Status.ALLTRADED:
                self.buyOrderID = None
                self.shortOrderID = None
                self.longExit = 0
                self.shortExit = 0

        pass

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

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

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

    #----------------------------------------------------------------------
    def on_stop_order(self, so):
        """停止单推送"""
        if so.offset == Offset.OPEN:
            if so.status == StopOrderStatus.CANCELLED or so.status == StopOrderStatus.TRIGGERED:
                self.orderList.remove(so.stopOrderID)

        # if so.offset in [OFFSET_CLOSE, OFFSET_CLOSETODAY, OFFSET_CLOSEYESTERDAY]:
        #     if self.sellOrderID:
        #         if so.orderID == self.sellOrderID.split('.')[1]:
        #             if so.status == STATUS_CANCELLED:
        #                 self.sellOrderID =  self.sell(self.longExit, self.fixedSize, True)
        #                 print u'###多头平仓,单号:%s' % self.sellOrderID
        #                 self.sellOrderID = self.orderIDConvert(self.sellOrderID)
        #     if self.coverOrderID:
        #         if so.orderID == self.coverOrderID.split('.')[1]:
        #             if so.status == STATUS_CANCELLED:
        #                 self.coverOrderID =  self.cover(self.shortExit, self.fixedSize, True)
        #                 print u'###空头平仓,单号:%s' % self.coverOrderID
        #                 self.coverOrderID = self.orderIDConvert(self.coverOrderID)
        pass

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

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

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

        elif now_hour == 15 and now_minute == 10 and self.timeFuncTurn:
            self.buyOrderID = None
            self.shortOrderID = None
            self.coverOrderID = None
            self.sellOrderID = None
            self.longExit = 0
            self.shortExit = 0
            self.orderList = []
            self.cta_engine.saveSyncData(self)
            self.timeFuncTurn = False
Exemplo n.º 28
0
class OrderDemoStrategy(CtaTemplate):
    """"""
    author = "用Python的交易员"

    boll_window = 18
    boll_dev = 3.4
    fixed_size = 1
    atr_window = 20
    atr_multiplier = 2

    boll_up = 0
    boll_down = 0
    boll_mid = 0

    atr_value = 0
    intra_trade_high = 0
    long_sl = 0
    intra_trade_low = 0
    short_sl = 0

    long_entry = 0
    short_entry = 0

    parameters = [
        "boll_window", "boll_dev", "fixed_size", "atr_window", "atr_multiplier"
    ]
    variables = [
        "boll_up", "boll_down", "boll_mid", "atr_value", "intra_trade_high",
        "long_sl", "intra_trade_low", "short_sl"
    ]

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

        self.bg = BarGenerator(self.on_bar, 15, self.on_15min_bar)
        self.am = ArrayManager()

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

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

    def on_init(self):
        """
        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):
        """"""
        # 生成交易信号
        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.boll_mid = am.sma(self.boll_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

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

        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_sl = self.intra_trade_high - self.atr_value * self.atr_multiplier
            self.long_sl = max(self.boll_mid, self.long_sl)

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

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

            self.short_sl = self.intra_trade_low + self.atr_value * self.atr_multiplier
            self.short_sl = min(self.boll_mid, self.short_sl)

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

        # 根据信号执行挂撤交易
        if self.pos == 0:
            # 检查之前委托都已经结束
            if not self.buy_vt_orderids:
                # 检查存在信号
                if self.buy_price:
                    self.buy_vt_orderids = self.buy(self.buy_price,
                                                    self.fixed_size, True)
                    self.buy_price = 0  # 执行需要清空信号
            else:
                # 遍历委托号列表撤单
                for vt_orderid in self.buy_vt_orderids:
                    self.cancel_order(vt_orderid)

            if not self.short_vt_orderids:
                if self.short_price:
                    self.short_vt_orderids = self.short(
                        self.short_price, self.fixed_size, True)
                    self.short_price = 0
            else:
                for vt_orderid in self.short_vt_orderids:
                    self.cancel_order(vt_orderid)
        elif self.pos > 0:
            if not self.sell_vt_orderids:
                if self.sell_price:
                    self.sell_vt_orderids = self.sell(self.sell_price,
                                                      abs(self.pos), True)
                    self.sell_price = 0
            else:
                for vt_orderid in self.sell_vt_orderids:
                    self.cancel_order(vt_orderid)
        else:
            if not self.cover_vt_orderids:
                if self.cover_price:
                    self.cover_vt_orderids = self.cover(
                        self.cover_price, abs(self.pos), True)
                    self.cover_price = 0
            else:
                for vt_orderid in self.cover_vt_orderids:
                    self.cancel_order(vt_orderid)

        # Update UI
        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.
        """
        # 如果发出的是停止单,委托状态的回调只能写在on_stop_order下
        # 只处理撤销或者触发的停止单委托
        if stop_order.status == StopOrderStatus.WAITING:
            return

        # 移除已经结束的停止单委托号
        for buf_orderids in [
                self.buy_vt_orderids, self.sell_vt_orderids,
                self.short_vt_orderids, self.cover_vt_orderids
        ]:
            if stop_order.stop_orderid in buf_orderids:
                buf_orderids.remove(stop_order.stop_orderid)

        # 发出新的委托
        if self.pos == 0:
            if not self.buy_vt_orderids:
                if self.buy_price:
                    self.buy_vt_orderids = self.buy(self.buy_price,
                                                    self.fixed_size, True)
                    self.buy_price = 0

            if not self.short_vt_orderids:
                if self.short_price:
                    self.short_vt_orderids = self.short(
                        self.short_price, self.fixed_size, True)
                    self.short_price = 0

        elif self.pos > 0:
            if not self.sell_vt_orderids:
                if self.sell_price:
                    self.sell_vt_orderids = self.sell(self.sell_price,
                                                      abs(self.pos), True)
                    self.sell_price = 0

        else:
            if not self.cover_vt_orderids:
                if self.cover_price:
                    self.cover_vt_orderids = self.cover(
                        self.cover_price, abs(self.pos), True)
                    self.cover_price = 0
Exemplo n.º 29
0
class DoubleMaStrategy(CtaTemplate):
    author = "用Python的交易员"

    fast_window = 10
    slow_window = 20

    fast_ma0 = 0.0
    fast_ma1 = 0.0

    slow_ma0 = 0.0
    slow_ma1 = 0.0

    period = 15

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

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

        self.bg = BarGenerator(self.on_bar, self.period, self.on_bar_period)
        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.
        """
        self.bg.update_bar(bar)

    def on_bar_period(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(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:
            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
Exemplo n.º 30
0
class BollingerBotAG2002Strategy(CtaInvestmentTemplate):
    """基于布林通道的交易策略"""
    author = u'tonywang_efun'

    # 策略参数
    initDays = 20  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量

    fixWinPrcnt = 2.4  # 固定止盈

    # (多头参数)
    bollLength = 43  # 通道窗口数
    entryDev = 3.0  # 开仓偏差
    exitDev = 1.2  # 平仓偏差
    trailingPrcnt = 1.2  # 移动止损百分比
    maLength = 18  # 过滤用均线窗口

    # (空头参数)
    shortBollLength = 28  # 通道窗口数
    shortEntryDev = 3.6  # 开仓偏差
    shortExitDev = 2.0  # 平仓偏差
    shortTrailingPrcnt = 0.6  # 移动止损百分比
    shortMaLength = 47  # 过滤用均线窗口

    # 公共策略变量
    posPrice = 0  # 持仓价

    # 策略变量(多头)
    entryLine = 0  # 开仓上轨
    exitLine = 0  # 平仓上轨
    maFilter = 0  # 均线过滤
    maFilterPrevious = 0  # 上一期均线
    intraTradeHigh = 0  # 持仓期内的最高点
    longEntry = 0  # 多头开仓
    longExit = 0  # 多头平仓

    # 策略变量(空头)
    shortEntryLine = 0  # 开仓上轨
    shortExitLine = 0  # 平仓上轨
    shortMaFilter = 0  # 均线过滤
    shortMaFilterPrevious = 0  # 上一期均线
    intraTradeLow = 0  # 持仓期内的最最低点
    shortEntry = 0  # 空头开仓
    shortExit = 0  # 空头平仓

    # 参数列表,保存了参数的名称
    parameters = [
        'initDays', 'fixedSize', 'fixWinPrcnt', 'bollLength', 'entryDev',
        'exitDev', 'trailingPrcnt', 'maLength', 'shortBollLength',
        'shortEntryDev', 'shortExitDev', 'shortTrailingPrcnt', 'shortMaLength'
    ]

    # 变量列表,保存了变量的名称
    variables = [
        'entryLine', 'exitLine', 'shortEntryLine', 'shortExitLine', 'posPrice',
        'longEntry', 'longExit', 'shortEntry', 'shortExit'
    ]

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

        self.bg = BarGenerator(self.on_bar, 15, self.on_xmin_bar)
        self.am = ArrayManager(100)

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

    # ----------------------------------------------------------------------
    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.
        """
        self.bg.update_bar(bar)

    def on_xmin_bar(self, bar: BarData):
        """收到x分钟K线"""
        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        self.cancel_all()

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

        # 计算多头指标数值
        self.entryLine, self.exitLine = am.boll_double_up(
            self.bollLength, self.entryDev, self.exitDev)
        ma_array = am.sma(self.maLength, True)
        self.maFilter = ma_array[-1]
        self.maFilterPrevious = ma_array[-2]

        # 计算空头指标数值
        self.shortEntryLine, self.shortExitLine = am.boll_double_down(
            self.shortBollLength, self.shortEntryDev, self.shortExitDev)
        short_ma_array = am.sma(self.shortMaLength, True)
        self.shortMaFilter = short_ma_array[-1]
        self.shortMaFilterPrevious = short_ma_array[-2]

        # 当前无仓位,发送OCO开仓委托
        if self.pos == 0:
            self.intraTradeHigh = bar.high_price
            self.intraTradeLow = bar.low_price

            if bar.close_price > self.maFilter > self.maFilterPrevious:
                self.longEntry = self.entryLine
                self.buy(self.longEntry, self.fixedSize, True)
            elif bar.close_price < self.shortMaFilter < self.shortMaFilterPrevious:
                self.shortEntry = self.shortEntryLine
                self.short(self.shortEntry, self.fixedSize, True)

        # 持有多头仓位
        elif self.pos > 0:
            if bar.close_price > self.posPrice \
                    and (bar.close_price - self.posPrice) / self.posPrice > (self.fixWinPrcnt / 100):
                print("fix sell-------------------------------")
                self.sell(bar.close_price * 0.99, abs(self.pos))
            else:
                self.intraTradeHigh = max(self.intraTradeHigh, bar.high_price)
                self.longExit = self.intraTradeHigh * (
                    1 - self.trailingPrcnt / 100)
                self.longExit = min(self.longExit, self.exitLine)

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

        # 持有空头仓位
        elif self.pos < 0:
            self.intraTradeLow = min(self.intraTradeLow, bar.low_price)
            self.shortExit = self.intraTradeLow * (
                1 + self.shortTrailingPrcnt / 100)
            self.shortExit = max(self.shortExit, self.shortExitLine)

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

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

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

    # ----------------------------------------------------------------------
    def on_trade(self, trade: TradeData):
        # 记录交易数据并分析投资情况
        self.record_trade(trade, "BollingerBot", True)

        self.posPrice = trade.price
        self.put_event()

    # ----------------------------------------------------------------------
    def on_stop_order(self, so):
        """停止单推送"""
        pass
Exemplo n.º 31
0
class BollChannelStrategy(CtaTemplate):
    """"""

    author = '用Python的交易员'

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

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

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

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

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

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

        self.bg = BarGenerator(self.on_bar,
                               self.xminute_window,
                               self.on_xminute_bar,
                               interval=Interval.MINUTE)
        self.am = ArrayManager(self.long_length + 100)

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

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

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

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

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

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

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

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

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

        short_mdeium_array = short_ema - mdeium_ema
        mdeium__long_array = mdeium_ema - long_ema

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

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

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

        if con1 and con2:
            self.ema_initde = 1

        elif con3 and con4:
            self.ema_initde = -1

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

            # if self.atr_value == 0:
            #     return
            # # 反向合约的计算方法,
            # atr_risk = talib.ATR(
            #     1 / self.am.high,
            #     1 / self.am.low,
            #     1 / self.am.close,
            #     self.atr_window
            # )[-1]
            # self.trading_size = max(int(self.risk_level / atr_risk), 1)

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

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

            elif self.ema_initde < 0:
                self.short(self.entry_down, self.trading_size, True)

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

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

        self.put_event()

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

        self.sync_data()

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

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

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

        elif self.exchange == Exchange.OKEX:
            self.load_bar(days=days, use_database=True)
            self.write_log(f"{self.exchange}交易所,从本地获取{days}数据初始化!")
        else:
            self.load_bar(days=days)
            self.write_log(f"{self.exchange}交易所,从交易获取{days}数据初始化!")
Exemplo n.º 33
0
class MultiTimeframeStrategy(CtaTemplate):
    """"""
    author = '用Python的交易员'

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

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

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

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

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

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

        self.bg5 = BarGenerator(self.on_bar, 5, self.on_5min_bar)
        self.am5 = ArrayManager()

        self.bg15 = BarGenerator(self.on_bar, 15, self.on_15min_bar)
        self.am15 = ArrayManager()

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

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

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

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

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

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

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

        if not self.ma_trend:
            return

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

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

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

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

        self.put_event()

    def on_15min_bar(self, bar: BarData):
        """"""
        self.am15.update_bar(bar)
        if not self.am15.inited:
            return

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

        if self.fast_ma > self.slow_ma:
            self.ma_trend = 1
        else:
            self.ma_trend = -1

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

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

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
Exemplo n.º 34
0
class DoubleSignalGenerator(CtaTemplate):
    """"""
    author = "yiran"

    atr_window = 20
    obv_window = 10
    minus_dm_window = 10
    mfi_window = 20
    ad_window = 20
    adosc_window = 20
    plus_dm_window = 20
    dx_window = 20
    adx_window = 20

    s_window = 5
    l_window = 15
    atr_multiplier = 0.05
    rsi_window = 11
    long_threshold_l_window = 50
    long_threshold_s_window = 80
    exit_return = 0.02
    exit_loss = 0.02
    exit_return_soft_long = -0.1
    exit_loss_soft_long = -0.2
    exit_return_soft_short = 0.2
    exit_loss_soft_short = 0.1

    fixed_size = 1

    start_time = time(hour=10)
    exit_time = time(hour=14, minute=55)

    long_order_record = []
    short_order_record = []

    rsi_value_l_window = -9999
    rsi_value_s_window = -9999
    atr_value = 0
    minus_dm_value = 0
    obv_value = 0
    mfi_value = 0
    ad_value = 0
    adosc_value = 0
    plus_dm_value = 0
    dx_value = 0
    adx_value = 0

    position_hold = 0
    long_entered = False
    short_entered = False

    parameters = []

    variables = []

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

        self.rsi_long_l = self.long_threshold_l_window
        self.rsi_long_s = self.long_threshold_s_window
        self.rsi_short_l = 100 - self.long_threshold_l_window
        self.rsi_short_s = 100 - self.long_threshold_s_window

        self.bg5 = BarGenerator(self.on_bar, self.s_window, self.on_5min_bar)
        self.am5 = ArrayManager()

        self.bg15 = BarGenerator(self.on_bar, self.l_window, self.on_15min_bar)
        self.am15 = ArrayManager()
        self.long_order_record = []
        self.short_order_record = []
        # 指标计算容器
        self.rsi_value_recorder_l_window = []
        self.rsi_time_recorder_l_window = []
        self.rsi_value_recorder_s_window = []
        self.rsi_time_recorder_s_window = []
        self.atr_time_recorder = []
        self.atr_value_recorder = []
        self.obv_time_recorder = []
        self.obv_value_recorder = []
        self.minus_dm_time_recorder = []
        self.minus_dm_value_recorder = []
        self.mfi_time_recorder = []
        self.mfi_value_recorder = []
        self.ad_time_recorder = []
        self.ad_value_recorder = []
        self.adosc_time_recorder = []
        self.adosc_value_recorder = []
        self.plus_dm_time_recorder = []
        self.plus_dm_value_recorder = []
        self.dx_time_recorder = []
        self.dx_value_recorder = []
        self.adx_time_recorder = []
        self.adx_value_recorder = []

    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

        self.rsi_value_s_window = self.am5.rsi(self.rsi_window)
        self.atr_value = self.am5.atr(self.atr_window)
        self.obv_value = self.am5.obv(self.obv_window)
        self.minus_dm_value = self.am5.minus_dm(self.minus_dm_window)
        self.mfi_value = self.am5.mfi(self.mfi_window)
        self.ad_value = self.am5.ad(self.ad_window)
        self.adosc_value = self.am5.adosc(self.adosc_window)
        self.plus_dm_value = self.am5.adosc(self.plus_dm_window)
        self.dx_value = self.am5.adosc(self.dx_window)
        self.adx_value = self.am5.adosc(self.adx_window)

        self.rsi_time_recorder_s_window.append(bar.datetime)
        self.rsi_value_recorder_s_window.append(self.rsi_value_s_window)

        self.atr_time_recorder.append(bar.datetime)
        self.atr_value_recorder.append(self.atr_value)

        self.obv_time_recorder.append(bar.datetime)
        self.obv_value_recorder.append(self.obv_value)

        self.minus_dm_time_recorder.append(bar.datetime)
        self.minus_dm_value_recorder.append(self.minus_dm_value)

        self.mfi_time_recorder.append(bar.datetime)
        self.mfi_value_recorder.append(self.mfi_value)

        self.ad_time_recorder.append(bar.datetime)
        self.ad_value_recorder.append(self.ad_value)

        self.adosc_time_recorder.append(bar.datetime)
        self.adosc_value_recorder.append(self.adosc_value)

        self.plus_dm_time_recorder.append(bar.datetime)
        self.plus_dm_value_recorder.append(self.plus_dm_value)

        self.dx_time_recorder.append(bar.datetime)
        self.dx_value_recorder.append(self.dx_value)

        self.adx_time_recorder.append(bar.datetime)
        self.adx_value_recorder.append(self.adx_value)

    def on_15min_bar(self, bar: BarData):
        """"""
        self.am15.update_bar(bar)
        if not self.am15.inited:
            return
        self.rsi_value_l_window = self.am15.rsi(self.rsi_window)
        self.rsi_time_recorder_l_window.append(bar.datetime)
        self.rsi_value_recorder_l_window.append(self.rsi_value_l_window)

    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