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

Plotting more than one line in an indicator



  • How do you plot more than one line on a chart with an indicator?

    The documentation mentions the LinePlotterIndicator but it doesn't explain how to call it.

    For testing I'm just creating a simple Indicator with two moving averages which I would like to plot on the chart:

    # Import the backtrader platform
    import backtrader as bt
    import math
    
    class ProjectedMovingAverageIndicator(bt.Indicator):
      lines = ('smaSlow','smaFast',)
      params = (('periodSlow', 200),('periodFast', 100),)
      plotinfo = dict(subplot=False)
    
      def __init__(self):
          self.addminperiod(self.params.periodSlow)
          
      def next(self):
          datasum = math.fsum(self.data.close.get(size=self.p.periodSlow))
          self.lines.smaSlow[0] = datasum / self.p.periodSlow
          self.lines.smaFast[0] = datasum / self.p.periodFast
          print(self.lines.smaSlow[0],' ', self.lines.smaFast[0])
    
      def signal(self):
        if self.lines.smaFast[-1] < self.lines.smaSlow[-1] and self.lines.smaFast[0] > self.lines.smaSlow[0]:
            signal = True
        else:
            signal = False
        #print(signal)
        return signal
    
    

    Thanks



  • bt should plot all indicator lines by default when you initiate your indicator in the strategy. For example, add bollinger bands indicator in your strategy and it will be plotted. So no need to use LinePlotterIndicator.



  • Thanks for the speedy reply @ab_trader. That's what I thought should happen, but as you can see in the attached it's not happening. I must be doing something wrong, I looked at the Bollinger band indicator code on Github and can see that the lines are being declared in the init function as opposed to next:

    def __init__(self):
            self.lines.mid = ma = self.p.movav(self.data, period=self.p.period)
            stddev = self.p.devfactor * StdDev(self.data, ma, period=self.p.period,
                                               movav=self.p.movav)
            self.lines.top = ma + stddev
            self.lines.bot = ma - stddev
    
            super(BollingerBands, self).__init__()
    

    Should I be doing that instead?

    Thanks

    ![0_1604489311543_Screenshot 2020-11-04 at 08.28.52.png](Uploading 100%)



  • Hmm image link didn't work, here is another [https://prnt.sc/vd8mek]



  • Ok I played around a bit and got it working:

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    # Import the backtrader platform
    import backtrader as bt
    import math
    
    class ProjectedMovingAverageIndicator(bt.Indicator):
    
      lines = ('smaSlow','smaFast',)
      params = (('periodSlow', 200),('periodFast', 100),('movav', bt.indicators.MovAv.Simple),)
      plotinfo = dict(subplot=False)
      plotlines = dict(
        smaSlow=dict(_samecolor=True),
        smaFast=dict(_samecolor=False),
        )
    
      def __init__(self):
        self.addminperiod(self.params.periodSlow)
        movavSlow = self.p.movav(self.data, period=self.p.periodSlow)
        movavFast = self.p.movav(self.data, period=self.p.periodFast)
        self.l.smaSlow = movavSlow #bt.Cmp(movav, self.data)
        self.l.smaFast = movavFast #bt.Cmp(movav, self.data)
    
      def signal(self):
        if self.lines.smaFast[-1] < self.lines.smaSlow[-1] and self.lines.smaFast[0] > self.lines.smaSlow[0]:
            signal = True
        else:
            signal = False
        #print(signal)
        return signal
    
    

    Thanks


Log in to reply
 

});