Overall Statistics |
Total Orders 174 Average Win 5.05% Average Loss -2.15% Compounding Annual Return 16.616% Drawdown 37.600% Expectancy 0.912 Start Equity 10000 End Equity 46565.18 Net Profit 365.652% Sharpe Ratio 0.705 Sortino Ratio 0.757 Probabilistic Sharpe Ratio 23.634% Loss Rate 43% Win Rate 57% Profit-Loss Ratio 2.35 Alpha 0.055 Beta 0.596 Annual Standard Deviation 0.144 Annual Variance 0.021 Information Ratio 0.185 Tracking Error 0.129 Treynor Ratio 0.17 Total Fees $155.00 Estimated Strategy Capacity $830000000.00 Lowest Capacity Asset QQQ RIWIV7K5Z9LX Portfolio Turnover 4.21% |
from AlgorithmImports import * class UniversalMarketStrategy(QCAlgorithm): def Initialize(self): # Set backtest parameters (User can change these) backtest_start_date = datetime(2015, 1, 1) # Backtest start date backtest_end_date = datetime(2025, 1, 1) # Backtest end date starting_cash = 10000 # Starting cash # Market symbols (User can change these to different assets) spy_symbol = "SPY" # Market benchmark bull_market_asset = "QQQ" # Asset for bull markets sideways_market_asset = "SPY" # Asset for sideways markets bear_market_asset = "GLD" # Asset for bear markets # SMA parameters (User can change these values) sma_short_period = 100 # Shorter SMA period sma_long_period = 200 # Longer SMA period # Apply settings self.SetStartDate(backtest_start_date) # Use SetStartDate() to set the backtest start date self.SetEndDate(backtest_end_date) # Use SetEndDate() to set the backtest end date self.SetCash(starting_cash) # Add data for the market benchmark and assets self.spy_symbol = self.AddEquity(spy_symbol, Resolution.Daily).Symbol self.bull_market_asset = self.AddEquity(bull_market_asset, Resolution.Daily).Symbol self.sideways_market_asset = self.AddEquity(sideways_market_asset, Resolution.Daily).Symbol self.bear_market_asset = self.AddEquity(bear_market_asset, Resolution.Daily).Symbol # Define SMAs for market benchmark self.spy_sma_short = self.SMA(self.spy_symbol, sma_short_period, Resolution.Daily) self.spy_sma_long = self.SMA(self.spy_symbol, sma_long_period, Resolution.Daily) # Warm-up period for SMAs (User should ensure this covers the longest SMA period) self.SetWarmUp(sma_long_period) def OnData(self, slice): # Ensure SMAs are ready before making decisions if not (self.spy_sma_short.IsReady and self.spy_sma_long.IsReady): return # Get SMA values and the current price of SPY spy_price = self.Securities[self.spy_symbol].Price sma_short_value = self.spy_sma_short.Current.Value sma_long_value = self.spy_sma_long.Current.Value # Determine the current market regime if spy_price > sma_long_value: # Bull Market if not self.Portfolio[self.bull_market_asset].Invested: self.SetHoldings(self.bull_market_asset, 1.0) self.Liquidate(self.sideways_market_asset) self.Liquidate(self.bear_market_asset) self.Debug("Bull market: Holding " + str(self.bull_market_asset)) elif sma_short_value < spy_price <= sma_long_value: # Sideways Market if not self.Portfolio[self.sideways_market_asset].Invested: self.SetHoldings(self.sideways_market_asset, 1.0) self.Liquidate(self.bull_market_asset) self.Liquidate(self.bear_market_asset) self.Debug("Sideways market: Holding " + str(self.sideways_market_asset)) elif spy_price <= sma_long_value: # Bear Market if not self.Portfolio[self.bear_market_asset].Invested: self.SetHoldings(self.bear_market_asset, 1.0) self.Liquidate(self.bull_market_asset) self.Liquidate(self.sideways_market_asset) self.Debug("Bear market: Holding " + str(self.bear_market_asset))