コード例 #1
0
ファイル: multi_signal_strategy.py プロジェクト: shhuiw/vnpy
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)
コード例 #2
0
ファイル: multi_signal_strategy.py プロジェクト: shhuiw/vnpy
class CciSignal(CtaSignal):
    """"""

    def __init__(self, cci_window: int, cci_level: float):
        """"""
        super(CciSignal, self).__init__()

        self.cci_window = cci_window
        self.cci_level = cci_level
        self.cci_long = self.cci_level
        self.cci_short = -self.cci_level

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

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

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

        cci_value = self.am.cci(self.cci_window)

        if cci_value >= self.cci_long:
            self.set_signal_pos(1)
        elif cci_value <= self.cci_short:
            self.set_signal_pos(-1)
        else:
            self.set_signal_pos(0)
コード例 #3
0
class BollingerBotJD2001Strategy(CtaInvestmentTemplate):
    """基于布林通道的交易策略"""
    author = u'tonywang_efun'

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

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

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

    # 策略变量(多头)
    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', 'bollLength', 'entryDev', 'exitDev',
        'trailingPrcnt', 'maLength', 'shortBollLength', 'shortEntryDev',
        'shortExitDev', 'shortTrailingPrcnt', 'shortMaLength'
    ]

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

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

        self.bg = BarGenerator(self.on_bar, 6, 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:
            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):
        # 记录交易数据并分析投资情况
        self.record_trade(trade, "BollingerBot", True)

        self.put_event()

    # ----------------------------------------------------------------------
    def on_stop_order(self, so):
        """停止单推送"""
        pass
コード例 #4
0
class OrmStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

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

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

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

    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.am = ArrayManager()

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

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

        self.load_bar(10)

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

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

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

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

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

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

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

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

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

            long_stop = self.intra_trade_high * \
                (1 - self.trailing_percent / 100)
            self.sell(long_stop, abs(self.pos), stop=True)

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

            short_stop = self.intra_trade_low * \
                (1 + self.trailing_percent / 100)
            self.cover(short_stop, abs(self.pos), stop=True)

        self.put_event()

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

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

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

    def sync_to_database(self):
        """"""
        if not self.trading:
            return

        variables = self.get_variables()
        save_strategy_data(self.strategy_name, variables)

    def sync_from_database(self):
        """"""
        variables = load_strategy_data(self.strategy_name)

        for key in self.variables:
            if key in variables:
                setattr(self, key, variables[key])
コード例 #5
0
ファイル: cincoHN1.py プロジェクト: hun1982qhu/CTA
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()
コード例 #6
0
class TurtleSignalStrategy(CtaTemplate):
    """"""
    author = "用Python的交易员"

    entry_window = 20
    exit_window = 10
    atr_window = 20
    fixed_size = 1

    entry_up = 0
    entry_down = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

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

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

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

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

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

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

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

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

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

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

        # Only calculates new entry channel when no position holding
        # 唐奇安通道上下轨,入场窗口
        if not self.pos:
            self.entry_up, self.entry_down = self.am.donchian(
                self.entry_window)
        # 出场窗口
        self.exit_up, self.exit_down = self.am.donchian(self.exit_window)

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

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

            # 自己独特的挂单(海龟有加仓规则)
            self.send_buy_orders(self.entry_up)
            self.send_short_orders(self.entry_down)
        elif self.pos > 0:
            self.send_buy_orders(self.entry_up)

            # 2ATR止损或者出场窗口期唐奇安通道突破
            sell_price = max(self.long_stop, self.exit_down)
            self.sell(sell_price, abs(self.pos), True)

        elif self.pos < 0:
            self.send_short_orders(self.entry_down)

            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.
        """
        # 成交后计算2ATR止损位置
        if trade.direction == Direction.LONG:
            self.long_entry = trade.price
            self.long_stop = self.long_entry - 2 * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + 2 * self.atr_value

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

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

    # 实现每0.5ATR加仓一个单位
    def send_buy_orders(self, price):
        """"""
        t = self.pos / self.fixed_size

        if t < 1:
            self.buy(price, self.fixed_size, True)

        if t < 2:
            self.buy(price + self.atr_value * 0.5, self.fixed_size, True)

        if t < 3:
            self.buy(price + self.atr_value, self.fixed_size, True)

        if t < 4:
            self.buy(price + self.atr_value * 1.5, self.fixed_size, True)

    def send_short_orders(self, price):
        """"""
        t = self.pos / self.fixed_size

        if t > -1:
            self.short(price, self.fixed_size, True)

        if t > -2:
            self.short(price - self.atr_value * 0.5, self.fixed_size, True)

        if t > -3:
            self.short(price - self.atr_value, self.fixed_size, True)

        if t > -4:
            self.short(price - self.atr_value * 1.5, self.fixed_size, True)
コード例 #7
0
ファイル: boll_channel_strategy.py プロジェクト: shhuiw/vnpy
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
コード例 #8
0
class DoubleMaExitMaReinStrategy(CtaTemplate):
    # 入场用快均线和慢均线交叉加过滤器(收盘价+atr),快均线一般固定为5,相当于使用单均线入场
    # 出场用满均线的.x系数的均线出场,出场后在反向信号触发前有n次重新入场的机会(通道入场)。
    author = "double_ma_exit_ma_rein"
    is_say_log = False

    fast_window = 20
    slow_window = 40
    atr_multi = 0.5
    mid_multi = 0.8
    max_rein = 1

    fast_ma0 = 0.0
    fast_ma1 = 0.0

    slow_ma0 = 0.0
    slow_ma1 = 0.0

    parameters = [
        "fast_window", "slow_window", "atr_multi", "mid_multi", "max_rein"
    ]
    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.am = ArrayManager(size=80)

        self.local_stop = True
        self.limit_up = 1.04
        self.limit_down = 0.96

        self.watch_long = False
        self.watch_short = False
        self.boll_up = 0
        self.boll_down = 0

        self.long_rein = False
        self.short_rein = False
        self.long_rein_count = 0
        self.short_rein_count = 0
        self.rein_highest = 0
        self.rein_lowest = 0

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

        # 回撤引擎,load_bar只有days(回溯交易日)和callback有作用,其他传入参数都没有作用。
        self.load_bar(80)

    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.
        """
        # 运行新bar之前,撤销之前的委托,否则容易各种异常
        self.cancel_all()

        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

        # 监测状态是持续性的,在状态未撤销之前且没有成交(没有仓位),每根bar都会发本地单
        if self.watch_long and self.pos == 0:
            self.buy(self.boll_up, 1, True)
            self.say_log("WatchLong:", bar.datetime, "boll_up:", self.boll_up)

        if self.watch_short and self.pos == 0:
            self.short(self.boll_down, 1, True)
            self.say_log("watchShort:", bar.datetime, "boll_down:",
                         self.boll_down)

        # 重新入场监测
        if self.long_rein and self.pos == 0:
            up, down = am.donchian(self.slow_window)
            # up = self.rein_highest
            self.buy(up, 1, True)
            self.say_log("ReinLong:", bar.datetime, "rein_up:", up,
                         "long_rein_count:", self.long_rein_count)

        if self.short_rein and self.pos == 0:
            up, down = am.donchian(self.slow_window)
            # down = self.rein_lowest
            self.short(down, 1, True)
            self.say_log("ReinShort:", bar.datetime, "rein_down:", down,
                         "short_rein_count:", self.short_rein_count)

        # 计算前高前低
        if self.pos == 0:
            if not self.long_rein and not self.short_rein:
                self.rein_highest = bar.high_price
                self.rein_lowest = bar.low_price

        # 快速出场条件
        if self.pos > 0:
            self.rein_highest = max(self.rein_highest, bar.high_price)

            mid_ma = am.sma(int(self.slow_window * self.mid_multi))
            self.sell(mid_ma, abs(self.pos), True)
            self.say_log("Close-Long-Ahead:", bar.datetime, 'mid_ma:', mid_ma)

        if self.pos < 0:
            self.rein_lowest = min(self.rein_lowest, bar.low_price)

            mid_ma = am.sma(int(self.slow_window * self.mid_multi))
            self.cover(mid_ma, abs(self.pos), True)
            self.say_log("Close-Short-Ahead:", bar.datetime, 'mid_ma:', mid_ma)

        # 交叉信号是一次性的,只在触发的bar运行,没成交的单在下一根bar计算之前会被撤销
        if cross_over:
            # 金叉,撤销做空监测单并取消做空监测
            # 撤销重新做空的监测
            self.cancel_all()
            self.watch_short = False
            self.short_rein = False
            self.short_rein_count = 0

            # 通道只在触发信号的时候计算,后续不再改变。
            atr_value = am.atr(self.slow_window) * self.atr_multi
            self.boll_up = bar.close_price + atr_value

            if self.pos == 0:
                # 立即发本地单,等待下一根撮合,同时开始监测做多
                self.buy(self.boll_up, 1, True)

                if self.trading:
                    self.watch_long = True

                self.say_log("Signal:", bar.datetime, "pos:", self.pos,
                             "close_up:", self.boll_up, "close:",
                             bar.close_price, "gloden-cross open", "trading:",
                             self.trading)

            elif self.pos < 0:
                # 有空头,碰到金叉后,先超价立即平仓
                # 反向单先发本地单,等待下一根bar一起撮合,并且开启做多监测
                self.cover(bar.close_price * self.limit_up, abs(self.pos),
                           False)
                self.buy(self.boll_up, 1, True)
                self.watch_long = True

                self.say_log("Signal:", bar.datetime, "pos:", self.pos,
                             "close_up:", self.boll_up, "close:",
                             bar.close_price, "gloden-cross close and open")

        elif cross_below:
            self.cancel_all()
            self.watch_long = False
            self.long_rein = False
            self.long_rein_count = 0

            atr_value = am.atr(self.slow_window) * self.atr_multi
            self.boll_down = bar.close_price - atr_value

            if self.pos == 0:
                self.short(self.boll_down, 1, True)

                if self.trading:
                    self.watch_short = True

                self.say_log("Signal:", bar.datetime, "pos:", self.pos,
                             "close_down:", self.boll_down, "close:",
                             bar.close_price, "dead-cross open", "trading:",
                             self.trading)
            elif self.pos > 0:
                self.sell(bar.close_price * self.limit_down, abs(self.pos),
                          False)
                self.short(self.boll_down, 1, True)
                self.watch_short = True

                self.say_log("Signal:", bar.datetime, "pos:", self.pos,
                             "close_down:", self.boll_down, "close:",
                             bar.close_price, "dead-cross close and open")

        self.say_log('datetime:', bar.datetime, 'pos:', self.pos,
                     'watch-long:', self.watch_long, 'watch_short:',
                     self.watch_short, 'long-rein:', self.long_rein,
                     'short-rein:', self.short_rein, 'highest:',
                     self.rein_highest, 'lowest:', self.rein_lowest)
        self.say_log('==' * 50)

        self.put_event()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        self.say_log("order", order.datetime, order.direction, order.offset,
                     order.price, order.volume)

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        if trade.offset == Offset.OPEN:
            if trade.direction == Direction.LONG:
                self.watch_long = False
                self.long_rein = False
            else:
                self.watch_short = False
                self.short_rein = False
        else:
            # 交易时做多平仓(平空头),并且不是由于双均线交叉触发的,开启重新入场监测
            if trade.direction == Direction.LONG and not self.watch_long:
                # 重入空头次数小于最大限制,才能重入空头
                if self.short_rein_count < self.max_rein:
                    self.short_rein = True
                    self.short_rein_count += 1

            if trade.direction == Direction.SHORT and not self.watch_short:
                if self.long_rein_count < self.max_rein:
                    self.long_rein = True
                    self.long_rein_count += 1

        self.say_log("Trade:", trade.datetime, trade.direction, trade.offset,
                     trade.price, trade.volume)
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        self.say_log("stop-order", stop_order.direction, stop_order.offset,
                     stop_order.price, stop_order.volume)

    def say_log(self, *args):
        if self.is_say_log:
            print(*args)
