| Overall Statistics |
|
Total Orders 16 Average Win 20.55% Average Loss -4.29% Compounding Annual Return 10.566% Drawdown 33.600% Expectancy 3.136 Start Equity 1000000 End Equity 2730098.62 Net Profit 173.010% Sharpe Ratio 0.493 Sortino Ratio 0.43 Probabilistic Sharpe Ratio 6.920% Loss Rate 29% Win Rate 71% Profit-Loss Ratio 4.79 Alpha 0.004 Beta 0.788 Annual Standard Deviation 0.129 Annual Variance 0.017 Information Ratio -0.175 Tracking Error 0.067 Treynor Ratio 0.081 Total Fees $443.83 Estimated Strategy Capacity $1900000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X Portfolio Turnover 0.41% |
#region imports
from AlgorithmImports import *
#endregion
class BollingerBandsMeanReversion(QCAlgorithm):
def initialize(self):
# Set algorithm parameters
self.set_start_date(2014, 1, 1) # Backtest start date
self.set_end_date(2024, 1, 1) # Backtest end date
self.set_cash(1_000_000) # Starting cash
# Add equity asset
self.symbol = self.add_equity("SPY", Resolution.Daily).symbol
# Set up Bollinger Bands indicator
self.bollinger = self.BB(self.symbol, 20, 2, Resolution.Daily)
# Warm-up period to initialize the Bollinger Bands
self.set_warm_up(20)
def on_data(self, data: Slice):
if self.is_warming_up:
return
# Check if the Bollinger Bands indicator is ready
if not self.bollinger.IsReady:
return
# Get the current price and Bollinger Bands values
price = self.securities[self.symbol].price
upper_band = self.bollinger.UpperBand.Current.Value
middle_band = self.bollinger.MiddleBand.Current.Value
lower_band = self.bollinger.LowerBand.Current.Value
# Debug the Bollinger Bands values
self.debug(f"Price: {price}, Upper Band: {upper_band}, Lower Band: {lower_band}")
# Check current holdings
holdings = self.portfolio[self.symbol].quantity
# Buy signal: Price below the lower Bollinger Band
if price < lower_band and holdings <= 0:
self.set_holdings(self.symbol, 1) # Invest 100% of portfolio
self.debug(f"BUY {self.symbol} at {price}")
# Sell signal: Price above the upper Bollinger Band
elif price > upper_band and holdings > 0:
self.liquidate(self.symbol)
self.debug(f"SELL {self.symbol} at {price}")