Generate code in 3 minutes
Enter your idea and AI generates runnable code.
Here is a complete, PEP8-compliant Mean Reversion trading strategy using Bollinger Bands on the QuantConnect (Lean) platform.
This algorithm implements a classic Mean Reversion strategy:
# region imports
from AlgorithmImports import *
# endregion
class BollingerMeanReversionStrategy(QCAlgorithm):
def initialize(self):
# 1. Set Strategy Settings
self.set_start_date(2020, 1, 1)
self.set_end_date(2023, 12, 31)
self.set_cash(100000) # Set Strategy Cash
# 2. Add Universe (Using SPY as the target asset)
self.ticker = "SPY"
self.equity = self.add_equity(self.ticker, Resolution.DAILY)
self.symbol = self.equity.symbol
# 3. Define Bollinger Bands Indicator
# Parameters: Period=20, Standard Deviation=2, Moving Average Type=Simple
self.bb = self.bb(self.symbol, 20, 2, MovingAverageType.SIMPLE, Resolution.DAILY)
# 4. Set WarmUp period to ensure indicators are ready immediately
self.set_warm_up(20)
def on_data(self, data: Slice):
# Ensure data exists and algorithm is done warming up
if self.is_warming_up or not self.bb.is_ready or self.symbol not in data:
return
# Get current price and indicator values
price = self.securities[self.symbol].close
upper_band = self.bb.upper_band.current.value
lower_band = self.bb.lower_band.current.value
middle_band = self.bb.middle_band.current.value
# Plotting for visual analysis
self.plot("Trade Plot", "Price", price)
self.plot("Trade Plot", "Upper Band", upper_band)
self.plot("Trade Plot", "Lower Band", lower_band)
self.plot("Trade Plot", "Middle Band", middle_band)
# --- Strategy Logic ---
# Check if we are currently invested
if not self.portfolio.invested:
# ENTRY LOGIC
# If price falls below lower band, buy (Long)
if price < lower_band:
self.set_holdings(self.symbol, 1.0)
self.debug(f"Buy Signal at {price} (Lower Band: {lower_band})")
# If price rises above upper band, sell short (Short)
elif price > upper_band:
self.set_holdings(self.symbol, -1.0)
self.debug(f"Short Signal at {price} (Upper Band: {upper_band})")
else:
# EXIT LOGIC
# If we are Long and price recovers to the mean (Middle Band)
if self.portfolio[self.symbol].is_long and price >= middle_band:
self.liquidate(self.symbol)
self.debug(f"Take Profit (Long) at {price} (Mean Reversion)")
# If we are Short and price falls back to the mean (Middle Band)
elif self.portfolio[self.symbol].is_short and price <= middle_band:
self.liquidate(self.symbol)
self.debug(f"Take Profit (Short) at {price} (Mean Reversion)")
self.bb(...): This helper method creates the Bollinger Band indicator and automatically registers it to receive data updates.self.set_warm_up(20): This ensures the algorithm processes 20 bars of data before the start date so the indicator is ready to trade immediately on day 1.self.plot(...): This generates a custom chart in the backtest results, allowing you to visually verify if the trades align with the bands.set_holdings, on_data) as per the latest QuantConnect API standards.Q: How can I change the sensitivity of the bands?
A: You can adjust the standard deviation parameter in the initialize method. Changing self.bb(self.symbol, 20, 2, ...) to self.bb(self.symbol, 20, 2.5, ...) will make the bands wider, resulting in fewer but potentially higher-quality signals.
Q: Can I use this for intraday trading?
A: Yes. Change Resolution.DAILY to Resolution.MINUTE or Resolution.HOUR in the add_equity and self.bb calls. Note that intraday data is noisier, so you might need to increase the period (e.g., from 20 to 50).
Q: How do I stop the strategy from Shorting?
A: To make this a "Long Only" strategy, simply remove the elif price > upper_band: block inside the Entry Logic and the elif self.portfolio[self.symbol].is_short block inside the Exit Logic.
Q: Why do we exit at the Middle Band instead of the opposite band?
A: Exiting at the Middle Band (Mean) increases the win rate (probability of profit) because the price touches the average more often than it swings from one extreme to the other. Exiting at the opposite band attempts to capture larger trends but often results in giving back profits if the trend reverses halfway.