コード例 #9
0
ファイル: turtle_signal_strategy.py プロジェクト: shhuiw/vnpy
class TurtleSignalStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    entry_window = 20
    exit_window = 10
    atr_window = 20
    fixed_size = 1

    entry_up = 0
    entry_down = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

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

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

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

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

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

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

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

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

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

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

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

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

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

            self.send_buy_orders(self.entry_up)
            self.send_short_orders(self.entry_down)
        elif self.pos > 0:
            self.send_buy_orders(self.long_entry)

            sell_price = max(self.long_stop, self.exit_down)
            self.sell(sell_price, abs(self.pos), True)

        elif self.pos < 0:
            self.send_short_orders(self.short_entry)

            cover_price = min(self.short_stop, self.exit_up)
            self.cover(cover_price, abs(self.pos), True)

        self.put_event()

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

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

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

    def send_buy_orders(self, price):
        """"""
        t = self.pos / self.fixed_size

        if t < 1:
            self.buy(price, self.fixed_size, True)

        if t < 2:
            self.buy(price + self.atr_value * 0.5, self.fixed_size, True)

        if t < 3:
            self.buy(price + self.atr_value, self.fixed_size, True)

        if t < 4:
            self.buy(price + self.atr_value * 1.5, self.fixed_size, True)

    def send_short_orders(self, price):
        """"""
        t = self.pos / self.fixed_size

        if t > -1:
            self.short(price, self.fixed_size, True)

        if t > -2:
            self.short(price - self.atr_value * 0.5, self.fixed_size, True)

        if t > -3:
            self.short(price - self.atr_value, self.fixed_size, True)

        if t > -4:
            self.short(price - self.atr_value * 1.5, self.fixed_size, True)
コード例 #10
0
class BollVixSignal(CtaSignal):
    """
    布林 vix
    """
    sma_array = 0
    boll_up_array = 0
    boll_down_array = 0
    entry_crossover = 0
    atr_value = 0
    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0

    def __init__(self, open_window, boll_window: int):
        """"""
        super().__init__()
        self.open_window = open_window
        self.boll_window = boll_window

        self.bg = BarGenerator(self.on_bar, self.open_window, self.on_xmin_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_xmin_bar(self, bar: BarData):
        """"""
        self.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

        # Calculate array  计算数组
        self.sma_array = self.am.sma(self.boll_window, True)
        std_array = self.am.sma(self.boll_window, True)
        dev = abs(self.am.close[:-1] - self.sma_array[:-1]) / std_array[:-1]
        dev_max = dev[-self.boll_window:].max()
        self.boll_up_array = self.sma_array[:-1] + std_array[:-1] * dev_max
        self.boll_down_array = self.sma_array[:-1] - std_array[:-1] * dev_max

        # Get current and last index
        last_sma = self.sma_array[-2]
        current_sma = self.sma_array[-1]
        last_close = self.am.close[-2]
        current_boll_up = self.boll_up_array[-1]
        last_boll_up = self.boll_up_array[-2]
        current_boll_down = self.boll_down_array[-1]
        last_boll_down = self.boll_down_array[-2]

        # Get crossover
        if last_close <= last_boll_up and current_boll_up < bar.close_price:
            self.set_signal_pos(1)

        elif last_close >= last_boll_down and current_boll_down > bar.close_price:
            self.set_signal_pos(-1)

        exit_long = last_close >= last_sma and current_sma > bar.close_price
        exit_short = last_close <= last_sma and current_sma < bar.close_price

        if exit_long and exit_short:
            self.set_signal_pos(0)
コード例 #11
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

    buy_orderidList = []
    short_orderidList = []
    orderList = []

    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.orderList:
            self.cancel_order(orderid)
        self.orderList = []

        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.orderList.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.orderList.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_orderidList:
                    self.cancel_order(short_orderid)

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

            for orderid in (self.buy_orderidList + self.short_orderidList):
                if orderid in self.orderList:
                    self.orderList.remove(orderid)

        self.put_event()

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

        self.orderList.append(self.buy_orderidList)
        self.orderList.append(self.short_orderidList)

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
コード例 #12
0
class TSMyoRBKRSIStrategy(CtaTemplate):
    """
    针对本地停止单触发的撤单失败导致重复挂单
        1.给cancel_all()返回值,去标记是否出现 OmsEngine中找不到 的情况,做相应处理
        2.策略自身维护一个订单列表,使用 on_stop_order/on_order 去同步cta_engine的 策略—订单列表map ,做相应判断
    """

    author = "TheSuperMyo"

    setup_coef = 0.25
    break_coef = 0.2
    enter_coef_1 = 1.07
    enter_coef_2 = 0.07

    fixed_size = 1
    donchian_window = 30
    atr_stop = 4
    atr_window = 35
    atr_ma_len = 20
    er_filter = 0.23

    trailing_stop = 0.6
    multiplier = 1

    buy_break = 0  # 突破买入价
    sell_setup = 0  # 观察卖出价
    sell_enter = 0  # 反转卖出价
    buy_enter = 0  # 反转买入价
    buy_setup = 0  # 观察买入价
    sell_break = 0  # 突破卖出价

    intra_trade_high = 0
    intra_trade_low = 0

    day_high = 0
    day_low = 0
    day_close = 0
    tend_high = 0
    tend_low = 0
    atr_value = 0
    atr_ma_value = 0
    limited_size = 8
    td_traded = 0

    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)  # 商品下午

    parameters = [
        "trailing_stop", "er_filter", "donchian_window", "limited_size",
        "atr_stop", "atr_window", "atr_ma_len"
    ]
    variables = [
        "tend_low", "tend_high", "atr_value", "atr_ma_value", "buy_break",
        "sell_setup", "sell_enter", "buy_enter", "buy_setup", "sell_break"
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(TSMyoRBKRSIStrategy, self).__init__(cta_engine, strategy_name,
                                                  vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar)
        self.am = TSMArrayManager()
        self.bars = []
        self.vt_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):
        """
        Callback of new bar data update.
        """
        # 如果撤单过程中出现在OMSEngine找不到订单
        # 则可能是挂单的EVENT_ORDER还未处理,跳过该此次执行
        any_not_find = 0
        any_not_find = self.cancel_all()
        if any_not_find == 1:
            self.write_log("出现撤单找不到问题,跳过此次执行")
            return

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

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

        last_bar = self.bars[-2]

        # 判断开盘bar,先使用split判别有夜盘品种开盘
        # last_bar是昨天的,也就是说bar是今天第一根
        if (last_bar.datetime.date() != bar.datetime.date()):
            if self.day_high:

                self.buy_setup = self.day_low - self.setup_coef * (
                    self.day_high - self.day_close)  # 观察买入价
                self.sell_setup = self.day_high + self.setup_coef * (
                    self.day_close - self.day_low)  # 观察卖出

                self.buy_enter = (self.enter_coef_1 / 2) * (
                    self.day_high +
                    self.day_low) - self.enter_coef_2 * self.day_high  # 反转买入价
                self.sell_enter = (self.enter_coef_1 / 2) * (
                    self.day_high +
                    self.day_low) - self.enter_coef_2 * self.day_low  # 反转卖出价

                self.buy_break = self.sell_setup + self.break_coef * (
                    self.sell_setup - self.buy_setup)  # 突破买入价
                self.sell_break = self.buy_setup - self.break_coef * (
                    self.sell_setup - self.buy_setup)  # 突破卖出价

            self.write_log(f"{bar.datetime.date()}开盘使用数据:")
            self.write_log(
                f"昨收:{self.day_close},昨高:{self.day_high},昨低:{self.day_low}")
            self.write_log(f"计算得出:")
            self.write_log(f"上中轨:{self.sell_setup},下中轨:{self.buy_setup}")
            self.day_high = bar.high_price
            self.day_low = bar.low_price
            self.day_close = bar.close_price
            self.td_traded = 0

        # 盘中记录当日HLC,为第二天计算做准备
        else:
            self.day_high = max(self.day_high, bar.high_price)
            self.day_low = min(self.day_low, bar.low_price)
            self.day_close = bar.close_price

        if not self.sell_setup:
            return

        # N分钟内最高价和最低价
        self.tend_high, self.tend_low = am.donchian(self.donchian_window)
        # ATR相关指标
        atr_array = am.atr(self.atr_window, True)
        self.atr_value = atr_array[-1]
        self.atr_ma_value = atr_array[-self.atr_ma_len:].mean()
        # ER
        er_value = am.er(20, False)
        if er_value > self.er_filter:
            er_flag = 1

        # 交易时间
        if (bar.datetime.time() < self.exit_time):
            # 设置ATR过滤,只有波动扩大才开仓
            if self.pos == 0 and self.atr_value > self.atr_ma_value and er_flag == 1:
                self.write_log(f"波动扩大:{self.atr_value} > {self.atr_ma_value}")
                self.intra_trade_low = bar.low_price
                self.intra_trade_high = bar.high_price
                # N分钟内最高价在sell_setup之上
                if self.tend_high > self.sell_setup:
                    self.write_log(
                        f"N分钟内 tend_high > sell_setup:{self.tend_high} > {self.sell_setup}"
                    )
                    # 添加过滤,突破价不低于最高价,才进场
                    long_entry = max(self.buy_break, self.day_high)
                    # 检查策略是否还有订单留存,或者是否达到交易上限
                    if self.vt_orderids or self.td_traded >= self.limited_size:
                        self.write_log("撤单不干净或达到交易限制,无法挂单")
                        return
                    orderids = self.buy(long_entry,
                                        self.fixed_size,
                                        stop=True,
                                        lock=True)
                    self.vt_orderids.extend(orderids)

                    # 反转系统进场,手数可以和趋势系统做区分
                    orderids = self.short(self.sell_enter,
                                          self.multiplier * self.fixed_size,
                                          stop=True,
                                          lock=True)
                    self.vt_orderids.extend(orderids)
                    self.write_log(
                        f"stop_order for buy & short:{long_entry} & {self.sell_enter}"
                    )

                elif self.tend_low < self.buy_setup:
                    self.write_log(
                        f"N分钟内 tend_low < buy_setup:{self.tend_low} < {self.buy_setup}"
                    )
                    short_entry = min(self.sell_break, self.day_low)
                    if self.vt_orderids or self.td_traded >= self.limited_size:
                        self.write_log("撤单不干净或达到交易限制,无法挂单")
                        return
                    orderids = self.short(short_entry,
                                          self.fixed_size,
                                          stop=True,
                                          lock=True)
                    self.vt_orderids.extend(orderids)
                    orderids = self.buy(self.buy_enter,
                                        self.multiplier * self.fixed_size,
                                        stop=True,
                                        lock=True)
                    self.vt_orderids.extend(orderids)
                    self.write_log(
                        f"stop_order for short & buy:{short_entry} & {self.buy_enter}"
                    )

            elif self.pos > 0:
                # 跟踪止损出场(百分比&ATR)
                self.intra_trade_high = max(self.intra_trade_high,
                                            bar.high_price)
                long_stop = max(
                    self.intra_trade_high * (1 - self.trailing_stop / 100),
                    self.intra_trade_high - self.atr_stop * self.atr_value)
                if self.vt_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.sell(long_stop,
                                     abs(self.pos),
                                     stop=True,
                                     lock=True)
                self.vt_orderids.extend(orderids)
                self.write_log(f"stop_order for sell:{long_stop}")

            elif self.pos < 0:
                self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
                short_stop = min(
                    self.intra_trade_low * (1 + self.trailing_stop / 100),
                    self.intra_trade_low + self.atr_stop * self.atr_value)
                if self.vt_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.cover(short_stop,
                                      abs(self.pos),
                                      stop=True,
                                      lock=True)
                self.vt_orderids.extend(orderids)
                self.write_log(f"stop_order for cover:{short_stop}")

        # 日内策略,最后6分钟不断尝试平仓
        else:
            if self.pos > 0:
                if self.vt_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.sell(bar.close_price, abs(self.pos), lock=True)
                self.vt_orderids.extend(orderids)

            elif self.pos < 0:
                if self.vt_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.cover(bar.close_price,
                                      abs(self.pos),
                                      lock=True)
                self.vt_orderids.extend(orderids)

        self.put_event()

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

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        self.td_traded += 1
        self.write_log(
            f"{trade.vt_symbol}在{trade.time}成交,价格{trade.price},方向{trade.direction}{trade.offset},数量{trade.volume}"
        )
        self.send_email(
            f"{trade.vt_symbol}在{trade.time}成交,价格{trade.price},方向{trade.direction}{trade.offset},数量{trade.volume}"
        )
        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.vt_orderids:
                self.vt_orderids.remove(stop_order.stop_orderid)
        # 触发的本地停止单,停止单移除,限价单加入
        if stop_order.status == StopOrderStatus.TRIGGERED:
            if stop_order.stop_orderid in self.vt_orderids:
                self.vt_orderids.remove(stop_order.stop_orderid)
                self.vt_orderids.extend(stop_order.vt_orderids)
            # 撤掉其他停止单
            for other_stop_orderids in self.vt_orderids:
                if other_stop_orderids.startswith(STOPORDER_PREFIX):
                    self.cancel_order(other_stop_orderids)
