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/

    custom indicator - error in strategy

    General Code/Help
    2
    5
    303
    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.
    • Jens Halsberghe
      Jens Halsberghe last edited by

      I created a custom indicator which I verified it works by first creating it as a strategy and now want to turn it into an indicator.
      I'm getting an error when I add it in a strategy.
      I'll give some snippets of the indicator as it's quite extensive. will post more if necessary.

      class Trend_Indicator(bt.Indicator):
          lines = ('Trend', 'ohlc')
          params = (
                  ('slowma', 21),
                  ('fastma', 8),
          )
      
          def __init__(self):
              
              # Add Bollinger bands
              self.BB = bt.indicators.BollingerBands(self.datas[0])
            
              self.ohlc.open = self.datas[0].open[0]
              self.ohlc.high = self.datas[0].high[0]
              self.ohlc.low = self.datas[0].low[0]
              self.ohlc.close = self.datas[0].close[0]
              
              self.SlowEMA= bt.indicators.EMA(self.datas[0],period=self.params.slowma)
              self.FastEMA = bt.indicators.EMA(self.datas[0],period=self.params.fastma)
              
              self.Trend.bollinger_touch = ""
              self.Trend.Status = ""
              self.Trend.Enter = ""
              self.Trend.ExitParameters = {"20BarRule": False, "EMARule": False, "OppositeBollingerTouch": False}
              self.Trend.EMARule = {"Close1":False, "Close2":False}
              self.Trend.Position = 0 
      

      the output of the indicator will be if the current bar is in an up or downtrend, it won't output anything, here's the logic which is in the next method

              if #some logic:
                  self.log(self.Trend.Status)
      
              if #some logic:
                  self.log(self.Trend.Status)
      

      Now adding it to the strategy:

      class my_strategy(bt.Strategy):
      
          params = (
                  ('slowma', 21),
                  ('fastma', 8),
          )
      
          def log(self, txt, dt=None):
              ''' Logging function for this strategy'''
              dt = dt or self.datas[0].datetime.datetime(0)
              print('%s, %s' % (dt.strftime("%Y-%m-%d %H:%M"), txt))
      
          def __init__(self):
              
              # Add Bollinger bands
              self.BB = bt.indicators.BollingerBands(self.datas[0])
            
              # Add Trend Indicator
              self.TI = self.Trend_Indicator(self.datas[0])
              
          def next(self):
              
              self.log(self.TI[0])
              
              
      if __name__ == '__main__':
      
          cerebro = bt.Cerebro()
          # Add a strategy
          cerebro.addstrategy(my_strategy)
          # Create a Data Feed
          minute_data = bt.feeds.PandasData(dataname=df2020)
          # Add the Data Feed to Cerebro
          cerebro.adddata(minute_data)
          cerebro.run()
      

      when running the strategy, I'm getting the following error:

      ---------------------------------------------------------------------------
      AttributeError                            Traceback (most recent call last)
      <ipython-input-84-44a2b1b8e87a> in <module>
           36     # Add the Data Feed to Cerebro
           37     cerebro.adddata(minute_data)
      ---> 38     cerebro.run()
      
      ~\Anaconda3\lib\site-packages\backtrader\cerebro.py in run(self, **kwargs)
         1125             # let's skip process "spawning"
         1126             for iterstrat in iterstrats:
      -> 1127                 runstrat = self.runstrategies(iterstrat)
         1128                 self.runstrats.append(runstrat)
         1129                 if self._dooptimize:
      
      ~\Anaconda3\lib\site-packages\backtrader\cerebro.py in runstrategies(self, iterstrat, predata)
         1215             sargs = self.datas + list(sargs)
         1216             try:
      -> 1217                 strat = stratcls(*sargs, **skwargs)
         1218             except bt.errors.StrategySkipError:
         1219                 continue  # do not add strategy to the mix
      
      ~\Anaconda3\lib\site-packages\backtrader\metabase.py in __call__(cls, *args, **kwargs)
           86         _obj, args, kwargs = cls.donew(*args, **kwargs)
           87         _obj, args, kwargs = cls.dopreinit(_obj, *args, **kwargs)
      ---> 88         _obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
           89         _obj, args, kwargs = cls.dopostinit(_obj, *args, **kwargs)
           90         return _obj
      
      ~\Anaconda3\lib\site-packages\backtrader\metabase.py in doinit(cls, _obj, *args, **kwargs)
           76 
           77     def doinit(cls, _obj, *args, **kwargs):
      ---> 78         _obj.__init__(*args, **kwargs)
           79         return _obj, args, kwargs
           80 
      
      <ipython-input-84-44a2b1b8e87a> in __init__(self)
           20 
           21         # Add Trend Indicator
      ---> 22         self.TI = self.Trend_Indicator(self.datas[0])
           23 
           24     def next(self):
      
      ~\Anaconda3\lib\site-packages\backtrader\lineseries.py in __getattr__(self, name)
          459         # in this object if we set an attribute in this object it will be
          460         # found before we end up here
      --> 461         return getattr(self.lines, name)
          462 
          463     def __len__(self):
      
      AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Strateg' object has no attribute 'Trend_Indicator'
      

      any help is greatly appreciated!

      thanks

      vladisld 1 Reply Last reply Reply Quote 0
      • vladisld
        vladisld @Jens Halsberghe last edited by

        @Jens-Halsberghe said in custom indicator - error in strategy:

        Add Trend Indicator

            self.TI = self.Trend_Indicator(self.datas[0])
        

        Seems like a typo.

        No need for self. in self.Trend_Indicator. Trend_Indicator is a class name and not a strategy property.

        Jens Halsberghe 1 Reply Last reply Reply Quote 1
        • Jens Halsberghe
          Jens Halsberghe @vladisld last edited by

          @vladisld

          thanks, it seems to be solved by that. I'm a bit confused in how to write the output of the indicator.

          the following seems to cause an issue

                  if #some logic:
                      self.log(self.Trend.Status)
          
                  if #some logic:
                      self.log(self.Trend.Status)
          

          I'm getting the following error:

          AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Indicat' object has no attribute 'log'
          

          I've tried changing it:

                  if #some logic:
                      self.Trend.Status[0]
          
                  if #some logic:
                      self.Trend.Status[0]
          

          but then the output when running the strategy is just showing all nan's

          To be honest I'm not sure how to make it work correctly. When reading the documentation it seems that the lines defined are being recorded but I only want to show the Trend line I created but then its attribute Status.

          I've tried a couple different variations like above but I haven't been able to get anywhere at the moment.

          1 Reply Last reply Reply Quote 0
          • Jens Halsberghe
            Jens Halsberghe last edited by

            just figured out I can do:

            
            
            self.Trend[0] = 1 # for a downtrend
            self.Trend[0] = -1 # for an uptrend
            
            

            I would like to use "up" and "down" it doesn't seem to accept it though

            1 Reply Last reply Reply Quote 0
            • Jens Halsberghe
              Jens Halsberghe last edited by

              I meant of course 1 for uptrend, -1 for downtrend but I can't edit my post

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