Calculating Average True Range (ATR) on OHLC data with Python

dataframe, pandas, python

Solution

For anyone else looking on how to do this, here is my answer.

def wwma(values, n):
    """
     J. Welles Wilder's EMA 
    """
    return values.ewm(alpha=1/n, adjust=False).mean()

def atr(df, n=14):
    data = df.copy()
    high = data[HIGH]
    low = data[LOW]
    close = data[CLOSE]
    data['tr0'] = abs(high - low)
    data['tr1'] = abs(high - close.shift())
    data['tr2'] = abs(low - close.shift())
    tr = data[['tr0', 'tr1', 'tr2']].max(axis=1)
    atr = wwma(tr, n)
    return atr

Problem

The ATR is the average of the True Range for a given period. True Range is (High-Low) meaning I have computed this with the following: ``` df['High'].subtract(df['Low']).rolling(distance).mean() ``` However if a short period (or 'distance' in the example above) is required the ATR can be very jumpy, i.e. with large sporadic gaps appearing between some numbers. The real ATR equation recognises this and smooths it out by doing the following: ``` Current ATR = [(Prior ATR x 13) + Current TR] / 14 ``` However I am unsure how to do this in the same manner as I did above, i.e. a column wide operation. Sample data including the TR and ATR(10) from my original method: ``` Date Time Open High Low Close TR ATR 30/09/16 14:45:00+00:00 1.1216 1.1221 1.1208 1.1209 0.0013 0.0013 30/09/16 15:00:00+00:00 1.1209 1.1211 1.1203 1.1205 0.0008 0.0013 30/09/16 15:15:00+00:00 1.1205 1.1216 1.1204 1.1216 0.0012 0.0013 30/09/16 15:30:00+00:00 1.1217 1.1222 1.1213 1.1216 0.0008 0.0013 30/09/16 15:45:00+00:00 1.1216 1.1240 1.1216 1.1240 0.0025 0.0015 30/09/16 16:00:00+00:00 1.1239 1.1246 1.1228 1.1242 0.0019 0.0015 30/09/16 16:15:00+00:00 1.1242 1.1251 1.1235 1.1240 0.0016 0.0016 30/09/16 16:30:00+00:00 1.1240 1.1240 1.1234 1.1236 0.0007 0.0014 30/09/16 16:45:00+00:00 1.1237 1.1245 1.1235 1.1238 0.0009 0.0012 30/09/16 17:00:00+00:00 1.1238 1.1239 1.1231 1.1233 0.0008 0.0012 30/09/16 17:15:00+00:00 1.1233 1.1245 1.1232 1.1240 0.0013 0.0012 30/09/16 17:30:00+00:00 1.1240 1.1242 1.1228 1.1230 0.0013 0.0013 30/09/16 17:45:00+00:00 1.1230 1.1230 1.1221 1.1227 0.0009 0.0013 30/09/16 18:00:00+00:00 1.1227 1.1232 1.1227 1.1232 0.0005 0.0012 30/09/16 18:15:00+00:00 1.1232 1.1232 1.1227 1.1227 0.0005 0.0010 30/09/16 18:30:00+00:00 1.1227 1.1231 1.1225 1.1231 0.0006 0.0009 30/09/16 18:45:00+00:00 1.1231 1.1237 1.1230 1.1232 0.0007 0.0008 30/09/16 19:00:00+00:00 1.1232 1.1233 1.1229 1.1231 0.0004 0.0008 30/09/16 19:15:00+00:00 1.1231 1.1234 1.1230 1.1230 0.0004 0.0007 30/09/16 19:30:00+00:00 1.1231 1.1234 1.1230 1.1234 0.0004 0.0007 30/09/16 19:45:00+00:00 1.1233 1.1240 1.1230 1.1239 0.0010 0.0007 30/09/16 20:00:00+00:00 1.1239 1.1242 1.1237 1.1238 0.0005 0.0006 30/09/16 20:15:00+00:00 1.1238 1.1240 1.1235 1.1237 0.0005 0.0006 30/09/16 20:30:00+00:00 1.1237 1.1238 1.1235 1.1235 0.0003 0.0005 30/09/16 20:45:00+00:00 1.1235 1.1236 1.1233 1.1233 0.0003 0.0005 30/09/16 21:00:00+00:00 1.1233 1.1238 1.1233 1.1237 0.0006 0.0005 30/09/16 21:15:00+00:00 1.1237 1.1244 1.1237 1.1242 0.0008 0.0005 30/09/16 21:30:00+00:00 1.1242 1.1243 1.1239 1.1239 0.0004 0.0005 30/09/16 21:45:00+00:00 1.1239 1.1244 1.1236 1.1241 0.0008 0.0006 ```

Original source