Exemple #1
0
    def compute(self, timestamp, high, low, close):
        # Breakout Indicator Inputs
        bb_basis = ta_EMA(close, self._bb_L) if self._use_EMA else ta_SMA(
            close, self._bb_L)
        fast_ma = ta_EMA(close, self._fast_MA_L)

        # Deviation (a simple BBAND)
        # dev = ta_STDDEV(close, self._bb_L)
        # bb_dev_inner = self._base_multiplier * dev

        # Upper bands
        # inner_high = bb_basis + bb_dev_inner
        # Lower Bands
        # inner_low = bb_basis - bb_dev_inner

        # Calculate Awesome Oscillator
        hl2 = (high + low) * 0.5

        xSMA1_hl2 = ta_SMA(hl2, self._awesome_fast_L)
        xSMA2_hl2 = ta_SMA(hl2, self._awesome_slow_L)
        xSMA1_SMA2 = xSMA1_hl2 - xSMA2_hl2

        # Calculate direction of AO
        if xSMA1_SMA2[-1] >= 0:
            if xSMA1_SMA2[-1] > xSMA1_SMA2[-2]:
                AO = 1
            else:
                AO = 2
        else:
            if xSMA1_SMA2[-1] > xSMA1_SMA2[-2]:
                AO = -1
            else:
                AO = -2

        # Calc breakouts
        break_down = crossunder(
            fast_ma,
            bb_basis) and close[-1] < bb_basis[-1] and AO < 0  # abs(AO)==2
        break_up = crossover(
            fast_ma,
            bb_basis) and close[-1] > bb_basis[-1] and AO > 0  # abs(AO)==1

        self._signal = 1 if break_up else -1 if break_down else 0

        self._last_timestamp = timestamp

        return self._signal
Exemple #2
0
    def compute(self, timestamp, high, low, close):
        # Breakout Indicator Inputs
        bb_basis = ta_EMA(close, self._bb_L) if self._use_EMA else ta_SMA(
            close, self._bb_L)
        fast_ma = ta_EMA(close, self._fast_MA_L)

        # Calculate Awesome Oscillator
        hl2 = (high + low) * 0.5

        xSMA1_hl2 = ta_SMA(hl2, self._awesome_fast_L)
        xSMA2_hl2 = ta_SMA(hl2, self._awesome_slow_L)
        xSMA1_SMA2 = xSMA1_hl2 - xSMA2_hl2

        # Calculate direction of AO
        if xSMA1_SMA2[-1] >= 0:
            if xSMA1_SMA2[-1] > xSMA1_SMA2[-2]:
                AO = 1
            else:
                AO = 2
        else:
            if xSMA1_SMA2[-1] > xSMA1_SMA2[-2]:
                AO = -1
            else:
                AO = -2

        # Calc breakouts
        break_down = crossunder(
            fast_ma,
            bb_basis) and close[-1] < bb_basis[-1] and AO < 0  # abs(AO)==2
        break_up = crossover(
            fast_ma,
            bb_basis) and close[-1] > bb_basis[-1] and AO > 0  # abs(AO)==1

        self._signal = 1 if break_up else -1 if break_down else 0

        self._last_timestamp = timestamp

        return self._signal
