For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See:

Renko Indicator to address existing issues

  • I'm creating a new Renko Indicator to address the issues (i.e. not based on the actual price movement, atr) ...

    class Renko(bt.Indicator):
        During a trend continuation, a new brick of the same color is added to the chart when the Renko Brick Size value,
        plus one tick is met. A reversal in the Renko trend and the formation of a different color brick is formed
        when price surpasses the Renko Brick Size parameter by twice the size plus one tick.
            atr  = SmoothedMovingAverage(TrueRange, period)
            open = open
            high = (close + size)
            low  = (close - size)
            close = close
            direction = Sum(up) - Sum(down) Notes: Neutral = 0, Up = 1, Down = -1
        See also:
        lines = ('open', 'high', 'low', 'close', 'volume', 'direction')
            Fixed = Fixed Brick Size, False, means ATR
        params = (('fixed', True), ('brick_size', 0.0001), ('period', 14), ('field', 'close'), ('movav', MovAv.Smoothed))
        plotinfo = dict(subplot=False)
        def __init__(self):
            o =
            h =
            l =
            c =
            v =
            up_count = {}
            down_count = {}
            # Due we need to keep track of all Bricks with OHLCV to push to Strategy after time resolution?
            total_bricks = {}
            (brick_lower_limit, brick_upper_limit) = (c - self.p.brick_size, c + self.p.brick_size)
            self.lines.atr = ATR(, period=self.p.period, movav=self.p.movav)
            self.lines.close = c
   = o
            self.lines.high = c + self.p.brick_size
            self.lines.low = c - self.p.brick_size
            self.lines.volume = v
            self.lines.direction = sum(self.up_count) - sum(self.down_count)
            super(Renko, self).__init__()
        def prenext(self):
            print('prenext:: current period:', len(self))
        def nextstart(self):
            print('nextstart:: current period:', len(self))
            # emulate default behavior ... call next
        def next(self):
            print('next:: current period:', len(self))
        def _plotlabel(self):
            plabels = [self.p.period]
            plabels += [self.p.movav] * self.p.notdefault('movav')
            return plabels

    Test Cases

    1. 1-minute resolution, fixed size = 1, direction=1 (upward), price movement= 3 => Expectation = 3 green (up) bricks
    2. 1-minute resolution, fixed size = 1, direction=1, price movement = -2 => Expectation = 0 bricks; not enough price movement when changing direction
    3. 1-minute resolution, fixed size = 1, direction=1, price movement = -2.1 => Expectation = 2 red (down) bricks

    I need the Strategy to expose all three bricks in the Next(self) would need access to all three bricks given that the resolution is 1 minute.

    Is this the correct implementation strategy? What will be the issues around time resolutions?

    I had thought about just sampling at a lower resolution, which would capture the price movements and push out the bars. However, we would still need a custom Renko indicator to address the up/down logic.

  • A new Renko class was created and I stopped using the RenkoFilter. The new Renko class didn't inherit from bt.Indicator as this open up a bunch of other issues. If you need it please fill free to ping me. I'll open it up once I get a few more unit tests around it.

Log in to reply