Renko Bricks

The Renko Bricks is a different way to present the evolution of prices in which price plays a more important role than time. This has been introduced as a filter in release 1.9.54.122 of backtrader

Stockcharts has a good reference on the Renko Bricks. See Renko Bricks @StockCharts

Some examples

Note

The size=35 and align=10.0 parameters are appropriate for the sample data in the backtrader repository. Those values have to be fine tuned for each data asset.

First, let’s put the Renko Bricks alone in a chart:

$ ./renko.py --renko size=35,align=10.0 --plot

The output

!image

One can see that the chart immediately reveals some resistance/support areas, which is one of the main advantages of the Renko Bricks. It should also be obvious that the temporal evolution in the X-Axis is no longer constant and is stretched or compressed, depending on whether the price action was more static during the period or moved several bricks.

To better see and appreciate the effects, let’s put the normal price bars and the Renko Bricks together on a chart:

$ ./renko.py --renko size=35,align=10.0 --plot --dual

The output

!image

The strechting and compression of time periods is now a lot more obvious. One other factor to consider is how the focus on the price action also has an effect on the indicators which are applied, as shown by the two RSI indicators which have been placed on the chart.

Sample Usage

$ ./renko.py --help
usage: renko.py [-h] [--data0 DATA0] [--fromdate FROMDATE] [--todate TODATE]
                [--cerebro kwargs] [--broker kwargs] [--sizer kwargs]
                [--strat kwargs] [--plot [kwargs]] [--renko kwargs] [--dual]

Renko bricks sample

optional arguments:
  -h, --help           show this help message and exit
  --data0 DATA0        Data to read in (default:
                       ../../datas/2005-2006-day-001.txt)
  --fromdate FROMDATE  Date[time] in YYYY-MM-DD[THH:MM:SS] format (default: )
  --todate TODATE      Date[time] in YYYY-MM-DD[THH:MM:SS] format (default: )
  --cerebro kwargs     kwargs in key=value format (default: )
  --broker kwargs      kwargs in key=value format (default: )
  --sizer kwargs       kwargs in key=value format (default: )
  --strat kwargs       kwargs in key=value format (default: )
  --plot [kwargs]      kwargs in key=value format (default: )
  --renko kwargs       kwargs in key=value format (default: )
  --dual               put the filter on a second version of the data
                       (default: False)

Sample Code

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import argparse
import datetime

import backtrader as bt


class St(bt.Strategy):
    params = dict(
    )

    def __init__(self):
        for d in self.datas:
            bt.ind.RSI(d)

    def next(self):
        pass


def runstrat(args=None):
    args = parse_args(args)

    cerebro = bt.Cerebro()

    # Data feed kwargs
    kwargs = dict()

    # Parse from/to-date
    dtfmt, tmfmt = '%Y-%m-%d', 'T%H:%M:%S'
    for a, d in ((getattr(args, x), x) for x in ['fromdate', 'todate']):
        if a:
            strpfmt = dtfmt + tmfmt * ('T' in a)
            kwargs[d] = datetime.datetime.strptime(a, strpfmt)

    data0 = bt.feeds.BacktraderCSVData(dataname=args.data0, **kwargs)

    fkwargs = dict()
    fkwargs.update(**eval('dict(' + args.renko + ')'))

    if not args.dual:
        data0.addfilter(bt.filters.Renko, **fkwargs)
        cerebro.adddata(data0)
    else:
        cerebro.adddata(data0)
        data1 = data0.clone()
        data1.addfilter(bt.filters.Renko, **fkwargs)
        cerebro.adddata(data1)

    # Broker
    cerebro.broker = bt.brokers.BackBroker(**eval('dict(' + args.broker + ')'))

    # Sizer
    cerebro.addsizer(bt.sizers.FixedSize, **eval('dict(' + args.sizer + ')'))

    # Strategy
    cerebro.addstrategy(St, **eval('dict(' + args.strat + ')'))

    # Execute
    kwargs = dict(stdstats=False)
    kwargs.update(**eval('dict(' + args.cerebro + ')'))
    cerebro.run(**kwargs)

    if args.plot:  # Plot if requested to
        kwargs = dict(style='candle')
        kwargs.update(**eval('dict(' + args.plot + ')'))
        cerebro.plot(**kwargs)


def parse_args(pargs=None):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description=(
            'Renko bricks sample'
        )
    )

    parser.add_argument('--data0', default='../../datas/2005-2006-day-001.txt',
                        required=False, help='Data to read in')

    # Defaults for dates
    parser.add_argument('--fromdate', required=False, default='',
                        help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')

    parser.add_argument('--todate', required=False, default='',
                        help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')

    parser.add_argument('--cerebro', required=False, default='',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--broker', required=False, default='',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--sizer', required=False, default='',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--strat', required=False, default='',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--plot', required=False, default='',
                        nargs='?', const='{}',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--renko', required=False, default='',
                        metavar='kwargs', help='kwargs in key=value format')

    parser.add_argument('--dual', required=False, action='store_true',
                        help='put the filter on a second version of the data')

    return parser.parse_args(pargs)


if __name__ == '__main__':
    runstrat()