jason m
jason m

Reputation: 6835

Using pandas and EWMA

I am accustomed to exponential moving average (EMA) being calculated the following way:

SMA: 10 period sum / 10 

Multiplier: (2 / (Time periods + 1) ) = (2 / (10 + 1) ) = 0.1818 (18.18%)

EMA: {Close - EMA(previous day)} x multiplier + EMA(previous day). 

Yet when I run pd.ewma(df['Close']) I do not see the output that matches this approach.

The following code gives me the answer I am expecting, but takes a bit longer to run.

Anyone have any pointers on what is the proper way to leverage this library to give me the output I am expecting?

import pandas.io.data as web

import datetime
import pandas as pd
start = datetime.datetime(2010, 1, 1)

end = datetime.datetime.today()
f = web.DataReader("SPY", 'yahoo', start, end)
f['sma']=pd.rolling_mean(f['Adj Close'],10)
days=10.
alpha=(2./(days+1.))
d={}

for x in f[(f['sma']>0)].index:
    if len(d)==0:
        d[x] = f[(f.index==x)]['sma'].values[0]
    else:
        d[x] = (f[(f.index==x)]['Adj Close'].values[0] - d[dt_prior])*alpha + d[dt_prior]

    dt_prior = x
pd.Series(d)

Upvotes: 0

Views: 3233

Answers (1)

zerovector
zerovector

Reputation: 1360

I think you were almost on there on your own.

e = f['Adj Close'].ewm(span=10, min_periods=10)

will generate what you are looking for. You may need to play around with adjust=True and other parameters to get it to exactly match the results of your for loop. But if you compare

e.tail(10) 
d.tail(10)

you'll see that the (possibly different) starting point of the ewma doesn't matter anymore and the latest results match exactly.

Upvotes: 1

Related Questions