Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    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

    General Code/Help
    renko
    1
    2
    184
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      booboothefool last edited by

      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!

      1 Reply Last reply Reply Quote 0
      • B
        booboothefool last edited by

        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!

        1 Reply Last reply Reply Quote 0
        • 1 / 1
        • First post
          Last post
        Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors