
Python Quantitative Trading Strategies
Learn mean reversion, trend following, pair trading, statistical arbitrage, and volatility trading strategies with Python code examples. Ideal for quant developers.
With the rise of algorithmic trading, Python has become an essential tool for quantitative development practitioners. This is due to Python's powerful ecosystem in scientific computing and data analysis, as well as its excellent third‑party library support. Libraries such as Pandas, NumPy, and SciPy provide rich data processing, numerical computation, and scientific computing functions for quantitative trading, enabling developers to conduct quantitative analysis and strategy development more efficiently. Today we introduce five classic quantitative trading strategies with corresponding Python code examples.
#1 Mean Reversion Strategy
The mean reversion strategy is a statistical arbitrage strategy based on the assumption that, in the long run, asset prices fluctuate around an average value, but eventually return to that long‑term mean. Below is a simple mean reversion strategy code example using a simple moving average to define the "mean" price and standard deviation to generate buy and sell signals. Here is the code:
python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data = pd.DataFrame({
'Date': pd.date_range(start='2023-01-01', periods=100),
'Close': np.random.normal(100, 10, 100) # generate simulated data
})
data.set_index('Date', inplace=True)
# Calculate 20‑day moving average and standard deviation
window = 20
data['Moving Average'] = data['Close'].rolling(window=window).mean()
data['Standard Deviation'] = data['Close'].rolling(window=window).std()
# Define buy and sell signal thresholds
data['Upper Bound'] = data['Moving Average'] + data['Standard Deviation']
data['Lower Bound'] = data['Moving Average'] - data['Standard Deviation']
# Generate trading signals
# Buy when price is below the mean, sell when above the mean
data['Position'] = 0
data.loc[data['Close'] < data['Lower Bound'], 'Position'] = 1 # buy signal
data.loc[data['Close'] > data['Upper Bound'], 'Position'] = -1 # sell signal
# Plot price and mean reversion bands
plt.figure(figsize=(14, 7))
plt.plot(data['Close'], label='Close Price')
plt.plot(data['Moving Average'], label='Moving Average')
plt.fill_between(data.index, data['Upper Bound'], data['Lower Bound'], color='gray', alpha=0.3, label='Mean Reversion Band')
plt.plot(data.index, data['Position'] * 50, label='Trading Signal', color='magenta')
plt.legend()
plt.show()
#2 Trend Following Strategy
The trend following strategy compares the short‑term average price with the long‑term average to identify the dominant market trend and follow it until the trend reverses. In simple terms, it finds the current market consensus for a stock – if everyone is buying, we follow suit and hold until the trend changes. In Python, we use the Moving Average Convergence Divergence (MACD) to judge short‑term price trends and generate corresponding buy/sell signals.
python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data = pd.DataFrame({
'Date': pd.date_range(start='2023-01-01', periods=200),
'Close': np.random.normal(100, 15, 200) # simulated data
})
data.set_index('Date', inplace=True)
# Calculate simple moving averages
short_window = 40
long_window = 100
data['Short MA'] = data['Close'].rolling(window=short_window).mean()
data['Long MA'] = data['Close'].rolling(window=long_window).mean()
# Generate trading signals
# Signal when short‑term MA crosses long‑term MA
data['Signal'] = 0
data['Signal'][short_window:] = np.where(data['Short MA'][short_window:] > data['Long MA'][short_window:], 1, 0)
data['Position'] = data['Signal'].diff()
# Plot price and moving averages
plt.figure(figsize=(14, 7))
plt.plot(data['Close'], label='Close Price')
plt.plot(data['Short MA'], label='40-Day Moving Average')
plt.plot(data['Long MA'], label='100-Day Moving Average')
plt.plot(data.index, data['Position'] * 50, label='Trading Signal', color='magenta', marker='o', linestyle='None')
plt.legend()
plt.show()
#3 Pair Trading
Pair trading is based on statistical arbitrage between two different assets that are highly correlated in price. When the price difference between the two deviates beyond the normal range, we buy the undervalued asset and sell the overvalued one. Over the long run, both prices should revert to their mean, but short‑term arbitrage opportunities may appear.
We can analyse the historical price relationship between two assets and generate trading signals based on deviations from the expected spread:
python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Create simulated price data for two highly correlated assets
np.random.seed(42)
data = pd.DataFrame({
'Date': pd.date_range(start='2023-01-01', periods=180),
'Asset_A': np.random.normal(100, 10, 180).cumsum() + 100,
'Asset_B': np.random.normal(100, 10, 180).cumsum() + 120
})
data.set_index('Date', inplace=True)
# Calculate price difference (spread)
data['Price_Diff'] = data['Asset_A'] - data['Asset_B']
# Calculate moving average and standard deviation of the spread
window = 30
data['Mean_Diff'] = data['Price_Diff'].rolling(window=window).mean()
data['Std_Diff'] = data['Price_Diff'].rolling(window=window).std()
# Set entry and exit thresholds
data['Upper_Bound'] = data['Mean_Diff'] + data['Std_Diff']
data['Lower_Bound'] = data['Mean_Diff'] - data['Std_Diff']
# Generate signals
# Spread > upper bound → short Asset A, long Asset B
# Spread < lower bound → long Asset A, short Asset B
data['Position'] = 0
data.loc[data['Price_Diff'] > data['Upper_Bound'], 'Position'] = -1
data.loc[data['Price_Diff'] < data['Lower_Bound'], 'Position'] = 1
# Plot asset prices and signals
plt.figure(figsize=(14, 7))
plt.subplot(211)
plt.plot(data['Asset_A'], label='Asset A')
plt.plot(data['Asset_B'], label='Asset B')
plt.legend()
plt.subplot(212)
plt.plot(data['Price_Diff'], label='Price Difference')
plt.plot(data['Mean_Diff'], label='Mean Difference')
plt.fill_between(data.index, data['Upper_Bound'], data['Lower_Bound'], color='gray', alpha=0.3, label='Trading Zone')
plt.plot(data.index, data['Position'] * 20, label='Trading Signal', color='magenta', marker='o', linestyle='None')
plt.legend()
plt.show()
#4 Statistical Arbitrage
Statistical arbitrage exploits price differences among multiple assets. One common approach is to identify pairs or portfolios of stocks that deviate from their normal value ranges and trade accordingly to earn profits. Below is a simple statistical arbitrage example in Python, trading based on the spread between two stocks.
python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
np.random.seed(42)
data = pd.DataFrame({
'Date': pd.date_range(start='2023-01-01', periods=250),
'Stock_A': np.random.normal(0, 1, 250).cumsum() + 50,
'Stock_B': np.random.normal(0, 1, 250).cumsum() + 50
})
data.set_index('Date', inplace=True)
# Calculate spread between two stocks
data['Spread'] = data['Stock_A'] - data['Stock_B']
# Calculate moving average and std of spread
window = 20
data['Spread Mean'] = data['Spread'].rolling(window=window).mean()
data['Spread Std'] = data['Spread'].rolling(window=window).std()
# Set entry and exit thresholds
entry_z = 2
exit_z = 0
data['Upper Threshold'] = data['Spread Mean'] + entry_z * data['Spread Std']
data['Lower Threshold'] = data['Spread Mean'] - entry_z * data['Spread Std']
data['Exit Threshold'] = data['Spread Mean'] + exit_z * data['Spread Std']
# Generate signals
data['Position'] = 0
data.loc[data['Spread'] > data['Upper Threshold'], 'Position'] = -1 # short A, long B
data.loc[data['Spread'] < data['Lower Threshold'], 'Position'] = 1 # long A, short B
data.loc[data['Spread'] * data['Position'] < data['Exit Threshold'], 'Position'] = 0 # exit
# Plot prices and signals
plt.figure(figsize=(14, 7))
plt.subplot(211)
plt.plot(data['Stock_A'], label='Stock A')
plt.plot(data['Stock_B'], label='Stock B')
plt.title('Stock Prices')
plt.legend()
plt.subplot(212)
plt.plot(data['Spread'], label='Spread')
plt.plot(data['Spread Mean'], label='Mean Spread')
plt.fill_between(data.index, data['Upper Threshold'], data['Lower Threshold'], color='gray', alpha=0.3, label='Entry Zone')
plt.plot(data.index, data['Position'] * 10, label='Trading Signal', color='magenta', marker='o', linestyle='None')
plt.title('Spread and Trading Signals')
plt.legend()
plt.show()
#5 Volatility Trading
Volatility strategies profit from changes in market volatility – buying when volatility is low and selling when it is high. For example, we compute daily returns and historical volatility (annualised standard deviation), then set conditions: sell when volatility exceeds 1.2 times the average, buy when it falls below 0.8 times the average. See code below:
python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
np.random.seed(42)
dates = pd.date_range(start='2023-01-01', periods=250)
prices = np.random.normal(0, 1, 250).cumsum() + 100
data = pd.DataFrame({
'Date': dates,
'Price': prices
})
data.set_index('Date', inplace=True)
# Calculate daily returns
data['Returns'] = data['Price'].pct_change()
data.dropna(inplace=True)
# Calculate historical volatility (using standard deviation as measure)
window = 20
data['Volatility'] = data['Returns'].rolling(window=window).std() * np.sqrt(252) # annualised
# Define strategy
threshold_high = data['Volatility'].mean() * 1.2
threshold_low = data['Volatility'].mean() * 0.8
data['Position'] = 0
data.loc[data['Volatility'] > threshold_high, 'Position'] = -1 # sell on high volatility
data.loc[data['Volatility'] < threshold_low, 'Position'] = 1 # buy on low volatility
# Plot price and volatility
plt.figure(figsize=(14, 10))
plt.subplot(211)
plt.plot(data['Price'], label='Price')
plt.title('Stock Price')
plt.legend()
plt.subplot(212)
plt.plot(data['Volatility'], label='Volatility')
plt.axhline(y=threshold_high, color='r', linestyle='--', label='High Threshold')
plt.axhline(y=threshold_low, color='g', linestyle='--', label='Low Threshold')
plt.plot(data.index, data['Position'] * 0.01, label='Trading Signal', color='magenta', marker='o', linestyle='None')
plt.title('Volatility and Trading Signals')
plt.legend()
plt.show()
Recommended Python Quantitative Trading Books
Doing quantitative trading with Python is a technical skill – you should maintain a lifelong learning mindset and keep improving.
Below are some e‑books I personally consider good, suitable for both beginners and experts. Click the image to start reading directly – feel free to take them. If these books help you, don't forget to recommend them to your friends.
- 1. Zero‑starting Point Python Big Data and Quantitative Trading – Target: Beginners
Click to download "Zero‑starting Point Python Big Data and Quantitative Trading".pdf - 2. The Road to Quantitative Trading: Stock Quantitative Analysis with Python – Target: Intermediate learners
Click to download "The Road to Quantitative Trading: Stock Quantitative Analysis with Python".pdf - 3. Artificial Intelligence in Finance: Implementing AI Quantitative Trading with Python – Target: Advanced practitioners
Click to download "Artificial Intelligence in Finance: Implementing AI Quantitative Trading with Python".pdf
【Recommended Reading】Essential Books for Futures Trading
【Recommended Reading】Recommended Books on Quantitative Investment