Quantitative trading is no longer the exclusive domain of hedge funds. With Python’s mature ecosystem and open data platforms, an individual investor with programming skills can build and test their own quantitative strategies over a weekend. This article provides a complete beginner workflow — from data acquisition to strategy backtesting — to help you take your first steps into quantitative investing.
Data Acquisition: Free and Paid Options
Free data sources: Yahoo Finance (yfinance Python library for US stocks, ETF daily data); Alpha Vantage (limited free API quota, suitable for beginners); Stooq (European and US stock market historical data, supported by yfinance); Deutsche Börse data (Xetra, Frankfurt Stock Exchange official open data).
Paid data sources: Quandl/Nasdaq Data Link (high-quality factor data, futures data); Refinitiv (professional-grade data, high cost). For beginners, Yahoo Finance data via yfinance is completely sufficient.
import yfinance as yf
import pandas as pd
# Get DAX index data
dax_ticker = "^GDAXI"
data = yf.download(dax_ticker, start="2020-01-01", end="2024-12-31")
print(data.tail())
A Simple Moving Average Crossover Strategy
import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
# Download data
df = yf.download("MSFT", start="2022-01-01", end="2024-12-31")["Close"]
df = df.to_frame(name="Close")
# Calculate moving averages
df["SMA20"] = df["Close"].rolling(20).mean()
df["SMA50"] = df["Close"].rolling(50).mean()
# Signal generation
df["Signal"] = 0
df.loc[df["SMA20"] > df["SMA50"], "Signal"] = 1 # Buy signal
df.loc[df["SMA20"] < df["SMA50"], "Signal"] = -1 # Sell signal
# Calculate strategy returns
df["Returns"] = df["Close"].pct_change()
df["Strategy"] = df["Signal"].shift(1) * df["Returns"]
df[["Returns", "Strategy"]].cumsum().apply(lambda x: x.exp()).plot(
title="Strategy vs Buy&Hold"
)
plt.show()
Complete quantitative trading tutorial.
Backtesting Framework Selection
Backtrader: The most mature Python backtesting framework, supporting multiple instruments, multiple timeframes, and multiple order types. Active community, suitable for complex strategies. Slightly steeper learning curve.
Vectorbt: NumPy-based vectorized backtesting framework, extremely fast (100x+ faster than Backtrader), suitable for parameter optimization and large-scale backtesting. Code is more concise but slightly less readable.
Zipline (official maintenance discontinued): Once the most mainstream backtesting framework; community support declined after Quantopian closed.
Backtesting Pitfalls: Three Biases You Must Avoid
Look-ahead Bias: Generating signals using today's closing price while assuming execution at today's closing price — in reality, you can only trade at the next day's open. You must apply shift(1) after signal calculation before computing returns.
Overfitting: Optimizing parameters to perfection on historical data so the strategy looks great historically but completely fails in real markets. Countermeasure: optimize parameters using only part of historical data (in-sample), then validate on the remainder (out-of-sample).
Ignoring transaction costs: Every trade has brokerage fees (~0.1–0.25%/trade in German markets), bid-ask spread, and slippage. High-frequency trading strategy actual returns are often substantially eroded by costs.