Exemple #3
0
    def process(self, timeframe, timestamp):
        # process only at base timeframe
        if timeframe != self.base_timeframe:
            return

        # update data at tick level
        if timeframe == self.base_timeframe:
            self.gen_candles_from_ticks(timestamp)

        accept, compute = self.filter_market(timestamp)
        if not accept:
            return

        # and compute
        entries = []
        exits = []

        if compute:
            entries, exits = self.compute(timeframe, timestamp)

        #
        # global indicators
        #

        ref_price = self.timeframes[self.ref_timeframe].price.last
        # sma200 = self.timeframes[self.ref_timeframe].sma200.last
        ref_sma55 = self.timeframes[self.ref_timeframe].sma55.last
        ref_sma = self.timeframes[self.ref_timeframe].sma.last
        ref_ema = self.timeframes[self.ref_timeframe].ema.last

        #
        # compute the entry
        #

        retained_entries = []

        for entry in entries:
            # only allowed range of signal for entry
            if not (self.min_traded_timeframe <= entry.timeframe <=
                    self.max_traded_timeframe):
                continue

            # trade region
            if not self.check_regions(timestamp, self.instrument.market_bid,
                                      self.instrument.market_ofr, entry,
                                      self.region_allow):
                continue

            # ref timeframe is contrary
            if entry.direction > 0 and not self.timeframes[
                    self.sltp_timeframe].can_long:
                continue

            if entry.direction < 0 and not self.timeframes[
                    self.sltp_timeframe].can_short:
                continue

            # initial stop-loss
            atr_stop = self.timeframes[self.sltp_timeframe].atr.stop_loss(
                entry.dir)

            if entry.direction > 0:
                # and an initial target
                take_profit = self.timeframes[
                    self.ref_timeframe].pivotpoint.last_resistances[2]

                if atr_stop < self.instrument.open_exec_price(entry.dir):
                    entry.sl = atr_stop

                gain = (take_profit - entry.p) / entry.p
                loss = (entry.p - entry.sl) / entry.p

            elif entry.direction < 0:
                # and an initial target
                take_profit = self.timeframes[
                    self.ref_timeframe].pivotpoint.last_supports[2]

                if atr_stop > self.instrument.open_exec_price(entry.dir):
                    entry.sl = atr_stop

                gain = (entry.p - take_profit) / entry.p
                loss = (entry.sl - entry.p) / entry.p

            if loss != 0 and (gain / loss < 1.0):
                Terminal.inst().message(
                    "%s %s %s %s %s %s" %
                    (entry.p, entry.sl, take_profit, gain, loss,
                     (gain / loss)),
                    view="debug")
                continue

            # not enought potential profit
            if gain < 0.005:
                continue

            entry.tp = take_profit if gain > 0.005 else entry.p * 1.01
            entry.set('partial-take-profit', 1.0)

            # max loss at x%
            if loss > 0.035:
                if entry.direction > 0:
                    entry.sl = entry.price * (1 - 0.035)
                elif entry.direction < 0:
                    entry.sl = entry.price * (1 + 0.035)

                # or do not do the trade to risky
                # continue

            retained_entries.append(entry)

            # TP 50% entry
            # entry_50pc = StrategySignal(0, 0)
            # entry_50pc.dup(entry)
            # entry_50pc.tp = np.max(self.timeframes[self.sltp_timeframe].pivotpoint.resistances[0])#[-1]
            # entry_50pc.set('partial-take-profit', 0.25)

            # retained_entries.append(entry_50pc)

        #
        # process eventually exits signals
        #

        if self.trades:
            self.lock()

            for trade in self.trades:
                retained_exit = None

                # important if we dont want to update user controlled trades if it have some operations
                user_mgmt = trade.is_user_trade()

                for signal in exits:
                    # @todo how to managed exit region ?

                    # receive an exit signal of the timeframe of the trade
                    if signal.timeframe == trade.timeframe:
                        retained_exit = signal
                        break

                    # exit signal on reference timeframe
                    if signal.timeframe == self.ref_timeframe:
                        retained_exit = signal
                        break

                    # exit from any parent timeframe signal
                    # if signal.timeframe > trade.timeframe:
                    #     retained_exit = signal
                    #     break

                # can cancel a non filled trade if exit signal occurs before timeout (timeframe)
                # if trade.is_entry_timeout(timestamp, trade.timeframe):
                #     trader = self.strategy.trader()
                #     trade.cancel_open(trader)
                #     Terminal.inst().info("Canceled order (exit signal or entry timeout) %s" % (self.instrument.market_id,), view='default')
                #     continue

                if user_mgmt:
                    retained_exit = None

                # if trade.is_opened() and not trade.is_valid(timestamp, trade.timeframe):
                #     # @todo re-adjust entry
                #     Terminal.inst().info("Update order %s trade %s TODO" % (trade.id, self.instrument.market_id,), view='default')
                #     continue

                # only for active and currently not closing trades
                if not trade.is_active() or trade.is_closing(
                ) or trade.is_closed():
                    continue

                close_exec_price = self.instrument.close_exec_price(trade.dir)

                #
                # stop-loss update
                #

                # always need a target, even if user trade and a stop order
                update_tp = not trade.tp or not trade.has_limit_order()
                update_sl = not trade.sl or not trade.has_stop_order()

                # current sl/tp
                stop_loss = trade.sl
                take_profit = trade.tp

                # ATR stop-loss (long/short)
                atr_stop = self.timeframes[self.sltp_timeframe].atr.stop_loss(
                    trade.direction)
                if trade.direction > 0:
                    # long, greater or initial
                    if atr_stop > stop_loss and atr_stop < close_exec_price * 0.995:
                        stop_loss = atr_stop

                elif trade.direction < 0:
                    # short, lesser or initial
                    if (atr_stop < stop_loss or stop_loss <= 0
                        ) and atr_stop > close_exec_price * 1.005:
                        stop_loss = atr_stop

                # update take-profit if necessary, and trailing stop-loss
                # new_exit = self.update_exit(trade, close_exec_price, self.timeframes[self.ref_timeframe].price, self.timeframes[self.ref_timeframe].pointpivot)

                if self.timeframes[
                        self.ref_timeframe].pivotpoint.last_pivot > 0.0:
                    if trade.direction > 0:
                        # long
                        if close_exec_price > self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_resistances[2]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.resistances[2]):
                                update_tp = True

                            if stop_loss < self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_resistances[
                                        1]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_resistances[1]

                        elif close_exec_price > self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_resistances[1]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.resistances[1]):
                                update_tp = True

                            if stop_loss < self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_resistances[
                                        0]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_resistances[0]

                        elif close_exec_price > self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_resistances[0]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.resistances[0]):
                                update_tp = True

                            if stop_loss < self.timeframes[
                                    self.ref_timeframe].pivotpoint.last_pivot:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_pivot

                        elif close_exec_price > self.timeframes[
                                self.ref_timeframe].pivotpoint.last_pivot:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[
                                        self.ref_timeframe].pivotpoint.pivot):
                                update_tp = True

                            if stop_loss < self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_supports[0]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_supports[0]

                        elif close_exec_price > self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_supports[0]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.supports[0]):
                                update_tp = True

                            if trade.sl < self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_supports[1]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_supports[1]

                        elif close_exec_price > self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_supports[1]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.supports[1]):
                                update_tp = True

                            if trade.sl < self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_supports[2]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_supports[2]

                        elif close_exec_price > self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_supports[2]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.supports[2]):
                                update_tp = True

                            if close_exec_price < self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_supports[2]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_supports[2]

                    elif trade.direction < 0:
                        # short (could use the sign, but if we want a non symmetrical approch...)
                        if close_exec_price < self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_supports[2]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.supports[2]):
                                update_tp = True

                            if close_exec_price > self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_supports[2]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_supports[2]

                        elif close_exec_price < self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_supports[1]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.supports[1]):
                                update_tp = True

                            if trade.sl > self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_supports[2]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_supports[2]

                        elif close_exec_price < self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_supports[0]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.supports[0]):
                                update_tp = True

                            if trade.sl > self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_supports[1]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_supports[1]

                        elif close_exec_price < self.timeframes[
                                self.ref_timeframe].pivotpoint.last_pivot:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[
                                        self.ref_timeframe].pivotpoint.pivot):
                                update_tp = True

                            if stop_loss > self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_supports[0]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_supports[0]

                        elif close_exec_price < self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_resistances[0]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.resistances[0]):
                                update_tp = True

                            if stop_loss > self.timeframes[
                                    self.ref_timeframe].pivotpoint.last_pivot:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_pivot

                        elif close_exec_price < self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_resistances[1]:
                            if utils.crossover(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.resistances[1]):

                                update_tp = True
                            if stop_loss > self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_resistances[
                                        0]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_resistances[0]

                        elif close_exec_price < self.timeframes[
                                self.
                                ref_timeframe].pivotpoint.last_resistances[2]:
                            if utils.crossunder(
                                    self.timeframes[
                                        self.ref_timeframe].price.prices,
                                    self.timeframes[self.ref_timeframe].
                                    pivotpoint.resistances[2]):
                                update_tp = True

                            if stop_loss > self.timeframes[
                                    self.
                                    ref_timeframe].pivotpoint.last_resistances[
                                        1]:
                                update_sl = True
                                # stop_loss = self.timeframes[self.ref_timeframe].pivotpoint.last_resistances[1]

                    #
                    # target update
                    #

                    # enought potential profit (0.5% min target)
                    if trade.direction > 0:
                        take_profit = self.timeframes[
                            self.ref_timeframe].pivotpoint.last_resistances[
                                int(2 * trade.get('partial-take-profit', 0))]

                        # if take_profit <= trade.entry_price:
                        #     take_profit = trade.entry_price * 1.05

                        gain = (take_profit -
                                trade.entry_price) / trade.entry_price
                        loss = (trade.entry_price -
                                trade.sl) / trade.entry_price

                    elif trade.direction < 0:
                        take_profit = self.timeframes[
                            self.ref_timeframe].pivotpoint.last_supports[int(
                                2 * trade.get('partial-take-profit', 0))]

                        # if take_profit >= trade.entry_price:
                        #     take_profit = trade.entry_price * 0.95

                        gain = (trade.entry_price -
                                take_profit) / trade.entry_price
                        loss = (trade.sl -
                                trade.entry_price) / trade.entry_price

                # reevaluate the R:R
                # @todo

                # if gain < 0.005 and update_tp:
                #    ...

                if update_sl and stop_loss > 0:
                    stop_loss = self.instrument.adjust_price(stop_loss)

                    if trade.sl != stop_loss:
                        # logger.info("SL %s %s %s" % (update_sl, stop_loss, trade.sl))

                        delta_time = timestamp - trade.last_stop_loss[0]
                        num_orders = trade.last_stop_loss[1]

                        # too many stop-loss modifications in the timeframe
                        if not trade.has_stop_order(
                        ) or delta_time > 60.0:  #not ((self.sltp_max_rate > num_orders) and (delta_time < self.sltp_max_timeframe)):
                            try:
                                trade.modify_stop_loss(self.strategy.trader(),
                                                       self.instrument,
                                                       stop_loss)
                            except Exception as e:
                                logger.error(repr(e))

                            Terminal.inst().info("%s modify SL" % timestamp,
                                                 view="debug")
                        else:
                            trade.sl = stop_loss

                if update_tp and take_profit > 0:
                    take_profit = self.instrument.adjust_price(take_profit)

                    if trade.tp != take_profit:
                        logger.info("TP %s %s %s" %
                                    (update_tp, take_profit, trade.tp))

                        delta_time = timestamp - trade.last_take_profit[0]
                        num_orders = trade.last_take_profit[1]

                        # too many stop-loss modifications in the timeframe
                        if not trade.has_limit_order(
                        ) or delta_time > 60.0:  #not ((self.sltp_max_rate > num_orders) and (delta_time < self.sltp_max_timeframe)):
                            try:
                                trade.modify_take_profit(
                                    self.strategy.trader(), self.instrument,
                                    take_profit)
                            except Exception as e:
                                logger.error(repr(e))

                            Terminal.inst().info("%s modify TP" % timestamp,
                                                 view="debug")
                        else:
                            trade.tp = take_profit

                #
                # exit trade if an exit signal retained
                #

                if retained_exit:
                    self.process_exit(timestamp, trade, retained_exit.price)
                    Terminal.inst().info("Exit trade %s %s" %
                                         (self.instrument.symbol, trade.id),
                                         view='debug')

            self.unlock()

        # update actives trades
        self.update_trades(timestamp)

        # retained long entry do the order entry signal
        for entry in retained_entries:
            self.process_entry(timestamp, entry.dir, entry.price, entry.tp,
                               entry.sl, entry.timeframe,
                               entry.get('partial-take-profit', 0))

        # streaming
        self.stream()