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/

    Unable to plot 2nd level nested indicator

    General Discussion
    2
    4
    198
    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.
    • A
      aartajew last edited by

      Hi guys,

      First of all, thanks for such a great tool for backtesting investing ideas!

      I try to plot a nested indicator. By nesting I mean using one's indicator data as entry data for another's indicator data.

      Here is what I do, based on the simple example from readme:

      from datetime import datetime
      import backtrader as bt
      
      class SmaCross(bt.SignalStrategy):
          def __init__(self):
              sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30)
              crossover = bt.ind.CrossOver(sma1, sma2)
              self.signal_add(bt.SIGNAL_LONG, crossover)
      
              mom = bt.ind.Momentum()
              mommom = bt.ind.Momentum(mom)
              mommommom = bt.ind.Momentum(mommom, plotforce=True)
      
      cerebro = bt.Cerebro()
      cerebro.addstrategy(SmaCross)
      
      data0 = bt.feeds.YahooFinanceCSVData(dataname='data/GLD.csv', 
      	                             fromdate=datetime(2011, 1, 1),
      	                             todate=datetime(2012, 12, 31))
      cerebro.adddata(data0)
      
      cerebro.run()
      cerebro.plot()
      

      It crashes with:

      $ python smacross.py
      Traceback (most recent call last):
        File "smacross.py", line 21, in <module>
          cerebro.plot()
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/cerebro.py", line 991, in plot
          start=start, end=end, use=use)
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/plot/plot.py", line 134, in plot
          self.sortdataindicators(strategy)
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/plot/plot.py", line 856, in sortdataindicators
          if key not in strategy.datas:
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineroot.py", line 281, in __eq__
          return self._operation(other, operator.__eq__)
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineroot.py", line 86, in _operation
          other, operation, r=r, intify=intify)
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineroot.py", line 201, in _operation_stage1
          return self._makeoperation(other, operation, r, self)
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/lineroot.py", line 331, in _makeoperation
          return self.lines[0]._makeoperation(other, operation, r, _ownerskip)
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/linebuffer.py", line 378, in _makeoperation
          _ownerskip=_ownerskip)
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/linebuffer.py", line 522, in __call__
          return super(MetaLineActions, cls).__call__(*args, **kwargs)
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/metabase.py", line 89, in __call__
          _obj, args, kwargs = cls.dopostinit(_obj, *args, **kwargs)
        File "/Users/adam/.pyenv/versions/backtrader/lib/python3.5/site-packages/backtrader/linebuffer.py", line 566, in dopostinit
          _obj._owner.addindicator(_obj)
      AttributeError: 'NoneType' object has no attribute 'addindicator'
      

      Without plotforce=True it won't crash, but the plot is still not visible.

      My env is macOS Catalina 10.15.3, Python 3.5.9 with packages:

      $ pip freeze
      backtrader==1.9.74.123
      cycler==0.10.0
      kiwisolver==1.1.0
      matplotlib==3.0.3
      numpy==1.18.3
      pyparsing==2.4.7
      python-dateutil==2.8.1
      six==1.14.0
      

      Any help would be appreciated :)

      Thanks in advance and keep up the fantastic work!
      Adam

      1 Reply Last reply Reply Quote 0
      • A
        ab_trader last edited by

        as a quick solution - you can put all three indicators on the same plot using plotmaster=mom parameter for 2nd and 3rd indicator.

        • If my answer helped, hit reputation up arrow at lower right corner of the post.
        • Python Debugging With Pdb
        • New to python and bt - check this out
        1 Reply Last reply Reply Quote 1
        • A
          aartajew last edited by

          Yeah that worked! Thanks a lot :)

          Meanwhile I've found another workaround, using dedicated indicator and nesting other indicator inside it:

          from datetime import datetime
          import backtrader as bt
          
          class NestedMomentum(bt.Indicator):
              lines = ('mom', 'mommom', 'mommommom')
              def __init__(self):
                  self.l.mom = bt.ind.Momentum()
                  self.l.mommom = bt.ind.Momentum(self.l.mom)
                  self.l.mommommom = bt.ind.Momentum(self.l.mommom)
          
          class SmaCross(bt.SignalStrategy):
              def __init__(self):
                  sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30)
                  crossover = bt.ind.CrossOver(sma1, sma2)
                  self.signal_add(bt.SIGNAL_LONG, crossover)
          
                  # plotmaster workaround
                  mom = bt.ind.Momentum()
                  mommom = bt.ind.Momentum(mom, plotmaster=mom)
                  mommommom = bt.ind.Momentum(mommom, plotmaster=mom)
          
                  # custom indicator workaround
                  nested = NestedMomentum()
          
          cerebro = bt.Cerebro()
          cerebro.addstrategy(SmaCross)
          
          data0 = bt.feeds.YahooFinanceCSVData(dataname='data/GLD.csv', 
          	                                 fromdate=datetime(2011, 1, 1),
          	                                 todate=datetime(2012, 12, 31))
          cerebro.adddata(data0)
          
          cerebro.run()
          cerebro.plot()
          

          Anyway it looks like a bug, but I'm happy there are workarounds :)

          A 1 Reply Last reply Reply Quote 0
          • A
            ab_trader @aartajew last edited by

            @aartajew it seems like an issue in the bt script, but to be 100% sure we need to hear from author or get deeper into bt scripts with debugger.

            • If my answer helped, hit reputation up arrow at lower right corner of the post.
            • Python Debugging With Pdb
            • New to python and bt - check this out
            1 Reply Last reply Reply Quote 1
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors