1

I'm trying to create support and resistance for the stocks chart. However, I got this error. Here is my code:

def isResistance(df,i):
    resistance = df['High'][i] > df['High'][i-1]  and df['High'][i] > df['High'][i+1] \
    and df['High'][i] > df['High'][i+2] and df['High'][i] > df['High'][i-2] \
    and df['High'][i] > df['High'][i+3] and df['High'][i] > df['High'][i-3] 
    
    return resistance

And I'm trying to take all of the list of the support and resistance by using this:

levels = []
for i in range(2,df.shape[0]-2):
    
    if isSupport(df,i):
        levels.append((i,df['Low'][i]))
    elif isResistance(df,i):
        levels.append((i,df['High'][i]))

Then the error occurs in this part:

and df['High'][i] > df['High'][i+3] and df['High'][i] > df['High'][i-3]

However, in this code there is no any errors:

def isSupport(df,i):
    support = df['Low'][i] < df['Low'][i-1]  and df['Low'][i] < df['Low'][i+1] \
    and df['Low'][i] < df['Low'][i+2] and df['Low'][i] < df['Low'][i-2] \
    and df['Low'][i] < df['Low'][i+3] and df['Low'][i] < df['Low'][i-3]
    
    return support

Do you have any idea to solve this issue? Thank you

Josh
  • 35
  • 1
  • 6
  • Assuming df is a Pandas dataframe, shouldn't it be possible to do this with a lot less code by leveraging some sort of slice + broadcast? Something like `all(df['High'][i] > df['High'][i-3:i+4])` (except I'm not sure at all how Pandas slices work...) – Ture Pålsson Nov 10 '20 at 06:41

1 Answers1

0

In Python, the logic are executed in order, that is,

for a and b and c, a will be evaluated first, then b, and lastly c. If a is False, b and c won't be executed and checked.

Therefore, in your case, since the clauses before df['High'][i] > df['High'][i+3] and df['High'][i] > df['High'][i-3] may evaluated to be False, the execution of this logic chain ended and will not evaluate the statement that has IndexError. But if they all evaluated to be True, the statement that has IndexError will be evaluated and thus throw an error to you.

To fix it, you can simply put one more clause before it, len(df['High']) >= 3, to take advantage of this logic chain evaluation order and stop it from accessing invalid index. Or I will just rewrite it to be a longer if statement for a cleaner code.

more on that here and here

kennysliding
  • 2,783
  • 1
  • 10
  • 31