Compute a simple and an exponential moving average, and see how each one weights the past.
A simple moving average of the last n closes gives every one of those n closes the same weight, and gives every close before them a weight of zero. An exponential moving average gives today the most weight, yesterday a bit less, the day before a bit less again, and never drops a close entirely.
In this lesson I compute both on seven prices I can check by hand, reproduce one exponential value from the formula ema_t = a * price_t + (1 - a) * ema_(t-1), and then put a 50 day version of each side by side on AAPL.
Step 1. Seven prices
.rolling(3).mean() is the simple moving average over three rows. .ewm(span=3, adjust=False).mean() is the exponential one.
The exponential average carries yesterday’s value forward and mixes in today’s price. The mixing weight is a = 2 / (span + 1), so a span of 3 gives a = 0.5.
Row 0 has no yesterday, so with adjust=False pandas seeds it with the first price.
Unrolling that recursion gives the weight on each past price: a on today, a * (1 - a) on yesterday, a * (1 - a)^2 on the day before, and so on.
weights = [alpha * (1- alpha) ** k for k inrange(6)]print([round(w, 4) for w in weights])# -> [0.5, 0.25, 0.125, 0.0625, 0.0312, 0.0156]print(round(sum(weights), 4)) # -> 0.9844
[0.5, 0.25, 0.125, 0.0625, 0.0312, 0.0156]
0.9844
Six days account for 98.44% of the weight. The rest sits on everything older, halving each step back, never reaching zero.
Step 3. When an old price leaves the window
Rows 4, 5 and 6 all have a price of 12. The simple average holds at 14.666667 while the 20 is still inside its three day window, then drops to 12.0 the moment the 20 falls out.
print(ind.head(3).round(2))# -> close sma50 ema50# -> Date# -> 2020-01-01 75.08 NaN 75.08# -> 2020-01-02 76.94 NaN 75.15# -> 2020-01-03 77.34 NaN 75.24print(ind.iloc[48:51].round(2))# -> close sma50 ema50# -> Date# -> 2020-03-09 78.50 NaN 76.42# -> 2020-03-10 80.98 76.20 76.60# -> 2020-03-11 79.65 76.29 76.72
close sma50 ema50
Date
2020-01-01 75.08 NaN 75.08
2020-01-02 76.94 NaN 75.15
2020-01-03 77.34 NaN 75.24
close sma50 ema50
Date
2020-03-09 78.50 NaN 76.42
2020-03-10 80.98 76.20 76.60
2020-03-11 79.65 76.29 76.72
The early exponential values are not an average of 50 days. On 2020-01-01 the value is just the first close, and it takes several dozen rows before the seed stops mattering.
Over the rows where both exist, the exponential average sits closer to the close.