コード例 #13
0
ファイル: Double_trendmodel.py プロジェクト: Yiran13/CTA-
class DoubleTrendModelStrategy(CtaTemplate):
    """"""

    author = "yiran"

    fixed_size = 1
    s_window = 5
    l_window = 15

    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_s = 50
    cross_over_slice_window_s = 4
    trail_bar_window_s = 6

    cross_over_record_max_num_l = 50
    cross_over_slice_window_l = 4
    trail_bar_window_l = 6

    bar_num_s = 0
    bar_num_after_crossover_s = 0

    bar_num_l = 0
    bar_num_after_crossover_l = 0

    mdif_s = 0
    cross_above_0_s = False
    cross_under_0_s = False
    cross_over_record_array_s = np.zeros(shape=(4,
                                                cross_over_record_max_num_s))
    cross_over_slice_window_highest_s = 0
    cross_over_slice_window_lowest_s = 0
    last_cross_over_interval_s = 0
    last_cross_over_side_s = 0

    mdif_l = 0
    cross_above_0_l = False
    cross_under_0_l = False
    cross_over_record_array_l = np.zeros(shape=(4,
                                                cross_over_record_max_num_l))
    cross_over_slice_window_highest_l = 0
    cross_over_slice_window_lowest_l = 0
    last_cross_over_interval_l = 0
    last_cross_over_side_l = 0

    long_open_stop_order_price_l = 0
    long_close_stop_order_price_l = 0
    short_open_stop_order_price_l = 0
    short_close_stop_order_price_l = 0

    long_open_stop_order_price_s = 0
    long_close_stop_order_price_s = 0
    short_open_stop_order_price_s = 0
    short_close_stop_order_price_s = 0

    parameters = [
        'fast_ma_macd', 'slow_ma_macd', 'signal_macd', 'true_range_window',
        'cross_over_record_max_num_l', 'cross_over_record_max_num_s',
        's_window', 'l_window', 'true_range_influence_multiplier',
        'cross_over_slice_window_l', 'cross_over_slice_window_s',
        'trail_bar_window_l', 'trail_bar_window_s'
    ]

    variables = []

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)
        self.bars = []
        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()

    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):
        self.bg5.update_bar(bar)
        self.bg15.update_bar(bar)

    def on_5min_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.cancel_all()
        self.am5.update_bar(bar)
        self.bar_num_s += 1
        if not self.am5.inited:
            return

        am = self.am5
        self.mdif_s, signal, hist = am.macd(self.fast_ma_macd,
                                            self.slow_ma_macd,
                                            self.signal_macd,
                                            array=True)
        self.long_close_stop_order_price_s = am.low[-self.
                                                    trail_bar_window_s:].min()
        self.short_close_stop_order_price_s = am.high[
            -self.trail_bar_window_s:].max()

        if self.mdif_s[-2] < 0 < self.mdif_s[-1]:
            self.cross_above_0_s = True
        elif self.mdif_s[-2] > 0 > self.mdif_s[-1]:
            self.cross_under_0_s = True

        if self.cross_under_0_s or self.cross_above_0_s:
            # bar_num
            self.cross_over_record_array_s[
                0, :-1] = self.cross_over_record_array_s[0, 1:]
            # high
            self.cross_over_record_array_s[
                1, :-1] = self.cross_over_record_array_s[1, 1:]
            # low
            self.cross_over_record_array_s[
                2, :-1] = self.cross_over_record_array_s[2, 1:]
            # cross_over_side
            self.cross_over_record_array_s[
                3, :-1] = self.cross_over_record_array_s[3, 1:]

            self.cross_over_record_array_s[0, -1] = self.bar_num_s
            self.cross_over_record_array_s[1, -1] = am.high[-1]
            self.cross_over_record_array_s[2, -1] = am.low[-1]
            if self.cross_above_0_s:
                side = 1
            elif self.cross_under_0_s:
                side = -1
            self.cross_over_record_array_s[3, -1] = side
            self.cross_above_0_s, self.cross_under_0_s = False, False

        self.cross_over_slice_window_highest_s = np.max(
            self.cross_over_record_array_s[1,
                                           -self.cross_over_slice_window_s:])
        self.cross_over_slice_window_lowest_s = np.min(
            self.cross_over_record_array_s[2,
                                           -self.cross_over_slice_window_s:])
        self.last_cross_over_interval_s = self.bar_num_s - \
            self.cross_over_record_array_s[0, -1]
        self.last_cross_over_side_s = self.cross_over_record_array_s[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_s = self.cross_over_slice_window_highest_s + \
            true_range_influence
        self.short_open_stop_order_price_s = self.cross_over_slice_window_lowest_s + \
            true_range_influence

        cross_overl_l = self.last_cross_over_interval_l <= self.last_cross_over_interval_l
        if self.pos == 0 and cross_overl_l:
            if self.last_cross_over_interval_s <= self.cross_over_record_max_num_s:
                if self.last_cross_over_side_s == 1 and self.last_cross_over_side_l == 1:
                    self.buy(self.long_open_stop_order_price_s,
                             self.fixed_size,
                             stop=True)
                if self.last_cross_over_side_s == -1 and self.last_cross_over_side_l == -1:
                    self.short(self.short_close_stop_order_price_s,
                               self.fixed_size,
                               stop=True)
        elif self.pos > 0:
            self.sell(self.long_close_stop_order_price_s, self.pos, stop=True)
        elif self.pos < 0:
            self.cover(self.short_close_stop_order_price_s,
                       np.abs(self.pos),
                       stop=True)

        self.put_event()

    def on_15min_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.cancel_all()
        self.am15.update_bar(bar)
        self.bar_num_l += 1
        if not self.am15.inited:
            return
        am = self.am15
        self.mdif_l, signal, hist = am.macd(self.fast_ma_macd,
                                            self.slow_ma_macd,
                                            self.signal_macd,
                                            array=True)
        self.long_close_stop_order_price_l = am.low[-self.
                                                    trail_bar_window_l:].min()
        self.short_close_stop_order_price_l = am.high[
            -self.trail_bar_window_l:].max()

        if self.mdif_l[-2] < 0 < self.mdif_l[-1]:
            self.cross_above_0_l = True
        elif self.mdif_l[-2] > 0 > self.mdif_l[-1]:
            self.cross_under_0_l = True

        if self.cross_under_0_l or self.cross_above_0_l:
            # bar_num
            self.cross_over_record_array_l[
                0, :-1] = self.cross_over_record_array_l[0, 1:]
            # high
            self.cross_over_record_array_l[
                1, :-1] = self.cross_over_record_array_l[1, 1:]
            # low
            self.cross_over_record_array_l[
                2, :-1] = self.cross_over_record_array_l[2, 1:]
            # cross_over_side
            self.cross_over_record_array_l[
                3, :-1] = self.cross_over_record_array_l[3, 1:]

            self.cross_over_record_array_l[0, -1] = self.bar_num_l
            self.cross_over_record_array_l[1, -1] = am.high[-1]
            self.cross_over_record_array_l[2, -1] = am.low[-1]
            if self.cross_above_0_l:
                side = 1
            elif self.cross_under_0_l:
                side = -1
            self.cross_over_record_array_l[3, -1] = side
            self.cross_above_0_l, self.cross_under_0_l = False, False
            self.last_cross_over_interval_l = self.bar_num_l - \
                                              self.cross_over_record_array_l[0, -1]
            self.last_cross_over_side_l = self.cross_over_record_array_l[3, -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
コード例 #14
0
class MacdAP001Strategy(CtaInvestmentTemplate):
    """基于布林通道的交易策略"""
    author = u'tonywang_efun'

    # 策略参数
    initDays = 15  # 初始化数据所用的天数
    fixedSize = 1  # 每次交易的数量
    fixWinPrcnt = 5  # 固定止盈百分比
    shortfixWinPrcnt = 5  # 固定止盈百分比

    # 公共策略变量
    posPrice = 0  # 持仓价
    macd = 0
    signal = 0
    hist = 0
    red_bar_num = 0
    green_bar_num = 0

    # 参数列表,保存了参数的名称
    parameters = ['initDays', 'fixedSize', 'fixWinPrcnt', 'shortfixWinPrcnt']

    # 变量列表,保存了变量的名称
    variables = ['posPrice', 'macd', 'signal', 'hist']

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

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

    # ----------------------------------------------------------------------
    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.macd, self.signal, self.hist = am.macd(12, 26, 9)

        if self.hist > 0:
            self.red_bar_num += 1
            self.green_bar_num = 0
        elif self.hist < 0:
            self.red_bar_num = 0
            self.green_bar_num += 1

        if self.red_bar_num == 1:
            print(bar.datetime, self.macd, self.signal, self.hist)

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

            if self.hist > 0:
                self.buy(bar.close_price, self.fixedSize)

            elif self.hist < 0:
                self.short(bar.close_price, self.fixedSize)

        # 持有多头仓位
        elif self.pos > 0:
            if 0 < self.posPrice < bar.close_price \
                    and (bar.close_price - self.posPrice) / self.posPrice > (self.fixWinPrcnt / 100):
                self.sell(bar.close_price * 0.99, abs(self.pos))
            elif self.hist < 0:
                self.sell(bar.close_price * 0.99, abs(self.pos))
            else:
                self.intraTradeHigh = max(self.intraTradeHigh, bar.high_price)

        # 持有空头仓位
        elif self.pos < 0:
            if bar.close_price < self.posPrice \
                    and (self.posPrice - bar.close_price) / self.posPrice > (self.shortfixWinPrcnt / 100):
                self.cover(bar.close_price * 1.01, abs(self.pos))
            elif self.hist > 0:
                self.cover(bar.close_price * 1.01, abs(self.pos))
            else:
                self.intraTradeLow = min(self.intraTradeLow, bar.low_price)

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

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

    # ----------------------------------------------------------------------
    def on_trade(self, trade):

        # 记录交易数据并分析投资情况
        self.record_trade(trade, "MACD", True)

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

    # ----------------------------------------------------------------------
    def on_stop_order(self, so):
        """停止单推送"""
        pass
コード例 #15
0
class CciSignal(CtaSignal):
    """
    """
    cci_up_array = 0
    cci_dow_array = 0
    cci_value = 0
    cci_up = 0
    cci_down = 0
    cci_ma = 0
    last_cci_value = 0
    current_cci_value = 0
    last_cci_up = 0
    current_cci_up = 0
    last_cci_down = 0
    current_cci_down = 0
    last_cci_ma = 0
    current_cci_ma = 0

    def __init__(self, open_window: int, cci_window: int, cci_level: float):
        """"""
        super().__init__()
        self.open_window = open_window
        self.cci_window = cci_window
        self.cci_level = cci_level
        self.cci_long = self.cci_level
        self.cci_short = -self.cci_level

        self.bg = BarGenerator(self.on_bar, self.open_window, self.on_x_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):
        """
        :param bar: 
        :return: 
        """
        self.bg.update_bar(bar)

    def on_x_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.am.update_bar(bar)
        if not self.am.inited:
            self.set_signal_pos(0)

        # 计算 前一根K线的 cci
        cci_array = talib.CCI(self.am.high[:-1], self.am.low[:-1],
                              self.am.close[:-1], self.cci_window)
        cci_ema = talib.EMA(cci_array, self.cci_window)

        dev_array = abs(
            cci_array[-self.cci_window:] -
            cci_ema[-self.cci_window:]) / cci_ema[-self.cci_window:]
        dev = np.max(dev_array[-self.cci_window:])

        self.cci_up_array = cci_ema[
            -self.cci_window:] + cci_array[-self.cci_window:] * dev
        self.cci_dow_array = cci_ema[
            -self.cci_window:] - cci_array[-self.cci_window:] * dev

        self.cci_value = self.am.cci(self.cci_window, True)

        self.last_cci_value = self.cci_value[-2]
        self.current_cci_value = self.cci_value[-1]
        self.last_cci_up = self.cci_up_array[-2]
        self.current_cci_up = self.cci_up_array[-1]
        self.last_cci_down = self.cci_dow_array[-2]
        self.current_cci_down = self.cci_dow_array[-1]
        self.last_cci_ma = cci_ema[-2]
        self.current_cci_ma = cci_ema[-1]

        if self.last_cci_value <= self.last_cci_up and self.current_cci_value > self.current_cci_up:
            self.set_signal_pos(1)

        elif self.last_cci_value >= self.last_cci_up and self.current_cci_value < self.current_cci_up:
            self.set_signal_pos(-1)

        cci_sell = self.last_cci_value >= self.last_cci_ma and self.current_cci_value < self.current_cci_ma
        cci_court = self.last_cci_value <= self.last_cci_ma and self.current_cci_value > self.current_cci_ma
        if cci_sell and cci_court:
            self.set_signal_pos(0)
コード例 #16
0
class Boll_Kc_Dc_Reverse_Strategy(CtaTemplate):
    """
    本策略为反向策略,币本位  Reverse 反向
    """

    author = "yunya"
    open_window = 2
    xsmall_window = 15
    com_length = 250
    boll_kk_dev = 2.0
    kk_atr_length = 30
    sl_multiplier = 0.5
    risk_level = 10000

    trading_size = 0
    xsmall_up_min = 0
    xsmall_down_min = 0
    xsmall_up_max = 0
    xsmall_down_max = 0
    xsmall_ema_mid = 0
    xsmall_com_width = 0
    long_entry = 0
    short_entry = 0
    long_stop = 0
    short_stop = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

    intra_trade_high = 0
    intra_trade_low = 0

    parameters = [
        "open_window",
        "xsmall_window",
        "com_length",
        "boll_kk_dev",
        "kk_atr_length",
        "sl_multiplier",
        "risk_level",
    ]
    variables = [
            "trading_size",
            "xsmall_up_min",
            "xsmall_down_min",
            "xsmall_up_max",
            "xsmall_down_max",
            "xsmall_ema_mid",
            "xsmall_com_width",
            "long_entry",
            "short_entry",
            "long_stop",
            "short_stop",
            "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_xsmall = BarGenerator(
            on_bar=self.on_bar,
            window=self.xsmall_window,
            on_window_bar=self.on_xsmall_bar,
            interval=Interval.MINUTE
        )
        self.am_xsmall = 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_xsmall.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_bar(bar)
        self.bg_xsmall.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_xsmall.inited or not self.am.inited:
            return

        if self.pos == 0:
            # 根据布林带宽度动态调整仓位大小
            self.trading_size = max(int(self.risk_level / self.xsmall_com_width), 1)
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            # 如果价格突破 xsmall_up_min 线时,在xsmall_up_max 价格挂停止单
            if self.am_xsmall.close[-1] >= self.xsmall_up_min and self.am.close[-1] >=self.xsmall_up_min:
                self.buy(self.xsmall_up_max,self.trading_size,True)

            # 如果价格突破 xsmall_down_min 线时,在xsmall_down_max 价格挂停止单
            elif self.am_xsmall.close[-1] <= self.xsmall_down_min and self.am.close[-1] <= self.xsmall_down_min:
                self.short(self.xsmall_down_max,self.trading_size,True)

        elif self.pos > 0:
            # 成交价固定止损位与中轨中最大值为当前止损位
            # self.exit_up = max(self.xsmall_ema_mid,self.long_stop)

            # 成交价回定止损 与最高价回撤一定比例通道宽度值
            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.xsmall_com_width * self.sl_multiplier
            self.exit_up = max(exit_long_stop,self.long_stop)
            self.sell(self.exit_up,abs(self.pos),True)

        elif self.pos < 0:
            # 成交价固定止损位与中轨中最小值为当前止损位
            # self.exit_down = min(self.xsmall_ema_mid,self.short_stop)

            # 成交价回定止损 与最高价回撤一定比例通道宽度值
            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.xsmall_com_width * self.sl_multiplier
            self.exit_down = min(exit_short_stop,self.short_stop)
            self.cover(self.exit_down,abs(self.pos),True)

        self.sync_data()
        self.put_event()

    def on_xsmall_bar(self, bar: BarData):
        """
        :param bar:
        :return:
        """
        # x分钟 多策略合合成的通道线
        self.am_xsmall.update_bar(bar)
        if not self.am_xsmall.inited :
            return

        self.xsmall_ema_mid,self.xsmall_com_width,self.xsmall_up_min, self.xsmall_down_min,\
        self.xsmall_up_max, self.xsmall_down_max = self.boll_kc_dc_combination(
                                                                        high=self.am_xsmall.high[:-1],
                                                                        low=self.am_xsmall.low[:-1],
                                                                        close=self.am_xsmall.close[:-1],
                                                                        boll_kk_dev=self.boll_kk_dev,
                                                                        kk_atr_length=self.kk_atr_length,
                                                                        com_length=self.com_length
                                                                        )

        # print(f"xsmall: mid:{self.xsmall_ema_mid},width:{self.xsmall_com_width},upmin:{self.xsmall_up_min},\
        #         downmin:{self.xsmall_down_min},upmax:{self.xsmall_up_max},downmax:{self.xsmall_down_max}" + "\n")

        self.atr_value = self.am_xsmall.atr(self.kk_atr_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_kc_dc_combination(self, high, close, low, boll_kk_dev,kk_atr_length,com_length):

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

        # 计算布林带
        boll_std = talib.STDDEV(close, com_length)
        boll_up = ema_com + boll_kk_dev * boll_std
        boll_down = ema_com - boll_kk_dev * boll_std

        # 计算肯特通道
        kc_atr = talib.ATR(high, low, close, kk_atr_length)
        kc_up = ema_com + kc_atr * boll_kk_dev
        kc_dowm = ema_com - kc_atr * boll_kk_dev

        # 计算唐安奇通道
        dc_up = talib.MAX(high, com_length)
        dc_down = talib.MIN(low, com_length)

        # 计算轨道 因kc通道是直接,最小值大概率是直接,所以去除
        pass_up_min = min(dc_up[-1], boll_up[-1])
        pass_down_min = max(dc_down[-1], boll_down[-1])

        pass_up_max = max(kc_up[-1], dc_up[-1], boll_up[-1])
        pass_down_max = min(kc_dowm[-1], dc_down[-1], boll_down[-1])
        ema_mid = ema_com[-1]

        com_width = abs(pass_up_max - pass_down_max)

        return ema_mid, com_width, pass_up_min, pass_down_min, pass_up_max, pass_down_max
コード例 #17
0
ファイル: 2-AtrRsi_Strategy.py プロジェクト: hun1982qhu/CTA
class AtrRsiStrategyHN(CtaTemplate):
    """"""

    author = "黄柠"

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

    # 变量
    atr_value = 0.0
    atr_ma = 0.0
    rsi_value = 0.0
    rsi_buy = 0.0
    rsi_sell = 0.0
    intra_trade_high = 0.0
    intra_trade_low = 0.0

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

    def __init__(
        self,
        cta_engine: Any,
        strategy_name: str,
        vt_symbol: str,
        setting: dict,
    ):
        """"""
        super().__init__(self, cta_engine, strategy_name, vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar)
        self.am = ArrayManager()

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

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

        self.load_bar(10)

    def on_start(self):
        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.cancel_all()

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

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

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

            # 当atr_value大于atr_ma时,表明市场波动性增大,趋势正在增强
            if self.atr_value > self.atr_ma:
                # 在趋势增强的情况下,用rsi指标产生交易信号
                if self.rsi_value > self.rsi_buy:
                    self.buy(bar.close_price + 5, self.fixed_size)
                elif self.rsi_value < self.rsi_sell:
                    self.short(bar.close_price - 5, self.fixed_size)

        if self.pos > 0:
            # 移动止损,首先找到交易周期内价格最高点
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.intra_trade_low = bar.low_price

            long_stop = self.intra_trade_high * (1 -
                                                 self.trailing_percent / 100)
            self.sell(long_stop, abs(self.pos), stop=True)

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

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

        self.put_event()
コード例 #18
0
class ExampleStrategy(CtaTemplate):
    """"""

    author = "DEAN"

    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(ExampleStrategy, 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
コード例 #19
0
ファイル: atr_rsi_strategy.py プロジェクト: shhuiw/vnpy
class AtrRsiStrategy(CtaTemplate):
    """"""

    author = '用Python的交易员'

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

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

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

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(AtrRsiStrategy, self).__init__(
            cta_engine, strategy_name, vt_symbol, setting
        )
        self.bg = BarGenerator(self.on_bar)
        self.am = ArrayManager()

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

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

        self.load_bar(10)

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

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

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

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

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

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

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

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

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

            long_stop = self.intra_trade_high * \
                (1 - self.trailing_percent / 100)
            self.sell(long_stop, abs(self.pos), stop=True)

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

            short_stop = self.intra_trade_low * \
                (1 + self.trailing_percent / 100)
            self.cover(short_stop, abs(self.pos), stop=True)

        self.put_event()

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

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

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
コード例 #20
0
class TSMyoIntraday30momStrategy(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)  # 商品下午

    trailing_stop = 0.4  # 跟踪止损
    stop_loss = 20
    th = 0.5 / 100  # 涨跌幅阈值
    fixed_size = 1  # 固定手数

    bar_counter = 0  # 计数器

    long_entry = 0
    short_entry = 0

    hold_high = 0
    hold_low = 0

    parameters = ['th', 'stop_loss', 'fixed_size']

    #variables = ['bar_counter','long_entry','short_entry','hold_high','hold_low']

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(TSMyoIntraday30momStrategy,
              self).__init__(cta_engine, strategy_name, vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar, 30, self.on_30_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):
        """
        根据信号挂单
        """

        self.cancel_all()
        self.bg.update_bar(bar)

        if self.pos == 0 and bar.datetime.time() < self.exit_time:
            if self.long_entry:
                # 入场开多,收盘价
                self.hold_high = bar.high_price
                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:
                # 入场开空,收盘价
                self.hold_low = bar.low_price
                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.long_entry = 0
            self.short_entry = 0
            #self.hold_high = max(self.hold_high,bar.high_price)
            #stop_long = self.hold_high * (1-self.trailing_stop/100)
            stop_long = self.hold_high - self.stop_loss

            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(stop_long, self.fixed_size, True, True)
                self.active_orderids.extend(orderids)

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

            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(stop_short, self.fixed_size, True, True)
                self.active_orderids.extend(orderids)

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

        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]
        # 开盘bar
        if last_bar.datetime.date() != bar.datetime.date():
            # 初始化
            self.bar_counter = 1
            self.long_entry = 0
            self.short_entry = 0

        if self.bar_counter != 7:
            return

        f1 = (am.close[-7] - am.close[-8]) / am.close[-8]
        f2 = (bar.close_price - bar.open_price) / bar.open_price
        print("930-1000:{0},  1400-1430:{1}".format(f1, f2))

        # 空仓且指示方向相同
        if self.pos == 0 and f1 * f2 > 0:
            if f1 > self.th:
                # 开多信号
                self.long_entry = 1
                self.short_entry = 0

            if f1 < -self.th:
                # 开空信号
                self.long_entry = 0
                self.short_entry = 1

    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.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)
コード例 #21
0
ファイル: macd_strategy.py プロジェクト: tonywanggit/vnpy
class MacdStrategy(CtaTemplate):
    """基于布林通道的交易策略"""
    author = u'tonywang_efun'

    # 策略参数
    fixed_size = 1                    # 每次交易的数量
    fixed_long_win_percent = 0.5      # 固定止盈百分比(多头)
    fixed_short_win_percent = 0.5     # 固定止盈百分比(空头)

    # 公共策略变量
    pos_price = 0  # 持仓价
    intra_trade_high = 0
    intra_trade_low = 0
    macd = 0
    signal = 0
    hist = 0
    red_bar_num = 0
    green_bar_num = 0

    exit_time = time(hour=14, minute=55)
    night_open_time = time(hour=21, minute=00)
    last_bar = None
    new_day = False

    # 参数列表,保存了参数的名称
    parameters = ['fixed_size',
                  'fixed_long_win_percent',
                  'fixed_short_win_percent']

    # 变量列表,保存了变量的名称
    variables = ['pos_price',
                 'intra_trade_high',
                 'intra_trade_low',
                 'macd',
                 'signal',
                 'hist']

    # ----------------------------------------------------------------------
    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, 20, 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("策略启动")
        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.
        """
        if not self.last_bar or self.last_bar.datetime.date() != bar.datetime.date():
            self.new_day = True
        self.last_bar = bar

        self.bg.update_bar(bar)

        if self.pos > 0:
            if self.exit_time <= bar.datetime.time() <= self.night_open_time:
                self.sell(bar.close_price * 0.99, abs(self.pos))

        elif self.pos < 0:
            if self.exit_time <= bar.datetime.time() <= self.night_open_time:
                self.cover(bar.close_price * 1.01, abs(self.pos))

    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.macd, self.signal, self.hist = am.macd(12, 26, 9)

        if self.hist > 0:
            self.red_bar_num += 1
            self.green_bar_num = 0
        elif self.hist < 0:
            self.red_bar_num = 0
            self.green_bar_num += 1

        if self.pos == 0 and (bar.datetime.time() < self.exit_time or bar.datetime.time() > self.night_open_time):
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            if self.hist > 0:
                self.buy(bar.close_price, self.fixed_size)

            elif self.hist < 0:
                self.short(bar.close_price, self.fixed_size)

        # 持有多头仓位
        elif self.pos > 0:
            if self.pos_price > bar.close_price \
                    and (self.pos_price - bar.close_price) / self.pos_price > (self.fixed_long_win_percent / 100):
                self.sell(bar.close_price * 0.99, abs(self.pos))
            elif self.hist < 0:
                self.sell(bar.close_price * 0.99, abs(self.pos))
            else:
                self.intra_trade_high = max(self.intra_trade_high, bar.high_price)

        # 持有空头仓位
        elif self.pos < 0:
            if bar.close_price > self.pos_price \
                    and (bar.close_price - self.pos_price) / self.pos_price > (self.fixed_short_win_percent / 100):
                self.cover(bar.close_price * 1.01, abs(self.pos))
            elif self.hist > 0:
                self.cover(bar.close_price * 1.01, abs(self.pos))
            else:
                self.intra_trade_low = min(self.intra_trade_low, bar.low_price)

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

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

    # ----------------------------------------------------------------------
    def on_trade(self, trade):
        self.pos_price = trade.price
        self.put_event()

    # ----------------------------------------------------------------------
    def on_stop_order(self, so):
        """停止单推送"""
        pass
コード例 #22
0
class DoubleMaRsiStrategy(CtaTemplate):
    # 在双均线基础上增加rsi多空过滤
    author = "double_ma_rsi"

    fast_window = 20
    slow_window = 40

    fast_ma0 = 0.0
    fast_ma1 = 0.0

    slow_ma0 = 0.0
    slow_ma1 = 0.0

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

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

        self.bg = BarGenerator(self.on_bar)
        self.am = ArrayManager(size=60)

        self.local_stop = False
        self.limit_up = 1.04
        self.limit_down = 0.96

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

        # switch from load minute bar to hour bar
        # 回撤引擎,load_bar只有days(回溯交易日)和callback有作用,其他传入参数都没有作用。
        self.load_bar(30)

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

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

        rsi = am.rsi(self.slow_window)

        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 * self.limit_up, 1, self.local_stop)
                # print("Signal:", bar.datetime, "pos:", self.pos, "price:", bar.close_price, "gloden-cross open")
            elif self.pos < 0:
                self.cover(bar.close_price * self.limit_up, abs(self.pos),
                           self.local_stop)
                # print("Signal:", bar.datetime, "pos:", self.pos, "price:", bar.close_price, "gloden-cross close short")
                if rsi > 50:
                    # print("Signal:", bar.datetime, "pos:", self.pos, "price:", bar.close_price, "gloden-cross open long after close")
                    self.buy(bar.close_price * self.limit_up, 1,
                             self.local_stop)

        elif cross_below:
            if self.pos == 0:
                self.short(bar.close_price * self.limit_down, 1,
                           self.local_stop)
                # print("Signal:", bar.datetime, "pos:", self.pos, "price:", bar.close_price, "dead-cross open")
            elif self.pos > 0:
                self.sell(bar.close_price * self.limit_down, abs(self.pos),
                          self.local_stop)
                # print("Signal:", bar.datetime, "pos:", self.pos, "price:", bar.close_price, "dead-cross close long")
                if rsi < 50:
                    self.short(bar.close_price * self.limit_down, 1,
                               self.local_stop)
                    # print("Signal:", bar.datetime, "pos:", self.pos, "price:", bar.close_price, "dead-cross open short after close")

        # print('==' * 50)
        # print('datetime:', bar.datetime, 'pos:', self.pos)

        self.put_event()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        # print("order", order.datetime, order.direction, order.offset, order.price, order.volume)
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        # print("Trade:", trade.datetime, trade.direction, trade.offset, trade.price, trade.volume)
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
コード例 #23
0
class SuperTurtleStrategyHNTest(CtaTemplate):
    """"""
    author = "Huang Ning"

    entry_window = 28
    exit_window = 7
    atr_window = 4
    risk_level = 0.2

    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 = [
        "entry_up", "entry_down", "exit_up", "exit_down", "trading_size",
        "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,
                               1,
                               self.on_hour_bar,
                               interval=Interval.HOUR)
        self.am = ArrayManager()

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

    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_hour_bar(self, bar: BarData):
        """"""

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

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

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

            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

            self.buy(self.entry_up, self.trading_size, True)
            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
コード例 #24
0
class TurtleDStrategy(CtaTemplate):
    """"""
    # 改版海龟信号-ma出场
    author = "turtle_exit_ma"

    entry_window = 50
    exit_window = 20
    atr_window = 20
    stop_multiple = 10
    fixed_size = 1

    can_long = True
    can_short = True

    entry_up = 0
    entry_down = 0
    exit_up = 0
    exit_down = 0
    atr_value = 0

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

    parameters = [
        "entry_window", "exit_window", "atr_window", "fixed_size",
        "stop_multiple", "can_long", "can_short"
    ]
    variables = ["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.am = ArrayManager()

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

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

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

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

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

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

        # Only calculates new entry channel when no position holding
        if not self.pos:
            self.entry_up, self.entry_down = self.am.donchian(
                self.entry_window)

        self.exit_up = self.exit_down = self.am.sma(self.exit_window)

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

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

            if self.can_long:
                self.send_buy_orders(self.entry_up)

            if self.can_short:
                self.send_short_orders(self.entry_down)
        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 - self.stop_multiple * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + self.stop_multiple * self.atr_value

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

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

    def send_buy_orders(self, price):
        """"""
        self.buy(price, self.fixed_size, True)

    def send_short_orders(self, price):
        """"""
        self.short(price, self.fixed_size, True)
コード例 #25
0
class CincoP2005Strategy(CtaTemplate):
    """"""

    author = "tonywang_efun"

    bar_window = 15
    boll_window = 34
    boll_dev = 3.0
    rsi_window = 12
    rsi_long = 69
    rsi_short = 22
    trailing_long = 2.2
    trailing_short = 2.6
    fixed_size = 2

    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

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

    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,
    ):
        """"""
        print(self.bar_window)
        super(CincoP2005Strategy, self).__init__(cta_engine, strategy_name,
                                                 vt_symbol, setting)
        print(self.bar_window)

        self.bg = BarGenerator(self.on_bar, self.bar_window, 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()

        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

            # 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.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_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
コード例 #26
0
class OscillatorDriveStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    boll_window = 34
    boll_dev = 2.4
    atr_window = 20
    trading_size = 1
    risk_level = 50
    sl_multiplier = 1.8
    dis_open = 8
    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
コード例 #27
0
ファイル: rsi_dollar_atr.py プロジェクト: Yiran13/CTA-
class RsiDollarATR(CtaTemplate):
    """"""
    author = "yiran"

    dollar_threshold = 1_00_00_00_0
    long_trend_cum_threshold = 10
    short_trend_cum_threshold = 10
    init_dollar_bar_num = 100

    rsi_window = 10
    atr_window = 10
    rsi_up_threshold = 70
    sma_short_window = 5
    sma_long_window = 20

    exit_loss = 0.02
    exit_return = 0.2
    atr_multiplier = 0.05
    cross_over_day = 10
    fixed_size = 1

    long_order_record = []
    short_order_record = []

    rsi_value = 0
    atr_value = 0
    long_trend_cum = 0
    short_trend_cum = 0
    stop_price = 0
    exit_price = 0
    hold_bar_num = 0

    cum_filtered = False
    dollar_bar_finished = False
    long_trend = False
    short_trend = False
    long_trend_days = np.inf
    short_trend_days = np.inf

    parameters = [
        'rsi_window',
        'rsi_up_threshold',
        'atr_window',
        'sma_short_window',
        'cross_over_day',
        'sma_long_window',
        'atr_multiplier',
        'long_trend_cum_threshold',
        'short_trend_cum_threshold',
        'exit_loss','exit_return',
        'sma_short_window',
        'sma_long_window']

    variables = ['rsi_value', 'atr_value', 'exit_price']

    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.am = ArrayManager()

        self.long_order_record = []
        self.short_order_record = []

        self.one_minute_bar_price_list = []
        self.one_minute_bar_volume_list = []
        self.time_list = []
        self.one_minute_bar_num_list = []

        # dollar-bar
        self.high_list = []
        self.low_list = []
        self.close_list = []
        self.open_list = []
        self.volume_list = []

        # cum_filter_bar
        self.cum_high_list = []
        self.cum_low_list = []
        self.cum_close_list = []
        self.cum_open_list = []
        self.cum_volume_list = []
        self.cum_time_list = []

    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.one_minute_bar_price_list.append(bar.close_price)
        self.one_minute_bar_volume_list.append(bar.volume)
        dollar_amount = np.sum(
            np.array(
                self.one_minute_bar_price_list) *
            np.array(
                self.one_minute_bar_volume_list))

        if dollar_amount >= self.dollar_threshold:

            high_price = np.max(self.one_minute_bar_price_list)
            close = self.one_minute_bar_price_list[-1]
            low_price = np.min(self.one_minute_bar_price_list)
            open_price = self.one_minute_bar_price_list[0]
            volume = np.sum(self.one_minute_bar_volume_list)

            self.high_list.append(high_price)
            self.close_list.append(close)
            self.open_list.append(open_price)
            self.volume_list.append(volume)
            self.low_list.append(low_price)
            self.time_list.append(bar.datetime)
            self.one_minute_bar_num_list.append(
                len(self.one_minute_bar_price_list))

            self.one_minute_bar_volume_list = []
            self.one_minute_bar_price_list = []
            # 交易策略信号计算在dollar合成之后
            self.dollar_bar_finished = True

        if len(self.high_list) < self.init_dollar_bar_num:
            return

        if self.dollar_bar_finished:
            self.cancel_all()
            close_array = np.array(self.close_list)
            high_array = np.array(self.high_list)
            low_array = np.array(self.low_list)
            open_array = np.array(self.open_list)
            volume_array = np.array(self.volume_list)

            if close_array.shape[0] < self.rsi_window:
                self.dollar_bar_finished = False
                return

            self.rsi_value = talib.RSI(close_array, self.rsi_window)[-1]
            if self.rsi_value > self.rsi_up_threshold:
                self.long_trend_cum += 1
            elif self.rsi_value < 100 - self.rsi_up_threshold:
                self.short_trend_cum += 1
            if self.long_trend_cum >= self.long_trend_cum_threshold or self.short_trend_cum >= self.short_trend_cum_threshold:
                self.cum_filtered = True

            if self.cum_filtered:
                self.cum_close_list.append(close_array[-1])
                self.cum_high_list.append(high_array[-1])
                self.cum_low_list.append(low_array[-1])
                self.cum_open_list.append(open_array[-1])
                self.cum_volume_list.append(volume_array[-1])
                self.cum_time_list.append(bar.datetime)

                if len(
                        self.cum_open_list) < max(
                        self.sma_long_window,
                        self.atr_window):
                    self.dollar_bar_finished = False
                    self.cum_filtered = False
                    self.long_trend_cum = 0
                    self.short_trend_cum = 0
                    return

                cum_close_array = np.array(self.cum_close_list)
                cum_high_array = np.array(self.cum_high_list)
                cum_low_array = np.array(self.cum_low_list)
                cum_open_array = np.array(self.cum_open_list)
                sma_short_window_array = talib.SMA(
                    cum_close_array, self.sma_short_window)
                sma_long_window_array = talib.SMA(
                    cum_close_array, self.sma_long_window)

                atr_array = talib.ATR(
                    cum_high_array,
                    cum_low_array,
                    cum_close_array,
                    self.atr_window)
                self.atr_value = atr_array[-1]

                if sma_long_window_array[-2] > sma_short_window_array[-2] and sma_long_window_array[-1] < sma_short_window_array[-1]:
                    self.long_trend = True
                    self.long_trend_days = 0
                elif sma_long_window_array[-2] < sma_short_window_array[-2] and sma_long_window_array[-1] > sma_short_window_array[-1]:
                    self.short_trend = True
                    self.short_trend_days = 0

                if self.short_trend_days != np.inf:
                    self.short_trend_days += 1
                elif self.long_trend_days != np.inf:
                    self.long_trend_days += 1

                if self.pos == 0:
                    self.stop_price = 0
                    self.exit_price = 0
                    self.hold_bar_num = 0
                    if self.short_trend and self.short_trend_days < self.cross_over_day:
                        self.short(bar.close_price - 5, self.fixed_size)
                        self.short_order_record.append(bar.close_price - 5)

                    elif self.long_trend and self.long_trend_days < self.cross_over_day:
                        self.buy(bar.close_price + 5, self.fixed_size)
                        self.long_order_record.append(bar.close_price + 5)

                elif self.pos > 0:
                    self.long_trend = False
                    self.long_trend_days = np.inf
                    buy_order_price = self.long_order_record[-1]
                    self.stop_price = buy_order_price * (1 - self.exit_loss)
                    self.exit_price = buy_order_price * \
                        (1 + self.exit_return) - self.hold_bar_num * self.atr_value * self.atr_multiplier
                    if bar.close_price <= self.exit_price:
                        self.sell(bar.close_price * 0.99, abs(self.pos))
                    elif bar.close_price >= self.exit_price:
                        self.sell(bar.close_price * 0.99, abs(self.pos))
                    self.hold_bar_num += 1

                elif self.pos < 0:
                    self.short_trend = False
                    self.short_trend_days = np.inf
                    sell_order_price = self.short_order_record[-1]
                    self.stop_price = sell_order_price * (1 + self.exit_loss)

                    self.exit_price = sell_order_price * \
                        (1 - self.exit_return) + self.hold_bar_num * self.atr_value * self.atr_multiplier
                    if bar.close_price >= self.stop_price:
                        self.cover(bar.close_price * 1.01, abs(self.pos))
                    elif bar.close_price <= self.exit_price:
                        self.cover(bar.close_price * 1.01, abs(self.pos))

                    self.hold_bar_num += 1

                self.dollar_bar_finished = False
                self.cum_filtered = False
                self.long_trend_cum = 0
                self.short_trend_cum = 0

    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
コード例 #28
0
class AtrRsiStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员" # 第一个参数最好是作者,万一泄露时还可以证明是你的

    ## 下面6个是定义策略的参数,参数初始化给默认值
    atr_length = 22
    atr_ma_length = 10
    rsi_length = 5
    rsi_entry = 16   # 计算初始化的时候计算rsi买入或者卖出的阈值
    trailing_percent = 0.8
    fixed_size = 1

    
    ## 下面6个是定义策略的默认变量,变量默认给0,代表初始化
    atr_value = 0
    atr_ma = 0
    rsi_value = 0
    rsi_buy = 0
    rsi_sell = 0
    intra_trade_high = 0
    intra_trade_low = 0

    ## 将策略参数的名称字符串放入parameters列表,告诉vnpy这些是参数
    parameters = [
        "atr_length",
        "atr_ma_length",
        "rsi_length",
        "rsi_entry",
        "trailing_percent",
        "fixed_size"
    ]
    ## 将策略变量的名称字符串放入variables列表,告诉vnpy这些是变量
    variables = [
        "atr_value",
        "atr_ma",
        "rsi_value",
        "rsi_buy",
        "rsi_sell",
        "intra_trade_high",
        "intra_trade_low"
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """想显示在策略页面上的,仅仅用来临时存放和调度的临时变量,可以在__init__中进行定义"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar)
        self.am = ArrayManager()

    def on_init(self):
        """
        Callback when strategy is inited.击页面上初始化按钮执行本函数
        """
        self.write_log("策略初始化")

        self.rsi_buy = 50 + self.rsi_entry     # 定义超买区域
        self.rsi_sell = 50 - self.rsi_entry    # 定义超卖区域

        self.load_bar(10)  # cta策略必须在初始化时加载历史k线,把初始化状态算出来。如果是国内品种,如果至少要10天的历史k线计算,考虑到国内黄金周小长假连同周末经常停止交易10天左右,那么这里最好加载20天的历史k线

    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. 实盘中CTP或Bitmex接口每次推送tick变化时都会调用
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update. K线推送的函数。一定是1分钟k线的推送。用于回测,实盘柜台只推送tick
        """
        self.cancel_all()  # 每根k线推送后,撤销之前一根K线上下的所有未成交订单,会导致比较频繁的撤单

        am = self.am        # 实例化ArrayManager对象
        am.update_bar(bar)  # 将k线推送到ArrayManager
        if not am.inited:   # 如判断ArrayManager初始化状态,如果ArrayManager没有完成初始化状态,就不管他
            return

        atr_array = am.atr(self.atr_length, array=True)  # 传入atr的时间窗口,创建atr时间序列
        self.atr_value = atr_array[-1]      # 取最近的atr数值为atr_value
        self.atr_ma = atr_array[-self.atr_ma_length:].mean()  # 给atr时间序列取最老的atr_ma_length个数据的平均值,赋值给atr_ma
        self.rsi_value = am.rsi(self.rsi_length)   # 传入rsi的时间窗口创建rsi指标时间序列
        ## 没有持仓的情况
        if self.pos == 0:
            self.intra_trade_high = bar.high_price   # 将当根bar的最高价赋值,下面似乎没有用到这个值
            self.intra_trade_low = bar.low_price     # 将当根bar的最低价赋值,下面似乎没有用到这个值
            ## 进场逻辑(5行代码)
            if self.atr_value > self.atr_ma:         # 【过滤】当atr超过其10天均值时,意味着短期波动显著上升
                if self.rsi_value > self.rsi_buy:    # 【信号】当最近的rsi进入超买区域
                    self.buy(bar.close_price + 5, self.fixed_size)  # 按照当根bar的收盘价+5个bp下多头限价单,固定仓位1手
                elif self.rsi_value < self.rsi_sell: # 【信号】当rsi进入超卖区域
                    self.short(bar.close_price - 5, self.fixed_size)  # 按照当根bar的收盘价-5个bp下空头限价单,固定仓位1手
        ## 出场策略,移动止损方法
        ## 持有多头仓位的情况
        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)  # 跟踪买入后价格最高到过什么位置
            self.intra_trade_low = bar.low_price   # 记录当根k线最低价水平

            long_stop = self.intra_trade_high * \
                (1 - self.trailing_percent / 100)         # 最高价*价格固定百分比(回撤)作为出场位置
            self.sell(long_stop, abs(self.pos), stop=True)  # 使用停止单卖出,目的在于不等待价格走完,而是当价格下跌超出回撤比例时,立刻执行卖出操作
        ## 持有空头仓位的情况
        elif self.pos < 0:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)   # 跟踪买入后价格最低到过什么位置
            self.intra_trade_high = bar.high_price

            short_stop = self.intra_trade_low * \
                (1 + self.trailing_percent / 100)
            self.cover(short_stop, abs(self.pos), stop=True)

        self.put_event()   # 刷新vntrader界面上的数据

    def on_order(self, order: OrderData):
        """
        Callback of new order data update. 委托状态推送:发出委托-券商收到-推到交易所-看到委托在交易所中某档挂单-反馈“未成交状态”-成交1手-委托状态变成“部分成交-成交全部-委托状态变成“全部成交”
        """
        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
コード例 #29
0
class IndicatorStrategy(CtaTemplate):
    """
    目前使用中轨加速,可以考虑使用另外一根均线来加速,这样可以避免在开仓时被平。
    """
    author = "yunya"

    open_window = 15
    boll_window = 10
    slow_length = 55
    fixed_size = 1

    condition_long = False
    condition_short = False
    indicator_current = 0
    indicator_last = 0
    boll_up_current = 0
    boll_up_last = 0
    boll_down_current = 0
    boll_down_last = 0
    boll_mid_current = 0
    boll_mid_last = 0

    parameters = [
        "open_window",
        "fast_length",
        "slow_length",
        "fixed_size",
    ]

    variables = [
        "condition_long",
        "condition_short",
        "indicator_current",
        "indicator_last",
        "boll_up_current",
        "boll_up_last",
        "boll_down_current",
        "boll_down_last",
        "boll_mid_current",
        "boll_mid_last",
    ]

    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.open_window, self.on_xmin_bar)
        self.am = ArrayManager(self.boll_window * 3 + 50)

        self.count: int = 0
        self.count_boll: int = 0
        self.indicator_inited: bool = False
        self.boll_inited: bool = False
        self.mtm_size: int = self.slow_length

        self.indicator_np_array: np.ndarray = np.zeros(self.boll_window * 3 +
                                                       5)

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

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

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

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

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.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

        indicator = self.indicator_array(self.am.high, self.am.low,
                                         self.am.close, self.boll_window,
                                         self.indicator_np_array)

        if not self.indicator_inited:
            return

        # 自适应布林带
        median = ta.SMA(indicator, self.boll_window)
        std = np.std(indicator, axis=0)
        z_score = abs(indicator - median) / std
        m_z = z_score[-self.boll_window - 1:-2].max()
        up = median + std * m_z
        dn = median - std * m_z

        if indicator[-1] > up[-1] and indicator[-2] <= up[-2]:
            print("开多" + "\n")
        elif indicator[-1] < median[-1] and indicator[-2] >= median[-2]:
            print("平多" + "\n")

        if indicator[-1] < dn[-1] and indicator[-2] >= dn[-2]:
            print("开空" + "\n")
        elif indicator[-1] > median[-1] and indicator[-2] <= median[-2]:
            print("平空" + "\n")

        #
        # exit()
        #
        # # 计算 大布林
        # sma_array = am.sma(self.slow_length, True)
        # std_array = am.std(self.slow_length, True)
        # dev = abs(self.am.close[:-1] - sma_array[:-1]) / std_array[:-1]
        #
        # dev_max = dev[-self.slow_length:].mean()
        # boll_up_max_array = sma_array + std_array * dev_max
        # boll_down_max_array = sma_array - std_array * dev_max
        #
        # boll_up_max = boll_up_max_array[-1]
        # boll_down_max = boll_down_max_array[-1]
        #
        # # 大于大周期布林上轨,不做空,小于布林下轨,不做多
        # if bar.close_price > boll_up_max:
        #     self.condition_long = True
        # else:
        #     self.condition_long = False
        #
        # if bar.close_price < boll_down_max:
        #     self.condition_short = True
        # else:
        #     self.condition_short = False
        #
        # self.indicator_current = self.indicator[-1]
        # self.indicator_last = self.indicator[-2]
        # self.boll_up_current = self.boll_up_array[-1]
        # self.boll_up_last = self.boll_up_array[-2]
        # self.boll_down_current = self.boll_down_array[-1]
        # self.boll_down_last = self.boll_down_array[-2]
        # self.boll_mid_current = self.boll_mid_array[-1]
        # self.boll_mid_last = self.boll_mid_array[-2]
        #
        # # 如果没有仓位,两条布林window一样
        # if self.pos == 0:
        #     condition1 = self.indicator_current > self.boll_up_current
        #     condition2 = self.indicator_last <= self.boll_up_last
        #
        #     condition3 = self.indicator_current < self.boll_up_current
        #     condition4 = self.indicator_last >= self.boll_down_last
        #
        #     if condition1 and condition2:
        #         # 在大网下轨,不做多
        #         if self.condition_short:
        #             self.buy(bar.close_price + 10, self.fixed_size)
        #
        #     elif condition3 and condition4:
        #         # 在大网上轨,不做空
        #         if self.condition_long:
        #             self.short(bar.close_price - 10, self.fixed_size)
        #
        # elif self.pos > 0:
        #     condition1 = self.indicator_current < self.boll_mid_current
        #     condition2 = self.indicator_last >= self.boll_mid_last
        #     if condition1 and condition2:
        #         self.sell(bar.close_price - 10, abs(self.pos))
        #
        # elif self.pos < 0:
        #     condition1 = self.indicator_current > self.boll_mid_current
        #     condition2 = self.indicator_last <= self.boll_mid_last
        #     if condition1 and condition2:
        #         self.cover(bar.close_price + 10, abs(self.pos))
        #
        # self.put_event()
        # self.sync_data()

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

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        pass
        # if trade.direction == Direction.LONG:
        #     self.trade_price_long = trade.price  # 成交最高价
        #     self.long_stop_trade = self.trade_price_long - self.atr_multiple * self.atr_value
        # else:
        #     self.trade_price_short = trade.price
        #     self.short_stop_trade = self.trade_price_short + self.atr_multiple * self.atr_value
        #
        # self.sync_data()
        # self.put_event()

    def atr_wd(self, high, low, close, n):
        """
        计算 atr 相对 close 的波动因子
        """
        atr = ta.ATR(high, low, close, n)
        ma = ta.SMA(close, n)

        wd_atr = atr / ma

        return wd_atr[-1]

    def mtm_atr(self, high, low, close, n):
        """
        1、计算 mtm值(用去掉量纲方式计算)
        2、用 atr 的方式计算得到 mtm_atr
        """
        # 计算MTM值
        high_shift = shift(high, 1)
        low_shift = shift(low, 1)
        close_shift = shift(close, 1)

        # 补全
        high_shift[0] = high_shift[1]
        low_shift[0] = low_shift[1]
        close_shift[0] = close_shift[1]

        # 计算mtm
        mtm_high = high / high_shift - 1
        mtm_low = low / low_shift - 1
        mtm_close = close / close_shift - 1

        mtm_atr = ta.ATR(mtm_high, mtm_low, mtm_close, n)

        return mtm_atr[-1]

    def mem_atr_mean_array(self, high, low, close, n):
        """
        :return:
        """
        # 计算MTM值
        high_shift = shift(high, 1)
        low_shift = shift(low, 1)
        close_shift = shift(close, 1)

        # 补全
        high_shift[0] = high_shift[1]
        low_shift[0] = low_shift[1]
        close_shift[0] = close_shift[1]

        # 计算mtm
        mtm_high = high / high_shift - 1
        mtm_low = low / low_shift - 1
        mtm_close = close / close_shift - 1

        # 计算MTM均值
        mtm_high_mean = ta.SMA(mtm_high, n)
        mtm_low_mean = ta.SMA(mtm_low, n)
        mtm_close_mean = ta.SMA(mtm_close, n)
        mtm_mean_atr = ta.ATR(mtm_high_mean, mtm_low_mean, mtm_close_mean, n)

        return mtm_mean_atr[-1]

    def indicator_array(self, high, low, close, n, indicator_np):
        """
        :return:
        """
        self.count += 1
        if not self.indicator_inited and self.count >= self.mtm_size:
            self.indicator_inited = True

        indicator_np[:-1] = indicator_np[1:]
        close_shift = shift(close, 1)
        close_shift[0] = close_shift[1]
        mtm_close = close / close_shift - 1
        close_mtm = ta.SMA(mtm_close, n)[-1]

        atr_wd = self.atr_wd(high, low, close, n)
        mtm_atr = self.mtm_atr(high, low, close, n)
        mtm_atr_mean = self.mem_atr_mean_array(high, low, close, n)

        indicator = close_mtm * atr_wd * mtm_atr * mtm_atr_mean
        indicator_np[-1] = indicator

        return indicator_np
コード例 #30
0
class TSMyoImpulseStrategy(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)  # 商品下午

    exit_counter = 0
    bar_tr = 0
    bar_atr = 0
    long_open = 0
    short_open = 0
    long_stop = 0
    short_stop = 0
    tr_k1 = 3.0
    tr_k2 = 2.0
    close_range = 0.2
    xmin = 20
    fixed_size = 1

    parameters = ["tr_k1", "tr_k2", "close_range", "xmin"]
    variables = [
        "exit_counter", "bar_tr", "bar_atr", "long_open", "long_stop",
        "short_open", "short_stop"
    ]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(TSMyoImpulseStrategy, self).__init__(cta_engine, strategy_name,
                                                   vt_symbol, setting)
        self.bg = BarGenerator(self.on_bar, self.xmin, self.on_xmin_bar)
        self.am = TSMArrayManager()
        # 策略自身订单管理
        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
        """
        pass

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

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

        self.cancel_all()

        if bar.datetime.time() < self.exit_time:
            if self.pos == 0:
                if self.long_open:
                    # 开多
                    if self.active_orderids:
                        self.write_log("撤单不干净,无法挂单")
                        return
                    orderids = self.buy(self.long_open,
                                        self.fixed_size,
                                        lock=True,
                                        stop=True)
                    self.active_orderids.extend(orderids)
                elif self.short_open:
                    # 开空
                    if self.active_orderids:
                        self.write_log("撤单不干净,无法挂单")
                        return
                    orderids = self.short(self.short_open,
                                          self.fixed_size,
                                          lock=True,
                                          stop=True)
                    self.active_orderids.extend(orderids)

            if self.pos > 0:
                self.exit_counter += 1
                if self.exit_counter > self.xmin:
                    if self.long_stop:
                        # 停止单止损
                        if self.active_orderids:
                            self.write_log("撤单不干净,无法挂单")
                            return
                        orderids = self.sell(self.long_stop,
                                             self.fixed_size,
                                             lock=True,
                                             stop=True)
                        self.active_orderids.extend(orderids)

            if self.pos < 0:
                self.exit_counter += 1
                if self.exit_counter > self.xmin:
                    if self.short_stop:
                        # 停止单止损
                        if self.active_orderids:
                            self.write_log("撤单不干净,无法挂单")
                            return
                        orderids = self.cover(self.long_stop,
                                              self.fixed_size,
                                              lock=True,
                                              stop=True)
                        self.active_orderids.extend(orderids)

        # 日内交易
        else:
            if self.pos > 0:
                # 平多
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.sell(bar.close_price,
                                     self.fixed_size,
                                     lock=True)
                self.active_orderids.extend(orderids)
            if self.pos < 0:
                # 平空
                if self.active_orderids:
                    self.write_log("撤单不干净,无法挂单")
                    return
                orderids = self.cover(bar.close_price,
                                      self.fixed_size,
                                      lock=True)
                self.active_orderids.extend(orderids)

        self.put_event()

    def on_xmin_bar(self, bar: BarData):
        """
        1.开盘/盘中信号生成
        2.生成止损价位
        """
        # for debug 930为930-945bar时间戳
        # self.cta_engine.output(bar.datetime.time())

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

        # 当前bar的TR和之前bars的ATR
        self.bar_tr = am.tr(False)
        atr_array = am.atr(240 / self.xmin, True)
        self.bar_atr = atr_array[-2]

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

        last_bar = self.bars[-2]
        # 第一根xminbar
        if last_bar.datetime.date() != bar.datetime.date():
            if self.bar_tr > self.bar_atr * self.tr_k1:
                # 计算close是否收在两端close_range内
                lv = (bar.close_price - bar.low_price) / (bar.high_price -
                                                          bar.low_price)
                if lv < self.close_range:
                    # 快速下跌波动且close收低,开多信号
                    self.long_open = bar.close_price
                    self.long_stop = bar.low_price
                    self.short_stop = 0
                    self.short_open = 0

                elif lv > (1 - self.close_range):
                    # 快速上涨波动且close收高,开空信号
                    self.short_open = bar.close_price
                    self.short_stop = bar.high_price
                    self.long_open = 0
                    self.long_stop = 0

        elif self.pos == 0:
            if self.bar_tr > self.bar_atr * self.tr_k2:
                # 计算close是否收在两端close_range内
                lv = (bar.close_price - bar.low_price) / (bar.high_price -
                                                          bar.low_price)
                if lv < self.close_range:
                    # 快速下跌波动且close收低,开多信号
                    self.long_open = bar.close_price
                    self.long_stop = bar.low_price
                    self.short_stop = 0
                    self.short_open = 0

                elif lv > (1 - self.close_range):
                    # 快速上涨波动且close收高,开空信号
                    self.short_open = bar.close_price
                    self.short_stop = bar.high_price
                    self.long_open = 0
                    self.long_stop = 0

        self.put_event()

    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):
        """
        1.重置倒计时
        """
        if self.pos == 0:
            self.exit_counter = 0
        # 邮寄提醒
        self.send_email(
            f"{trade.vt_symbol}在{trade.time}成交,价格{trade.price},方向{trade.direction}{trade.offset},数量{trade.volume}"
        )
        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)
