1

I am trying to convert the snippet from https://medium.datadriveninvestor.com/how-to-detect-support-resistance-levels-and-breakout-using-python-f8b5dac42f21 into backtrader custom indicator. However, I encounter error AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'shape'

The support and resistance snippet I want to convert:

#method 1: fractal candlestick pattern
# determine bullish fractal 
def is_support(df,i):  
  cond1 = df['Low'][i] < df['Low'][i-1]   
  cond2 = df['Low'][i] < df['Low'][i+1]   
  cond3 = df['Low'][i+1] < df['Low'][i+2]   
  cond4 = df['Low'][i-1] < df['Low'][i-2]  
  return (cond1 and cond2 and cond3 and cond4) 
# determine bearish fractal
def is_resistance(df,i):  
  cond1 = df['High'][i] > df['High'][i-1]   
  cond2 = df['High'][i] > df['High'][i+1]   
  cond3 = df['High'][i+1] > df['High'][i+2]   
  cond4 = df['High'][i-1] > df['High'][i-2]  
  return (cond1 and cond2 and cond3 and cond4)
# to make sure the new level area does not exist already
def is_far_from_level(value, levels, df):    
  ave =  np.mean(df['High'] - df['Low'])    
  return np.sum([abs(value-level)<ave for _,level in levels])==0
# a list to store resistance and support levels
levels = []
for i in range(2, df.shape[0] - 2):  
  if is_support(df, i):    
    low = df['Low'][i]    
    if is_far_from_level(low, levels, df):      
      levels.append((i, low))  
  elif is_resistance(df, i):    
    high = df['High'][i]    
    if is_far_from_level(high, levels, df):      
      levels.append((i, high))

When I convert to backtarder by create custom indicator under bt.Indicator

class SR_Fractal(bt.Indicator):
    lines = ("S","R")
    plotinfo = dict(subplot = True)
    plotlines = dict(
    Support = dict(_name='S',color='red'),
    Resistance = dict(_name='R',color='green')
    )
    
    def __init__(self):
    
        # determine bullish fractal 

        def is_support(self):  
            cond1 = self.data.low[0]< self.data.low[-1] 
            cond2 = self.data.low[0]< self.data.low[1]   
            cond3 = self.data.low[1]< self.data.low[2]   
            cond4 = self.data.low[-1]< self.data.low[-2] 
            return (cond1 and cond2 and cond3 and cond4) 
        # determine bearish fractal

        def is_resistance(self):  
            cond1 = self.data.high[0] > self.data.high[-1]   
            cond2 = self.data.high[0] > self.data.high[1]   
            cond3 = self.data.high[1] > self.data.high[2]   
            cond4 = self.data.high[-1] > self.data.high[-2]  
            return (cond1 and cond2 and cond3 and cond4)
        # to make sure the new level area does not exist already
        def is_far_from_level(value, levels, self):    
            ave =  np.mean(self.data.high - self.data.low)    
            return np.sum([abs(value-level)<ave for _,level in levels])==0
        # a list to store resistance and support levels
        levels = []
        for i in range(2, self.data.shape[0] - 2):  
            if is_support(self.data, i):    
                low = self.data.low[i]    
                if is_far_from_level(low, levels, self):      
                    levels.append((i, low))  
            elif is_resistance(self.data, i):    
                high = self.data.high[i]    
                if is_far_from_level(high, levels, self):      
                    levels.append((i, high))    

Please advice the correct way I shall amend to get the support resistance correct

bkcollection
  • 913
  • 1
  • 12
  • 35

0 Answers0