pythonfinancequantitative-finance

Parabolic SAR in Python....PSAR keep growing instead of reversing


I have a pandas dataframe of Open/high/low/close stock prices and I am writing to write a function that will add Parabolic SAR to my dataframe. Right now the PSAR number just grows insanely huge and i never seem to get much in terms of flipping between bull and bear directions. Any help in understanding why my PSAR grows so crazy would be great. I've tried several variations on this code to no avail.

For those who are not familiar with PSAR:

Rising SAR

Eg: 13-Apr-10: SAR = 48.28 = 48.13 + .14(49.20 - 48.13)

Falling SAR

Eg: 9-Feb-10: SAR = 43.56 = 43.84 - .16(43.84 - 42.07)

During Reversal, the PSAR becomes the prior extreme point EP, and the new EP is the previous high or low depending on the direction of the flip. The AF resets to 0.02.

My function:

def addSAR(df):
    df.loc[0, 'AF'] =0.02
    df.loc[0, 'PSAR'] = df.loc[0, 'low']
    df.loc[0, 'EP'] = df.loc[0, 'high']
    df.loc[0, 'PSARdir'] = "bull"

    for a in range(1, len(df)):

        if df.loc[a-1, 'PSARdir'] == 'bull':

            df.loc[a, 'PSAR'] = df.loc[a-1, 'PSAR'] + (df.loc[a-1, 'AF']*(df.loc[a-1, 'EP']-df.loc[a-1, 'PSAR']))            

            df.loc[a, 'PSARdir'] = "bull"

            if df.loc[a, 'low'] < df.loc[a-1, 'PSAR']:
                df.loc[a, 'PSARdir'] = "bear"
                df.loc[a, 'PSAR'] = df.loc[a-1, 'EP']
                df.loc[a, 'EP'] = df.loc[a-1, 'low']
                df.loc[a, 'AF'] = .02

            else:
                if df.loc[a, 'high'] > df.loc[a-1, 'EP']:
                    df.loc[a, 'EP'] = df.loc[a, 'high']
                    if df.loc[a-1, 'AF'] <= 0.18:
                        df.loc[a, 'AF'] =df.loc[a-1, 'AF'] + 0.02
                    else:
                        df.loc[a, 'AF'] = df.loc[a-1, 'AF']
                elif df.loc[a, 'high'] <= df.loc[a-1, 'EP']:
                    df.loc[a, 'AF'] = df.loc[a-1, 'AF']
                    df.loc[a, 'EP'] = df.loc[a-1, 'EP']               



        elif df.loc[a-1, 'PSARdir'] == 'bear':

            df.loc[a, 'PSAR'] = df.loc[a-1, 'PSAR'] - (df.loc[a-1, 'AF']*(df.loc[a-1, 'EP']-df.loc[a-1, 'PSAR']))

            df.loc[a, 'PSARdir'] = "bear"

            if df.loc[a, 'high'] > df.loc[a-1, 'PSAR']:
                df.loc[a, 'PSARdir'] = "bull"
                df.loc[a, 'PSAR'] = df.loc[a-1, 'EP']
                df.loc[a, 'EP'] = df.loc[a-1, 'high']
                df.loc[a, 'AF'] = .02

            else:
                if df.loc[a, 'low'] < df.loc[a-1, 'EP']:
                    df.loc[a, 'EP'] = df.loc[a, 'low']
                    if df.loc[a-1, 'AF'] <= 0.18:
                        df.loc[a, 'AF'] = df.loc[a-1, 'AF'] + 0.02
                    else:
                        df.loc[a, 'AF'] = df.loc[a-1, 'AF']

                elif df.loc[a, 'low'] >= df.loc[a-1, 'EP']:
                    df.loc[a, 'AF'] = df.loc[a-1, 'AF']
                    df.loc[a, 'EP'] = df.loc[a-1, 'EP']           

    return df

Solution

  • figured it out

    df.loc[a, 'PSAR'] = df.loc[a-1, 'PSAR'] + (df.loc[a-1, 'AF']*(df.loc[a-1, 'EP']-df.loc[a-1, 'PSAR'])) 
    

    Should be df.loc[a, 'PSAR'] = df.loc[a-1, 'PSAR'] + (df.loc[a-1, 'AF']*(df.loc[a-1, 'PSAR']-df.loc[a-1, 'EP']))

    last two variables transposed!

    now I can clean up the function and make it better.