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