コード例 #31
0
class TSMyoBollSARStrategy(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线周期
    boll_len = 26  # 布林带周期
    boll_nstd = 2.5  # 布林带宽
    low_std_len = 6  # 波动率持续低迷周期
    low_std_value = 9.2  # 波动率阈值

    setup_bar = 85  # 基础拟合分钟数

    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 = [
        'low_std_value', 'low_std_len', 'boll_nstd', 'boll_len', '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(TSMyoBollSARStrategy, 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.fit_bar * self.boll_len:
            return

        boll_up, boll_down = am.boll(self.boll_len, self.boll_nstd, False)

        std_array = am.std(self.low_std_len, True)
        std = std_array[-2]

        if self.pos == 0 and std < self.low_std_value:
            if bar.close_price > boll_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 < boll_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)
コード例 #32
0
class SuperComboStrategy(CtaTemplate):
    """"""
    author = "用Python的交易员"

    # Parameters

    thrust_long = 0.34
    trailing_long = 0.35

    thrust_short = 0.4
    trailing_short = 0.8

    trading_size = 1

    # Variables
    day_open = 0
    day_high = 0
    day_low = 0
    sum_range = 0

    long_entry = 0
    short_entry = 0
    intra_trade_high = 0
    intra_trade_low = 0
    long_stop = 0
    short_stop = 0
    last_bar = None

    parameters = [
        "thrust_long", "trailing_long", "thrust_short", "trailing_short",
        "trading_size"
    ]

    variables = [
        "day_high", "day_low", "sum_range", "long_entry", "short_entry",
        "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)

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

        self.load_bar(10)

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

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

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

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

        if not self.last_bar:
            self.last_bar = bar
            return

        # For a new day, update all entry_range
        if bar.datetime.day != self.last_bar.datetime.day:
            self.sum_range = self.day_high - self.day_low
            self.day_open = bar.open_price
            self.day_high = bar.high_price
            self.day_low = bar.low_price

            long_entry_range = self.thrust_long * self.sum_range
            self.long_entry = self.day_open + long_entry_range

            short_entry_range = self.thrust_short * self.sum_range
            self.short_entry = self.day_open - short_entry_range
        # Otherwise update daily high/low price
        else:
            self.day_high = max(self.day_high, bar.high_price)
            self.day_low = min(self.day_low, bar.low_price)

            self.long_entry = max(self.long_entry, self.day_high)
            self.short_entry = min(self.short_entry, self.day_low)

        # Only open positions before 14:55
        if bar.datetime.time() < time(14, 55):
            # No pos
            if not self.pos:
                self.intra_trade_low = bar.low_price
                self.intra_trade_high = bar.high_price

                if bar.close_price > self.day_open:
                    self.buy(self.long_entry,
                             self.trading_size,
                             True,
                             lock=True)
                else:
                    self.short(self.short_entry,
                               self.trading_size,
                               True,
                               lock=True)
            # Long pos
            elif self.pos > 0:
                self.intra_trade_high = max(self.intra_trade_high,
                                            bar.high_price)
                self.long_stop = self.intra_trade_high * \
                    (1 - self.trailing_long / 100)
                self.sell(self.long_stop, abs(self.pos), True, True)
            # Short pos
            else:
                self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
                self.short_stop = self.intra_trade_low * \
                    (1 + self.trailing_short / 100)
                self.cover(self.short_stop, abs(self.pos), True, True)
        # Close all positions after 14:55
        else:
            if self.pos > 0:
                self.sell(bar.close_price - 10, abs(self.pos), lock=True)
            elif self.pos < 0:
                self.cover(bar.close_price + 10, abs(self.pos), lock=True)

        self.last_bar = bar
        self.put_event()

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

    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
コード例 #33
0
class DualThrustStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    fixed_size = 1
    k1 = 0.4
    k2 = 0.6

    bars = []

    day_open = 0
    day_high = 0
    day_low = 0

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

    long_entered = False
    short_entered = False

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

    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.am = ArrayManager()
        self.bars = []

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

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

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

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

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

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

        if last_bar.datetime.date() != bar.datetime.date():
            if self.day_high:
                self.range = self.day_high - self.day_low
                self.long_entry = bar.open_price + self.k1 * self.range
                self.short_entry = bar.open_price - self.k2 * self.range

            self.day_open = bar.open_price
            self.day_high = bar.high_price
            self.day_low = bar.low_price

            self.long_entered = False
            self.short_entered = False
        else:
            self.day_high = max(self.day_high, bar.high_price)
            self.day_low = min(self.day_low, bar.low_price)

        if not self.range:
            return

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

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

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

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

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

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

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

        else:
            if self.pos > 0:
                self.sell(bar.close_price * 0.99, abs(self.pos))
            elif self.pos < 0:
                self.cover(bar.close_price * 1.01, abs(self.pos))

        self.put_event()

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

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

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
コード例 #34
0
ファイル: dual_thrust_strategy.py プロジェクト: Alyle/vnpy
class DualThrustStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    fixed_size = 1
    k1 = 0.4
    k2 = 0.6

    bars = []

    day_open = 0
    day_high = 0
    day_low = 0

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

    long_entered = False
    short_entered = False

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

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

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

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

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

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

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

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

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

        if last_bar.datetime.date() != bar.datetime.date():
            if self.day_high:
                self.range = self.day_high - self.day_low
                self.long_entry = bar.open_price + self.k1 * self.range
                self.short_entry = bar.open_price - self.k2 * self.range

            self.day_open = bar.open_price
            self.day_high = bar.high_price
            self.day_low = bar.low_price

            self.long_entered = False
            self.short_entered = False
        else:
            self.day_high = max(self.day_high, bar.high_price)
            self.day_low = min(self.day_low, bar.low_price)

        if not self.range:
            return

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

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

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

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

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

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

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

        else:
            if self.pos > 0:
                self.sell(bar.close_price * 0.99, abs(self.pos))
            elif self.pos < 0:
                self.cover(bar.close_price * 1.01, abs(self.pos))

        self.put_event()

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

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

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass
コード例 #35
0
class CincoStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    boll_window = 51
    boll_dev = 2.5
    atr_window = 4
    risk_level = 200
    trailing_short = 0.8
    trailing_long = 0.5

    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
    interval = 15

    parameters = [
        "boll_window", "boll_dev", "risk_level", "atr_window", "interval",
        "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, self.interval, 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)
        boll_width = self.boll_up - self.boll_down

        if self.pos == 0:
            atr_fix = am.atr(self.atr_window)
            self.trading_size = int(self.risk_level / atr_fix)

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

            self.buy(self.boll_up, self.trading_size, True)
            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.trailing_long * boll_width)
            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.trailing_short * boll_width)
            self.cover(self.short_stop, abs(self.pos), True)

        self.put_event()
        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
コード例 #36
0
ファイル: king_keltner_strategy.py プロジェクト: Alyle/vnpy
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
コード例 #37
0
ファイル: kk_demo_strategy_0.py プロジェクト: hun1982qhu/CTA
class DemoStrategy0(CtaTemplate):
    """"""

    author = "用Python的交易员"

    dc_length = 11
    trailing_percent = 0.8
    fixed_size = 1

    dc_up = 0
    dc_down = 0
    intra_trade_high = 0
    intra_trade_low = 0

    parameters = ["dc_length", "trailing_percent", "fixed_size"]
    variables = ["dc_up", "dc_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()

    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):
        """"""
        # 全撤
        self.cancel_all()

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

        # 计算指标
        self.dc_up, self.dc_down = am.donchian(self.dc_length)

        # 检查信号
        if not self.pos:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            self.buy(self.dc_up, self.fixed_size, True)
            self.short(self.dc_down, self.fixed_size, True)
        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.intra_trade_low = bar.low_price

            long_stop = self.intra_trade_high * (1 -
                                                 self.trailing_percent / 100)
            if bar.low_price <= long_stop:
                self.sell(bar.close_price - 10, 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)

            short_stop = self.intra_trade_low * (1 +
                                                 self.trailing_percent / 100)
            if bar.high_price >= short_stop:
                self.cover(bar.close_price + 10, 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
コード例 #38
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
コード例 #39
0
ファイル: double_ma_strategy.py プロジェクト: Alyle/vnpy
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

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

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

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

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

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

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

        self.put_event()

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

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

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

        fast_ma = am.sma(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