Smoothing a noisy series and finding its rhythm
A filter turns one series into another by mixing each value with its neighbours. A moving average of days is the simplest filter: each output is the average of the last inputs, so noise shrinks but the output also lags behind. An exponential moving average (EMA) gives recent days more weight: , where is the smoothing weight. signal.lfilter(b, a, x) runs any such filter on a series, using only past and present values. The average delay of an EMA is days, and that of an -day moving average is days, so a 19-day average and an EMA with both lag by about 9 days.
The second job is finding cycles. signal.periodogram(x) splits the variance of a series into frequencies, measured in cycles per day. A peak at frequency means a repeating pattern with period days. With one observation per day you can see frequencies only up to cycles per day, the Nyquist limit, because a faster cycle cannot be told apart from a slower one. One warning matters a great deal in trading. signal.filtfilt runs the filter forward and then backward, which removes the lag, but each output then uses future values. A signal built with filtfilt looks perfect in a backtest and cannot be traded, because tomorrow's data is not available today. Use only causal filters such as lfilter for anything you plan to trade.
- Smoothing costs lag: a longer window or a smaller removes more noise and delays the signal more.
- Periods from peaks: a periodogram peak at frequency means a cycle of days, up to a limit of 0.5 cycles a day.
- Only causal filters for trading:
filtfiltuses the future, so it is for analysis, never for a live signal.
Lab · what's graded
- An EMA step10 pts
- A moving average10 pts
- The weight for a window10 pts
- A period from a frequency10 pts
- The lag of an EMA10 pts
- What each routine does15 pts
- Why filtfilt cannot be traded35 pts