Backtesting
20 min
Backtesting simulates how a trading strategy would have performed on historical data — before risking real money on it. The moving average crossover is one of the oldest, simplest strategies: compute a short-window and long-window average of price, and treat the SHORT average crossing above the LONG average as a "buy" signal (recent prices are outpacing the longer trend — momentum is picking up).
def moving_average(prices, window):
result = []
for i in range(window - 1, len(prices)):
avg = sum(prices[i - window + 1 : i + 1]) / window
result.append(avg)
return result
print(moving_average([10, 11, 12, 13, 14], 3)) # [11.0, 12.0, 13.0]
The short MA reacts to recent price moves faster than the long MA does -- that lag difference is exactly what a crossover strategy is trying to detect and trade on.
A crossover strategy generates a trading signal by comparing the two:
def sma_crossover_signal(prices, short_window, long_window):
short_ma = sum(prices[-short_window:]) / short_window
long_ma = sum(prices[-long_window:]) / long_window
if short_ma > long_ma:
return 1 # "golden cross" -- bullish signal
elif short_ma < long_ma:
return -1 # "death cross" -- bearish signal
return 0
Backtesting this kind of strategy across years of historical data tells you how it WOULD have performed — but a strategy that looks great on history isn't automatically great going forward. The real risk is overfitting: tuning window sizes and rules so precisely to historical noise that the strategy has essentially memorized the past rather than capturing a real, persistent pattern — the same overfitting risk you'll see again in the Model Evaluation course, applied to trading instead of machine learning.
Write `moving_average(prices, window)`: return a list of simple moving averages — one for every position where a full `window` of prices is available — each rounded to 4 decimals.
Write `sma_crossover_signal(prices, short_window, long_window)`: compute the short-window and long-window moving averages over the MOST RECENT prices, and return 1 if short > long, -1 if short < long, 0 if equal.
What is the main danger of 'overfitting' a backtested trading strategy?
You can compute moving averages and implement a basic crossover trading signal, and understand backtesting's central risk: overfitting a strategy to historical noise.