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



  • 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



  • @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.



  • @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.



  • 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



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


Log in to reply
 

});