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

Problem with my custom Indicator, UIcerIndex

  • Hi!
    I'm trying to implement a indicator, the short version is:

    1. Percent-Drawdown = ((Close - 14-period Max Close)/14-period Max Close) x 100
    2. Squared Average = (14-period Sum of Percent-Drawdown Squared)/14
    3. Ulcer Index = Square Root of Squared Average

    But I ran into problems. I cannot get it right. When I do print the len(myslice) i always get the output 2.

    What are my misstakes? I seem to miss something obvious here.

     class UICerIndex(bt.Indicator):
        params = ('period', 14), )
        lines = ('UICer',)
        def __init__(self):
            self.highstV = None
        def next(self):
            myslice = self.data0.close.get(size=self.p.period)
            self.highstValue = bt.Max(myslice)
            for e in myslice:
                DP += ((self.highstValue - e) / self.highstValue * 100) ** 2
            meanvalue = DP / self.p.period
            # SMA = A1..An/n

  • @Jakob-Schütte maybe[0].close.get(size=self.p.period) instead of self.data0.close.get(size=self.p.period) ? 🙂

  • Thanks! That was a typo. But I have come further. But now I have a other problem that I do not know how to fix.

    UIcerIndex", line 33, in next response = math.sqrt(meanvalue)
    TypeError: must be real number, not LinesOperation

    I'm new to Backtrader and could need some help...

        def next(self):
            myslice = self.datas[0].close.get(size=self.p.period)
            self.highstValue = bt.Max(myslice)
            for e in myslice:
                self.DP += ((self.highstValue - e) / self.highstValue * 100) ** 2
            meanvalue = self.DP / self.p.period
            # SMA = A1..An/n
            response = math.sqrt(meanvalue)

  • @Jakob-Schütte fyi.

    class ulcerIndex(bt.Indicator):
        lines = ('Ulcer','highestClose','perDrawdown','sqAvg')
        params = (('period', 14),)
        plotlines = dict(
        def __init__(self):
            # To make mixins work - super at the end for cooperative inheritance
            super(ulcerIndex, self).__init__()
            self.l.highestClose = bt.ind.Highest(, period=self.p.period)
            self.l.perDrawdown = ( * 100
            self.l.sqAvg = bt.ind.SumN(self.l.perDrawdown,period=self.p.period)**2/14
            self.l.Ulcer= pow(self.l.sqAvg,0.5)

  • @barton05 said in Problem with my custom Indicator, UIcerIndex:

    self.l.sqAvg = bt.ind.SumN(self.l.perDrawdown,period=self.p.period)**2/14

    should be changed to:

    self.l.sqAvg = bt.ind.SumN(self.l.perDrawdown,period=self.p.period)**2/self.p.period

  • @barton05 Thanks. Appreciate your help a lot!

    Newbie questions:

    1. self.l.sqAvg = bt.ind.SumN(self.l.perDrawdown,period=self.p.period)**2/14 Will that line iterate over the latest 14 values and apply self.l.perDrawdown?

    2. Why are you doing the Super-call? I cannot fully understand your comment.

  • @Jakob-Schütte

    yes, and better use self.p.period instead of a hardcode value 14.
    super call related to inheritance, tbh i'm not sure for details.

Log in to reply