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

Can't seem to get Renko to show up correctly on forward testing



  • Hi there so I basically took this script https://www.backtrader.com/blog/posts/2017-06-26-renko-bricks/renko-bricks/ and built some basic logic on top of it for testing.

    Algorithm is as follows:

    • only take longs
    • when you get 2 green Renko bars, go long
    • after that, when 2 red Renko bars show up, close the long position

    It seems to work as expected in backtesting, but when forward testing on a live data feed, I can't seem to make any sense of the data and the results returned.

    Here you can see data feed claims to be on a long green streak, so it buys in, however the chart on Oanda shows the streak is actually red, which is the wrong time to buy in. The data feed also acts like the price keeps going up by the box size so there are a ton of bars being formed or something, when there was in fact only 1. I am proud to say this bot loses 100% of the time! 😂

    Screenshot 2020-05-12 16.19.49.png

    Screenshot 2020-05-12 16.20.29.png

    On Oanda it is using Traditional, 0.01 settings for the box size, so I assume this is similar to these settings for the program:

    renko.py --renko size=0.01 --plot
    

    but as you can see, the prices are off by a tenth or so, so I have no idea how to make them match up.

    Code:

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    import argparse
    import datetime
    import pandas as pd
    
    import backtrader as bt
    
    import alpaca_backtrader_api
    
    import btoandav20
    StoreCls = btoandav20.stores.OandaV20Store
    DataCls = btoandav20.feeds.OandaV20Data
    # BrokerCls = btoandav20.brokers.OandaV20Broker
    
    from keys.keys import key_id, secret_key, base_url
    
    
    class St(bt.Strategy):
        params = dict(
        )
    
        def __init__(self):
            # for d in self.datas:
                # bt.ind.RSI(d)
                
            self.c =  self.datas[0].close
            self.o = self.datas[0].open
            
            self.streak = 0
            self.required_streak = 2
            
    
        def next(self):
            if self.c > self.o:
                if self.streak > 0:
                    self.streak += 1
                else:
                    self.streak = 1
            elif self.c < self.o:
                if self.streak < 0:
                    self.streak -= 1
                else:
                    self.streak = -1
                    
            txt = list()
            txt.append('Data0')
            txt.append('%04d' % len(self.data0))
            dtfmt = '%m-%d %H:%M:%S'
            txt.append('%s' % self.data.datetime.datetime(0).strftime(dtfmt))
            txt.append('C {:2f}'.format(self.data.close[0]))
            txt.append('O {:2f}'.format(self.data.open[0]))
            txt.append('{}'.format(self.streak))
            print(', '.join(txt))
                    
            if not self.position:
                if self.c > self.o and self.streak >= self.required_streak:
                    print('BUY')
                    self.buy()
                    
            elif self.position:
                if self.c < self.o and self.streak <= -selfrequired_streakthres:
                    print('CLOSE')
                    self.close()
    
    
    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)
        
        # ALPACA
        # store = alpaca_backtrader_api.AlpacaStore(
        #     key_id=key_id,
        #     secret_key=secret_key,
        #     paper=True,
        # )
        # DataFactory = store.getdata
        # data0 = DataFactory(dataname='TSLA',
        #         # timeframe=bt.TimeFrame.Days,
        #         timeframe=bt.TimeFrame.Minutes,
        #         compression=1,
        #         # fromdate=pd.Timestamp.now(),
        #         # fromdate=pd.Timestamp.today(),
        #         # fromdate=pd.Timestamp(2020,5,1),
        #         # todate=pd.Timestamp(2020,5,7),
        #         historical=False,
        # )
    
        # OANDA
        store = btoandav20.stores.OandaV20Store(
                token='mytoken',
                account='myaccount',
                practice=True,
        )
        DataFactory = store.getdata
        data0 = DataFactory(dataname='USD_JPY',
                timeframe=bt.TimeFrame.Minutes,
                historical=False,
                backfill_start=False,
        )
    
        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 + ')'))
        broker = store.getbroker()
        cerebro.setbroker(broker)
    
        # Sizer
        # cerebro.broker.setcash(100000)
        cerebro.addsizer(bt.sizers.FixedSize, stake=1)
    
        # Strategy
        cerebro.addstrategy(St, **eval('dict(' + args.strat + ')'))
    
        # Execute
        kwargs = dict(stdstats=True)
        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()
            cerebro.plot(style='candle', barup='green', bardown='maroon')
    
    
    def parse_args(pargs=None):
        parser = argparse.ArgumentParser(
            formatter_class=argparse.ArgumentDefaultsHelpFormatter,
            description=(
                'Renko bricks sample'
            )
        )
    
        parser.add_argument('--data0', default='data/TSLA.csv',
                            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()
    

    Any help would be greatly appreciated! Just trying to get something, anything simple working here with Renko bars!



  • Please ignore this typo

    @booboothefool said in Can't seem to get Renko to show up correctly on forward testing:

            if self.c < self.o and self.streak <= -selfrequired_streakthres:
    
    if self.c < self.o and self.streak <= -self.required_streak:
    

    e.g.
    2 green bars = +2
    2 red bars = -2

    You get the idea. Thanks!


Log in to reply
 

});