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}")