Moving averages: smoothing noisy data
Raw prices jitter up and down. A moving average smooths that noise by averaging a sliding window, revealing the trend underneath. (For learning, not financial advice.)
The big idea
A simple moving average replaces each point with the average of the last N points, smoothing short-term noise.
See it in code
A moving average is built from an ordinary average: add up some closes and divide by how many there are. Here's a plain 3-day average, no sliding yet:
# The average of the last 3 closes - for study, not advice.
closes = [100, 102, 101]
avg = sum(closes) / len(closes)
print(f"Average: {avg:.2f}")Average: 101.00
One average of three prices. To smooth a whole series we compute this over and over — each time shifting the window one price forward.
Add the one idea that makes it moving: slide the window. Here we average the first three closes, then slide over by one and average the next three:
closes = [100, 102, 101, 104]
window = 3
first = closes[0:3]
second = closes[1:4]
print(f"Window 1: {sum(first) / window:.2f}")
print(f"Window 2: {sum(second) / window:.2f}")Window 1: 101.00 Window 2: 102.33
Two windows by hand. Slicing [start:stop] grabs exactly the three prices we want — now a loop can slide it across the entire series instead of stopping at two.
Now let a loop slide that window over every day. For each day (once there's enough history) we take the last window closes, average them, and print the smoothed value — the slice closes[i-window+1:i+1] is the sliding window:
closes = [100, 102, 101, 104, 103, 106]
window = 3
for i in range(window - 1, len(closes)):
chunk = closes[i - window + 1:i + 1]
avg = sum(chunk) / window
print(f"Day {i + 1}: SMA({window}) = {avg:.2f}")Day 3: SMA(3) = 101.00 Day 4: SMA(3) = 102.33 Day 5: SMA(3) = 102.67 Day 6: SMA(3) = 104.33
The first two values, 101.00 and 102.33, are exactly the windows we did by hand — the loop just keeps sliding to the end. Each value is calmer than the raw prices. The loop starts at window - 1 because you need a full window before you can average — the first days have no smoothed value.
The sliding window is a fundamental technique: smoothing sensor readings, a rolling average of daily steps, frame-rate over the last second, blurring an image. Any time recent context matters more than a single noisy point, a moving window is the tool.
Try it yourself
Change window to 2 and compare how much less it smooths. Then compute two averages — a fast (small window) and a slow (large window) — the setup for a crossover signal.
The common mistake
Off-by-one errors on the window. The slice [i-window+1:i+1] must include exactly window items ending at i. Start the loop too early and you average a partial (wrong-sized) window; get the slice bounds wrong and every value is subtly off.
What it unlocks
Averaging a window builds on lists, list indexing, and operators, and feeds trading signals.