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

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
            self.addminperiod(self.p.period)
            return
    
        def next(self):
            myslice = self.data0.close.get(size=self.p.period)
            print(len(myslice))
            self.highstValue = bt.Max(myslice)
            DP=0
    
            for e in myslice:
                DP += ((self.highstValue - e) / self.highstValue * 100) ** 2
    
            meanvalue = DP / self.p.period
            # SMA = A1..An/n
            self.lines.UICer=sqrt(meanvalue)
            return


  • @Jakob-Schütte maybe self.data[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 v1.py", 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)
            print(len(myslice))
    
            self.highstValue = bt.Max(myslice)
            self.DP=0
    
            for e in myslice:
                self.DP += ((self.highstValue - e) / self.highstValue * 100) ** 2
            print("DP")
            print(self.DP)
            meanvalue = self.DP / self.p.period
            # SMA = A1..An/n
            response = math.sqrt(meanvalue)
            print(str(response))
    
            self.lines[0]=(response)


  • @Jakob-Schütte fyi.

    
    class ulcerIndex(bt.Indicator):
        lines = ('Ulcer','highestClose','perDrawdown','sqAvg')
        params = (('period', 14),)
        plotlines = dict(
            highestClose=dict(_plotskip=True),
            perDrawdown=dict(_plotskip=True),
            sqAvg=dict(_plotskip=True),
        )
        def __init__(self):
            # To make mixins work - super at the end for cooperative inheritance
            super(ulcerIndex, self).__init__()
            self.l.highestClose = bt.ind.Highest(self.data.close, period=self.p.period)
            self.l.perDrawdown = (self.data.close-self.l.highestClose)/self.l.highestClose * 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
 

});