Exemple #1
0
    def calc_swing(self, bars: List[Bar], direction, default, maxLookBack,
                   minDelta):
        series = BarSeries.HIGH if direction > 0 else BarSeries.LOW
        for length in range(1, min(self.max_swing_length + 1,
                                   maxLookBack - 1)):
            cex = lowest(bars, length, 1, series)
            ex = highest(bars, length, 1, series)
            preRange = highest(bars, 2, length + 1, series)
            e = ex
            if direction < 0:
                e = cex
                preRange = lowest(bars, 2, length + 1, series)
            if direction * (e - preRange) > 0 \
                    and direction * (e - get_bar_value(bars[length + 1], series)) > minDelta \
                    and direction * (e - get_bar_value(bars[0], series)) > minDelta:
                return e + direction * minDelta

        return default
Exemple #2
0
    def calc_trail(self, bars: List[Bar], offset, direction, move_length,
                   threshold, maxDist):
        if direction > 0:
            range = highest(bars, 2, offset + move_length, BarSeries.HIGH)
            move = bars[offset].high - range
            last_value = bars[0].low
            offset_value = bars[offset].low
        else:
            range = lowest(bars, 2, offset + move_length, BarSeries.LOW)
            move = range - bars[offset].low
            last_value = bars[0].high
            offset_value = bars[offset].high

        last_data: Data = self.get_data(bars[1])
        if last_data is None:
            # defaults
            last_since_reset = 0
            last_buffer = 0
        else:
            last_buffer = last_data.buffer
            if direction > 0:
                last_since_reset = last_data.sinceLongReset
            else:
                last_since_reset = last_data.sinceShortReset

        if move > threshold and last_since_reset >= move_length and (
                offset_value - last_value) * direction < 0 and (
                    range - last_value) * direction < 0:
            sinceReset = move_length + 1
        else:
            sinceReset = min(last_since_reset + 1, self.max_look_back)

        if direction > 0:
            trail = max(
                lowest(bars, sinceReset - 1, 0, BarSeries.LOW) - maxDist,
                lowest(bars, sinceReset, 0, BarSeries.LOW) - last_buffer)
        else:
            trail = min(
                highest(bars, sinceReset - 1, 0, BarSeries.HIGH) + maxDist,
                highest(bars, sinceReset, 0, BarSeries.HIGH) + last_buffer)

        return [sinceReset, trail]
Exemple #3
0
    def process_bar(self, bars: List[Bar]):
        prevData: Data = self.get_data(bars[1])

        swingHigh = prevData.swingHigh if prevData is not None else None
        highestAfter = highest(bars, self.after, 1, BarSeries.HIGH)
        candidate = bars[self.after + 1].high
        highestBefore = highest(bars, self.before, self.after + 2,
                                BarSeries.HIGH)
        if highestAfter <= candidate and highestBefore <= candidate:
            swingHigh = candidate
        if swingHigh is not None and bars[0].high > swingHigh:
            swingHigh = None

        swingLow = prevData.swingLow if prevData is not None else None
        lowestAfter = lowest(bars, self.after, 1, BarSeries.LOW)
        candidate = bars[self.after + 1].low
        lowestBefore = lowest(bars, self.before, self.after + 2, BarSeries.LOW)
        if lowestAfter >= candidate and lowestBefore >= candidate:
            swingLow = candidate
        if swingLow is not None and bars[0].low < swingLow:
            swingLow = None

        self.write_data(bars[0], Data(swingHigh=swingHigh, swingLow=swingLow))
Exemple #4
0
    def open_orders(self, is_new_bar, directionFilter, bars, account,
                    open_positions):
        if (not is_new_bar) or len(bars) < self.min_bars_needed():
            return  # only open orders on beginning of bar

        if not self.entries_allowed(bars):
            self.logger.info("no entries allowed")
            return

        # check for signal. we are at the open of the new bar. so bars[0] contains of only 1 tick.
        # we look at data bars[1] and bars[2]
        prevFast = self.fastMA.get_data(bars[2])
        currentFast = self.fastMA.get_data(bars[1])
        prevSlow = self.slowMA.get_data(bars[2])
        currentSlow = self.slowMA.get_data(bars[1])
        swingData: Data = self.swings.get_data(bars[1])  # for stops

        # include the expected slipage in the risk calculation
        expectedEntrySplipagePerc = 0.0015
        expectedExitSlipagePerc = 0.0015
        signalId = "MACross+" + str(bars[0].tstamp)

        if prevFast <= prevSlow and currentFast > currentSlow:
            # cross up -> long entry
            entry = bars[0].open  # current price
            stop = swingData.swingLow
            if stop is None:
                stop = lowest(bars, self.swings.before + self.swings.after, 1,
                              BarSeries.LOW)
            amount = self.calc_pos_size(
                risk=self.risk_factor,
                exitPrice=stop * (1 - expectedExitSlipagePerc),
                entry=entry * (1 + expectedEntrySplipagePerc))

            # open the position and save it
            posId = TradingBot.full_pos_id(signalId, PositionDirection.LONG)
            pos = Position(id=posId,
                           entry=entry,
                           amount=amount,
                           stop=stop,
                           tstamp=bars[0].tstamp)
            open_positions[posId] = pos
            # send entry as market, immediatly send SL too
            self.order_interface.send_order(
                Order(orderId=TradingBot.generate_order_id(
                    posId, OrderType.ENTRY),
                      amount=amount,
                      stop=None,
                      limit=None))
            self.order_interface.send_order(
                Order(orderId=TradingBot.generate_order_id(
                    posId, OrderType.SL),
                      amount=-amount,
                      stop=stop,
                      limit=None))
            pos.status = PositionStatus.OPEN

        elif prevFast >= prevSlow and currentFast < currentSlow:
            # cross down -> short entry
            entry = bars[0].open  # current price
            stop = swingData.swingHigh
            if stop is None:
                stop = highest(bars, self.swings.before + self.swings.after, 1,
                               BarSeries.HIGH)
            amount = self.calc_pos_size(
                risk=self.risk_factor,
                exitPrice=stop * (1 + expectedExitSlipagePerc),
                entry=entry * (1 - expectedEntrySplipagePerc))

            # open the position and save it
            posId = TradingBot.full_pos_id(signalId, PositionDirection.SHORT)
            pos = Position(id=posId,
                           entry=entry,
                           amount=amount,
                           stop=stop,
                           tstamp=bars[0].tstamp)
            open_positions[posId] = pos
            # send entry as market, immediatly send SL too
            self.order_interface.send_order(
                Order(orderId=TradingBot.generate_order_id(
                    posId, OrderType.ENTRY),
                      amount=amount,
                      stop=None,
                      limit=None))
            self.order_interface.send_order(
                Order(orderId=TradingBot.generate_order_id(
                    posId, OrderType.SL),
                      amount=-amount,
                      stop=stop,
                      limit=None))
            pos.status = PositionStatus.OPEN