| 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
self.SetStartDate(2015, 1, 1) # Backtest start date
self.set_end_date(2025, 1, 1)
self.SetCash(10000) # Starting cash
# Add SPY as the crossover indicator
self.spy_symbol = self.AddEquity("SPY", Resolution.Daily).Symbol
# Add assets for different regimes
self.bull_market_asset = self.AddEquity("QQQ", Resolution.Daily).Symbol
self.sideways_market_asset = self.AddEquity("SPY", Resolution.Daily).Symbol
self.bear_market_asset = self.AddEquity("GLD", Resolution.Daily).Symbol
# Define SMAs for SPY
self.spy_sma_100 = self.SMA(self.spy_symbol, 100, Resolution.Daily)
self.spy_sma_200 = self.SMA(self.spy_symbol, 200, Resolution.Daily)
# Warm up data for SMAs
self.SetWarmUp(200)
def OnData(self, slice):
# Ensure SMAs are ready
if not (self.spy_sma_100.IsReady and self.spy_sma_200.IsReady):
return
# Retrieve SMA values and current SPY price
spy_price = self.Securities[self.spy_symbol].Price
sma_100_value = self.spy_sma_100.Current.Value
sma_200_value = self.spy_sma_200.Current.Value
# Determine the current market regime and allocate assets accordingly
if spy_price > sma_200_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)
elif sma_100_value < spy_price <= sma_200_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)
elif spy_price <= sma_200_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)