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

Tips for better/faster code in my custom indicator - Absolute Strength Histogram



  • Hi all, I'm coded a backtrader version of the Absolute Strength Histogram (ASH) indicator, wonder if I could get some feedback on "proper/optimized" ways of coding it.

    Description and calculation of indicator is from : https://www.mql5.com/en/code/21429

    My main issue, is that when coding, I created each line bar by bar, primarily in the "next()" function. And when calculating a weighted average, I couldn't seem to get a BT indicator function to work, so used "numpy" functions.

    Another questions, most of the "lines" in my code are for calculations/storing values, is there a recommended way to store these data instead? My understanding is that lines should be mainly for plotting/output.

    It seems to work, but clearly not optimal, hope for any suggestions! Thanks!

    
    class ASH(bt.Indicator):
        lines = ("SmthBulls", "SmthBears", "Bulls", "Bears", "AvgBulls", "AvgBears", "ash")
        params = (("Mode", 0),  #RSI = 0, Stoch = 1
                  ("Length", 9),
                  ("Smooth", 1),)
        
        plotinfo = dict(plot=False, subplot=True)
        
    
        
        def __init__(self):
            self.addminperiod(self.p.Length+self.p.Smooth+5)
            self.sma_close =  bt.indicators.SMA(self.data, period=1)
            self.highest = bt.indicators.Highest(self.data.high, period = self.p.Length)  
            self.lowest = bt.indicators.Lowest(self.data.low, period = self.p.Length)        
        
        def next(self):
            
            if self.p.Mode == 0:
                self.l.Bulls[0] = 0.5 * (math.fabs(self.sma_close[0] - self.sma_close[-1]) + (self.sma_close[0] - self.sma_close[-1]))
                self.l.Bears[0] = 0.5 * (math.fabs(self.sma_close[0] - self.sma_close[-1]) - (self.sma_close[0] - self.sma_close[-1]))
                
            if self.p.Mode == 1:
                self.l.Bulls[0] = self.sma_close[0] - self.lowest[0]
                self.l.Bears[0] = self.highest[0] - self.sma_close[0]
            
            if not math.isnan(self.l.Bulls[-1*self.p.Length]) and not math.isnan(self.l.Bears[-1*self.p.Length]):
                weights = np.array(range(1, self.p.Length + 1))
                
                avgBullarray = np.array([])
                avgBeararray = np.array([])
                for i in range(-1 * self.p.Length+1, 1):
                    avgBullarray = np.append(avgBullarray, self.l.Bulls[i] )
                    avgBeararray = np.append(avgBeararray, self.l.Bears[i] )
    
                self.l.AvgBulls[0] = np.average(avgBullarray, weights=weights)
                self.l.AvgBears[0] = np.average(avgBeararray, weights=weights)
    
            if not math.isnan(self.l.AvgBulls[-1*self.p.Smooth]) and not math.isnan(self.l.AvgBears[-1*self.p.Smooth]):
                weights = np.array(range(1, self.p.Smooth + 1))
                
                smthBullarray = np.array([])
                smthBeararray = np.array([])
                for i in range(-1 * self.p.Smooth+1, 1):
                    smthBullarray = np.append(smthBullarray, self.l.AvgBulls[i] )
                    smthBeararray = np.append(smthBeararray, self.l.AvgBears[i] )
    
                self.l.SmthBulls[0] = np.average(smthBullarray, weights=weights)
                self.l.SmthBears[0] = np.average(smthBeararray, weights=weights)
                
            
            self.l.ash[0] = self.l.SmthBulls[0] - self.l.SmthBears[0]
    
    
    

  • administrators



  • @backtrader Awesome, thks!


Log in to reply
 

});