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

Custom Observer for debug arrows on graph, to be called in stratergy, error

  • Re: Plotting a boolean indicator

    Been trying to make a way I can debug my algorithm visually by using a arrow like BuySell Observer. I want to be able to call addpoint which will add it to the graph, however I have ran into a few problems these include:
    Getting an error when trying to call the line outside of the next()

       self.lines.peak[index] = copy.deepcopy(yvalue)
      File "/usr/local/lib/python3.7/site-packages/backtrader/", line 62, in __get__
        return obj.lines[self.line]
    AttributeError: 'NoneType' object has no attribute 'lines'

    with example code:

    def addpoint(self, index, typepoint, yvalue):
            self.lines.peak[index] = copy.deepcopy(yvalue)

    Due to this I have been trying to do things through the next function with example code below:

    import math
    import copy
    from import Observer
    class PeaksAndTroofs(Observer):
        lines = ('peak', 'troof',)
        plotinfo = dict(plot=True, subplot=False, plotlinelabels=True)
        plotlines = dict(
            peak=dict(marker='v', markersize=8.0, color='purple',
                     fillstyle='full', ls=''),
            troof=dict(marker='^', markersize=8.0, color='blue',
                      fillstyle='full', ls='')
        params = (
            ('barplot', False),  # plot above/below max/min for clarity in bar plot
            ('bardist', 0.015),  # distance to max/min in absolute perc
        typepoint = []
        yvaluepoint = []
        index = []
        def next(self):
            if self.yvaluepoint != [] and self.typepoint != [] and self.index != []:
                for i in range(len(self.index)):
                    if self.typepoint[i] == 'peak':
                        self.lines.peak[self.index[i]] = copy.deepcopy(self.yvaluepoint[i])
                    elif self.typepoint == 'troof':
                        self.lines.troof[self.index[i]] = copy.deepcopy(self.yvaluepoint[i])
                self.typepoint = []
                self.yvaluepoint = []
                self.index = []
        def addpoint(self, index, typepoint, yvalue):

    I don't get any results out onto the graph, I beileve its due to the.

    self.typepoint = []
    self.yvaluepoint = []
    self.index = []

    This is due to when removing I get the a sort of expected behavouir with plotting however, indicators are repeated and troofs don't exsist.
    This is the graph with the above code commented out.

    I am creating my calls to addpoint like this in my stratergy.

    if len(self.dataclose) % 10 == 0:
         self.peaks_and_troofs_ob.addpoint(self.peaks_and_troofs_ob, 0, 'peak', self.dataclose[0])
    elif len(self.dataclose) % 5 == 0:
                self.peaks_and_troofs_ob.addpoint(self.peaks_and_troofs_ob, 0, 'troof', self.dataclose[0])

    And the way I have pulled in the new observer to the stratergy is this in the init

    # Plots peaks and troofs
    self.peaks_and_troofs_ob = PeaksAndTroofs

  • @HarryBurge said in Custom Observer for debug arrows on graph, to be called in strategy, error:

    I am creating my calls to addpoint like this in my strategy.

    Few points:

    1. Having a strategy dependent on specific observer is probably not the best idea design-wise.
    2. Why the same logic can't be run right inside the observer? All datas are available for observers AFAIR.

Log in to reply