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