210. Simple Moving Average
210.1. SMA (Simple Moving Average)
For a time series , the SMA of window size at time is:
The average of the last values. Equal weights on each. The forecast is .
210.1.1. Choosing the window size
The window size trades two effects:
- Small (1–3): forecast tracks recent observations closely. Responsive to changes; noisy.
- Large (10+): forecast smooths out short-term noise. Stable; lags behind real changes.
Rules of thumb:
- For non-trending, smooth series: around 5–10 typically works.
- For high-frequency noise: bigger to filter the noise.
- For responsive forecasting (regime detection): smaller .
210.1.2. Lag
SMA lags the true level. If the underlying series is rising linearly, the SMA tracks roughly time steps behind — because the average of the last values has a center of mass at . Larger → larger lag.
This is why SMA is poor for trending series — it’s structurally late. Use ETS or ARIMA when there’s trend.
210.1.3. Visualization
The SMA filters the high-frequency noise and produces a smoother curve, but with a horizontal lag relative to the data.
-
Model parameters
- : window size (number of past observations to average)
-
Observation
- : observed value at time , for
-
Output
- : one-step-ahead forecast for time , given information up to
Example
.
Data
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
| 10 | 20 | 30 | 20 | 12 | 24 | 36 | 24 |
Init — no parameters to seed; the first forecast is at once we have observations.
First forecast — at , using :
Iterate:
| 4 | 20 | (10 + 20 + 30) / 3 = 20.00 | 0.00 |
| 5 | 12 | (20 + 30 + 20) / 3 = 23.33 | −11.33 |
| 6 | 24 | (30 + 20 + 12) / 3 = 20.67 | 3.33 |
| 7 | 36 | (20 + 12 + 24) / 3 = 18.67 | 17.33 |
| 8 | 24 | (12 + 24 + 36) / 3 = 24.00 | 0.00 |
| 9 | — | (24 + 36 + 24) / 3 = 28.00 | — |
sma.py
pl.col('X').rolling_mean(window_size)