Rolling Windows
18 min
A rolling window computes a statistic over a moving slice of the
most recent n points, sliding forward one point at a time — you
already used this exact pattern for moving averages in the Quant Finance
Fundamentals course's Backtesting module. The same technique applies to
ANY statistic, not just the mean:
def rolling_std(series, window):
result = []
for i in range(window - 1, len(series)):
chunk = series[i - window + 1 : i + 1]
mean = sum(chunk) / window
variance = sum((x - mean) ** 2 for x in chunk) / window
result.append(variance ** 0.5)
return result
A rolling standard deviation tracks how VOLATILE the series has been recently — rising rolling std means the series has gotten choppier; falling means it's calmed down.
Same window size, wildly different rolling std -- exactly the signal you'd want for something like a volatility-based trading strategy, or flagging when a system's behavior has become unusually erratic.
A rolling z-score flags anomalies relative to RECENT behavior, not the series' entire history:
def rolling_zscore(series, window):
result = []
for i in range(window - 1, len(series)):
chunk = series[i - window + 1 : i + 1]
mean = sum(chunk) / window
variance = sum((x - mean) ** 2 for x in chunk) / window
std = variance ** 0.5
result.append(0.0 if std == 0 else (series[i] - mean) / std)
return result
A value that's only slightly above the series' ALL-TIME average might still be a big local anomaly if recent values have all clustered tightly together — a rolling z-score catches that; a single global z-score computed once over the whole series would miss it entirely. This is exactly how real-time anomaly detection systems (fraud detection, server monitoring) actually work.
Write `rolling_std(series, window)`: for every position with a full window available, compute the (population) standard deviation of that window. Return a list, each value rounded to 4 decimals.
Write `rolling_zscore(series, window)`: for every position with a full window available, compute how many rolling standard deviations away from the rolling mean the LAST value in that window is — `(series[i] - window_mean) / window_std`. Use 0.0 if the window's std is 0. Round to 4 decimals.
Why is a ROLLING z-score (computed from a nearby window) often more useful for anomaly detection than a GLOBAL z-score (computed from the whole series' mean/std)?
You can compute rolling standard deviation and rolling z-scores, and understand why local (rolling) statistics catch anomalies that global statistics miss.