A Python backtesting framework that tests the Golden Cross moving average strategy against a buy-and-hold benchmark using 5 years of real historical data.
I am a Mechatronics Engineering graduate and a postgraduate in Finance from Henley Business School, looking to enter the field of finance in data science, machine learning, or quantitative finance.
- πΌ LinkedIn: linkedin.com/in/sauravsen34
- π§ Email: saurav0sen34@gmail.com
Rather than making investment decisions based on intuition, this project uses past data to test whether a trading strategy would have actually made money on real historical prices β before risking any real capital. It compares the strategy's performance against simply buying and holding the stock for the same period.
A trend-following strategy based on two moving averages:
- Buy signal (Golden Cross): When the 50-day MA crosses above the 200-day MA β bullish signal, enter the market
- Sell signal (Death Cross): When the 50-day MA crosses below the 200-day MA β bearish signal, exit the market
The idea is to ride uptrends and avoid downtrends by following momentum rather than predicting price direction.
| Metric | Value |
|---|---|
| Initial Capital | $10,000 |
| Buy & Hold Final Value | $15,795 |
| Strategy Final Value | $8,299 |
| Strategy vs Buy & Hold | -47.46% |
What this tells us: The Golden Cross strategy significantly underperformed buy and hold for Apple. This is because Apple has such a strong long-term uptrend that being out of the market during Death Cross periods means missing the biggest gains. The strategy is too slow to react to Apple's momentum-driven price action.
This is an honest result β and a valuable one. It shows that backtesting is essential precisely because strategies that sound logical in theory can lose money in practice.
Backtesting β testing a trading strategy on historical data to evaluate performance before deploying real capital. The litmus test for any algorithmic strategy.
Lookahead Bias β a common backtesting mistake where future information is accidentally used to make past trading decisions, producing unrealistically good results. Prevented here by using Signal.shift(1) β trading on yesterday's signal, not today's.
Benchmark β the buy-and-hold return used as a comparison. A strategy that doesn't beat the benchmark has no practical value.
Missing Costs β this backtest does not account for transaction costs, slippage, or taxes. Real results would be worse.
git clone https://github.com/sauravsen3/algorithmic-backtest.git
cd algorithmic-backtest
pip install -r requirements.txt
python backtest.pyalgorithmic-backtest/
β
βββ backtest.py # Strategy logic, signals, backtest, chart
βββ requirements.txt # Python dependencies
βββ backtest_results.png # Generated on first run
- yfinance β 5 years of historical OHLCV data
- pandas / numpy β signal generation and return calculation
- matplotlib β strategy vs benchmark performance chart
Part of a series of quantitative finance projects. Previous: Portfolio Optimisation. Next: Pairs Trading Strategy.