Overall Statistics
Total Orders
26610
Average Win
0.08%
Average Loss
-0.06%
Compounding Annual Return
27.819%
Drawdown
7.300%
Expectancy
0.459
Start Equity
100000
End Equity
3219033.19
Net Profit
3119.033%
Sharpe Ratio
2.131
Sortino Ratio
2.964
Probabilistic Sharpe Ratio
100.000%
Loss Rate
41%
Win Rate
59%
Profit-Loss Ratio
1.45
Alpha
0.146
Beta
0.232
Annual Standard Deviation
0.078
Annual Variance
0.006
Information Ratio
0.61
Tracking Error
0.128
Treynor Ratio
0.719
Total Fees
$0.00
Estimated Strategy Capacity
$7700000.00
Lowest Capacity Asset
EUM TXA0MGR7LUG5
Portfolio Turnover
14.83%
Drawdown Recovery
163
# region imports
from AlgorithmImports import *
# endregion
# Additional helper methods for the Symphony DSL strategy

def _us_equities_main_strategy(self) -> dict:
    """Main equity strategy when no overbought conditions"""
    allocations = {}
    
    spy_rsi_70 = self._get_rsi("SPY", 70)
    qqq_rsi_90 = self._get_rsi("QQQ", 90)
    
    if spy_rsi_70 > 62:
        # Overbought on longer timeframe
        if qqq_rsi_90 > 60:
            # VIX blend
            smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
            for ticker, weight in smooth_safety.items():
                allocations[ticker] = weight
        else:
            # Defensive assets
            allocations["IAU"] = 0.5
            allocations["EDV"] = 0.5
    else:
        # Normal market - use ticker blend with inverse volatility
        intl_group = self._calculate_inverse_volatility_weights(["SCHE", "AIA"], 10)
        domestic_group = self._calculate_inverse_volatility_weights(["QQQ", "SPY"], 10)
        
        for ticker, weight in intl_group.items():
            allocations[ticker] = weight * 0.5
        for ticker, weight in domestic_group.items():
            allocations[ticker] = weight * 0.5
    
    return allocations

def _steadfast_hedged(self) -> dict:
    """Wrapper for steadfast_portfolio_hedged"""
    return self._steadfast_portfolio_hedged()

def _alt_blocks(self) -> dict:
    """Alternative blocks - EEM and TLT momentum"""
    allocations = {}
    
    # EEM strategy
    eem_price = self._get_price("EEM")
    eem_sma_200 = self._get_sma("EEM", 200)
    
    if eem_price > eem_sma_200:
        allocations["EEM"] = 0.5
    else:
        allocations["EUM"] = 0.5
    
    # TLT momentum
    tlt_rsi_10 = self._get_rsi("TLT", 10)
    tlt_sma_15 = self._get_sma("TLT", 25)
    tlt_sma_50 = self._get_sma("TLT", 50)
    
    if tlt_rsi_10 < 35:
        allocations["TLT"] = 0.5
    elif tlt_sma_15 > tlt_sma_50:
        allocations["TLT"] = 0.5
    else:
        allocations["SHV"] = 0.5
    
    return allocations

def _ftlt_2007_hedged(self) -> dict:
    """2007 FTLT with hedging"""
    allocations = {}
    
    # 12% FTLT, 88% hedgers
    ftlt_alloc = self._ftlt_2007()
    for ticker, weight in ftlt_alloc.items():
        allocations[ticker] = weight * 0.12
    
    # Hedgers
    hedge_alloc = self._hedgers()
    for ticker, weight in hedge_alloc.items():
        if ticker in allocations:
            allocations[ticker] += weight * 0.88
        else:
            allocations[ticker] = weight * 0.88
    
    return allocations

def _tip_tmv_strategy(self) -> dict:
    """TIP/TMV strategy"""
    allocations = {}
    
    tlt_price = self._get_price("TLT")
    tlt_sma_200 = self._get_sma("TLT", 200)
    tmf_rsi_10 = self._get_rsi("TMF", 10)
    
    if tlt_price > tlt_sma_200:
        if tmf_rsi_10 < 32:
            allocations["TMF"] = 1.0
        else:
            allocations["TIP"] = 0.5
            allocations["BIL"] = 0.5
    else:
        allocations["BIL"] = 1.0
    
    return allocations

def _tip_strategy(self) -> dict:
    """TIP momentum strategy"""
    allocations = {}
    
    iei_sma_50 = self._get_sma("IEI", 50)
    iei_sma_25 = self._get_sma("IEI", 25)
    iei_sma_9 = self._get_sma("IEI", 10)
    
    if iei_sma_50 > iei_sma_25 > iei_sma_9:
        allocations["BIL"] = 1.0
    else:
        allocations["TIP"] = 1.0
    
    return allocations

def _tlt_strategy(self) -> dict:
    """TLT momentum strategy"""
    allocations = {}
    
    tlt_sma_350 = self._get_sma("TLT", 200)
    tlt_sma_550 = self._get_sma("TLT", 200)
    tlt_rsi_60 = self._get_rsi("TLT", 60)
    
    if tlt_sma_350 > tlt_sma_550:
        if tlt_rsi_60 > 62:
            allocations["SHY"] = 1.0
        else:
            allocations["TLT"] = 1.0
    else:
        if tlt_rsi_60 > 53:
            allocations["TLT"] = 1.0
        else:
            allocations["SHV"] = 1.0
    
    return allocations

def _ief_strategy(self) -> dict:
    """IEF strategy"""
    allocations = {}
    
    iei_sma_50 = self._get_sma("IEI", 50)
    iei_sma_25 = self._get_sma("IEI", 25)
    
    if iei_sma_50 > iei_sma_25:
        allocations["IEF"] = 1.0
    else:
        allocations["BIL"] = 1.0
    
    return allocations

def _iei_strategy(self) -> dict:
    """IEI strategy"""
    allocations = {}
    
    iei_sma_50 = self._get_sma("IEI", 50)
    iei_sma_25 = self._get_sma("IEI", 25)
    
    if iei_sma_50 > iei_sma_25:
        allocations["IEI"] = 1.0
    else:
        allocations["BIL"] = 1.0
    
    return allocations

def _bil_volatility_hedge(self) -> dict:
    """BIL with volatility hedge"""
    allocations = {}
    
    qqq_rsi_10 = self._get_rsi("QQQ", 10)
    spy_rsi_10 = self._get_rsi("SPY", 10)
    
    if qqq_rsi_10 > 79 or spy_rsi_10 > 80:
        allocations["UVXY"] = 1.0
    else:
        allocations["BIL"] = 1.0
    
    return allocations

def _usd_strength(self) -> dict:
    """US Dollar strength strategy"""
    allocations = {}
    
    spy_rsi_60 = self._get_rsi("SPY", 60)
    
    if spy_rsi_60 > 60:
        allocations["TLT"] = 1.0
    else:
        allocations["SHY"] = 1.0
    
    return allocations

def _energy_momentum_v3(self) -> dict:
    """Energy momentum V3"""
    allocations = {}
    
    # Oil strategy
    uco_rsi_10 = self._get_rsi("UCO", 10)
    dbo_price = self._get_price("DBO")
    dbo_sma_130 = self._get_sma("DBO", 50)
    
    if uco_rsi_10 < 14:
        allocations["UCO"] = 0.5
    elif dbo_price > dbo_sma_130:
        allocations["DBO"] = 0.5
    else:
        allocations["SHV"] = 0.5
    
    # Natural gas
    fcg_sma_100 = self._get_sma("FCG", 50)
    fcg_sma_500 = self._get_sma("FCG", 200)
    
    if fcg_sma_100 > fcg_sma_500:
        allocations["FCG"] = 0.5
    else:
        allocations["SHV"] = 0.5
    
    return allocations

def _commodities_macro_momentum(self) -> dict:
    """Commodities macro momentum"""
    allocations = {}
    
    dbc_sma_100 = self._get_sma("DBC", 50)
    dbc_sma_252 = self._get_sma("DBC", 200)
    dbc_sma_50 = self._get_sma("DBC", 50)
    
    if dbc_sma_100 > dbc_sma_252:
        if dbc_sma_50 > dbc_sma_100:
            allocations["DBC"] = 1.0
        else:
            allocations["SHY"] = 1.0
    else:
        allocations["SHY"] = 1.0
    
    return allocations

def _shorting_spy(self) -> dict:
    """Shorting SPY strategy"""
    allocations = {}
    
    spy_price = self._get_price("SPY")
    spy_sma_200 = self._get_sma("SPY", 200)
    qqq_rsi_10 = self._get_rsi("QQQ", 10)
    
    if spy_price > spy_sma_200:
        allocations["SHV"] = 1.0
    elif qqq_rsi_10 < 30:
        allocations["XLK"] = 1.0
    else:
        allocations["SH"] = 0.5
        allocations["SHV"] = 0.5
    
    return allocations

def _volatility_strategies(self) -> dict:
    """Volatility strategies"""
    allocations = {}
    
    tqqq_rsi_10 = self._get_rsi("TQQQ", 10)
    spy_rsi_10 = self._get_rsi("SPY", 10)
    
    if tqqq_rsi_10 > 79 or spy_rsi_10 > 80:
        allocations["UVXY"] = 1.0
    else:
        allocations["SHY"] = 1.0
    
    return allocations

def _uvxy_win_rate_strategy(self) -> dict:
    """UVXY 100% win rate strategy"""
    allocations = {}
    
    tqqq_rsi_10 = self._get_rsi("TQQQ", 10)
    uvxy_rsi_60 = self._get_rsi("UVXY", 60)
    spy_rsi_10 = self._get_rsi("SPY", 10)
    
    if tqqq_rsi_10 > 81 and uvxy_rsi_60 > 40:
        allocations["UVXY"] = 1.0
    elif spy_rsi_10 > 80 and uvxy_rsi_60 > 40:
        allocations["UVXY"] = 1.0
    else:
        allocations["SHV"] = 1.0
    
    return allocations
# region imports
from AlgorithmImports import *
from collections import defaultdict
# endregion

class HelperStrategies:
    """Helper strategies to reduce main.py size"""
    
    def __init__(self, algorithm):
        self.algo = algorithm
    
    def us_equities_main_strategy(self) -> dict:
        """Main equity strategy - full DSL complexity"""
        allocations = {}
        
        spy_rsi_70 = self.algo._get_rsi("SPY", 70)
        qqq_rsi_90 = self.algo._get_rsi("QQQ", 90)
        vixy_cum_ret_10 = self.algo._get_cumulative_return("VIXY", 10)
        
        if spy_rsi_70 > 62:
            if qqq_rsi_90 > 60:
                smooth_safety = self.algo._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                for ticker, weight in smooth_safety.items():
                    allocations[ticker] = weight * 0.25
                allocations["IAU"] = 0.25
                allocations["USO"] = 0.25
                allocations["DBC"] = 0.25
            else:
                allocations["EDV"] = 0.5
                allocations["IAU"] = 0.5
        else:
            if vixy_cum_ret_10 > 20:
                high_vol_alloc = self.high_volatility_strategy()
                for ticker, weight in high_vol_alloc.items():
                    allocations[ticker] = weight
            else:
                tech_util_alloc = self.tech_vs_utilities_strategy()
                for ticker, weight in tech_util_alloc.items():
                    allocations[ticker] = weight
        
        return allocations
    
    def high_volatility_strategy(self) -> dict:
        """High volatility strategy"""
        allocations = {}
        
        spy_price = self.algo._get_price("SPY")
        spy_sma_200 = self.algo._get_sma("SPY", 200)
        vixy_cum_ret_10 = self.algo._get_cumulative_return("VIXY", 10)
        tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
        
        if spy_price > spy_sma_200:
            intl_group = self.algo._calculate_inverse_volatility_weights(["SCHE", "AIA"], 10)
            domestic_group = self.algo._calculate_inverse_volatility_weights(["SPY", "QQQ"], 10)
            
            for ticker, weight in intl_group.items():
                allocations[ticker] = weight * 0.5
            for ticker, weight in domestic_group.items():
                allocations[ticker] = weight * 0.5
        else:
            if tqqq_rsi_10 < 30:
                allocations["IYW"] = 1.0
            else:
                if vixy_cum_ret_10 > 25:
                    splv_btal = self.algo._calculate_inverse_volatility_weights(["USMV", "BTAL"], 10)
                    for ticker, weight in splv_btal.items():
                        allocations[ticker] = weight
                else:
                    intl_group = self.algo._calculate_inverse_volatility_weights(["SCHE", "AIA"], 10)
                    domestic_group = self.algo._calculate_inverse_volatility_weights(["SPY", "QQQ"], 10)
                    
                    for ticker, weight in intl_group.items():
                        allocations[ticker] = weight * 0.5
                    for ticker, weight in domestic_group.items():
                        allocations[ticker] = weight * 0.5
        
        return allocations
    
    def tech_vs_utilities_strategy(self) -> dict:
        """Tech vs Utilities momentum strategy"""
        allocations = {}
        
        iyw_rsi_126 = self.algo._get_rsi("IYW", 126)
        xlp_rsi_126 = self.algo._get_rsi("XLP", 126)
        
        if iyw_rsi_126 > xlp_rsi_126:
            agg_sh_alloc = self.agg_sh_strategy(2.0)
            for ticker, weight in agg_sh_alloc.items():
                allocations[ticker] = weight
        else:
            tlt_rsi_126 = self.algo._get_rsi("TLT", 126)
            
            if tlt_rsi_126 < 50:
                agg_sh_alloc = self.agg_sh_strategy(1.5)
                for ticker, weight in agg_sh_alloc.items():
                    allocations[ticker] = weight
            else:
                qqq_price = self.algo._get_price("QQQ")
                qqq_sma_25 = self.algo._get_sma("QQQ", 25)
                
                if qqq_price > qqq_sma_25:
                    allocations["QQQ"] = 1.0
                else:
                    allocations["EDV"] = 0.5
                    allocations["SHY"] = 0.5
        
        return allocations
    
    def agg_sh_strategy(self, leverage: float) -> dict:
        """AGG vs SH momentum with leverage control"""
        allocations = {}
        
        agg_rsi_20 = self.algo._get_rsi("AGG", 20)
        sh_rsi_60 = self.algo._get_rsi("SH", 60)
        
        if agg_rsi_20 > sh_rsi_60:
            bgx_usmv = self.algo._calculate_inverse_volatility_weights(["USMV", "SPY"], 20)
            
            for ticker, weight in bgx_usmv.items():
                allocations[ticker] = weight * 0.5
            
            if leverage >= 2.0:
                allocations["TQQQ"] = 0.5
            else:
                allocations["QLD"] = 0.5
        else:
            igsb_rsi_20 = self.algo._get_rsi("IGSB", 20)
            spy_rsi_20 = self.algo._get_rsi("SPY", 20)
            
            if igsb_rsi_20 > spy_rsi_20:
                bgx_usmv = self.algo._calculate_inverse_volatility_weights(["USMV", "SPY"], 20)
                
                for ticker, weight in bgx_usmv.items():
                    allocations[ticker] = weight * 0.5
                
                if leverage >= 2.0:
                    allocations["TQQQ"] = 0.5
                else:
                    allocations["QLD"] = 0.5
            else:
                allocations["PSQ"] = 1.0
        
        return allocations
# region imports
from AlgorithmImports import *
from collections import defaultdict
import numpy as np
from strategy_components import StrategyComponents
from helper_strategies import HelperStrategies
# endregion

class TangencyVolatilityStrategy(QCAlgorithm):
    """Complex multi-strategy portfolio based on Symphony DSL conversion"""
    
    def initialize(self):
        self.set_start_date(2012, 1, 1)
        self.set_cash(100000)
        self.settings.free_portfolio_value_percentage = 0.0
        self.settings.seed_initial_prices = True  # Ensure prices available
        
        # Core universe of symbols from the strategy
        self._symbols = {}
        self._add_core_symbols()
        
        # Indicator management
        self._indicators = {}
        self._setup_indicators()
        
        self.set_warmup(timedelta(days=600))
        
        # Initialize strategy components helper
        self._strategy_components = StrategyComponents(self)
        self._helper_strategies = HelperStrategies(self)
        
        # Performance tracking
        self._rebalance_count = 0
        self._last_rebalance_time = None
        
        # Caching for expensive calculations
        self._cache = {}
        self._cache_date = None
    
    def _add_core_symbols(self):
        """Add the core symbols used in the strategy"""
        # Volatility products
        volatility_symbols = ["VIXY", "UVXY", "VIXM", "SVXY"]
        
        # Equity ETFs
        equity_symbols = ["SPY", "QQQ", "TQQQ", "SOXX", "SOXL", "SOXS",
                         "SCHX", "MGC", "IOO", "XLP", "VTV", "VOX", "XLF",
                         "XLK", "IYW", "IYY", "TECL", "QLD", "SSO", "UPRO",

                         "IDU", "EQWL", "RSPT", "XMPT", "OEF", "KRE", "BGX", "VTI",
                         "VBR", "VUG", "VO", "VB", "VEA", "VNQ", "XLV", "XLI",
                         "XLE", "XLY", "XLU", "XLRE", "IWM", "MDY", "DIA"]
        
        # International
        international_symbols = ["EEM", "EDC", "EDZ", "EEMV", "SCHE", "AIA"]
        
        # Defensive/Beta
        defensive_symbols = ["BTAL", "EUM", "USMV", "PSQ", "SH", "QID"]
        
        # Bonds
        bond_symbols = ["BIL", "SHV", "SHY", "TLT", "TMF", "TMV", "IEF", "IEI",

                       "BND", "AGG", "TIP", "IGSB", "BSV", "EDV", "IGIB",
                       "LQD", "HYG", "JNK", "EMB", "MUB", "VCSH", "VCIT"]
        
        # Commodities
        commodity_symbols = ["GLD", "IAU", "DBC", "XME", "DBA", "DBO", "USO",
                           "UCO", "FCG", "UNG", "KOLD", "BOIL"]
        
        # Stocks mentioned
        stocks = ["COKE", "COST", "LLY", "NVO", "GE", "PGR"]
        
        # Additional symbols from DSL
        additional_symbols = ["UUP", "ICLN", "TAN", "FAN", "XOP", "SPHB", "SCHD", 
                             "BWZ", "EMB", "ILCG", "VOOG", "VOOV", "FAS", "UGL", 
                             "PST", "DBB", "WOOD", "SLV", "USD"]
        
        all_symbols = (volatility_symbols + equity_symbols + international_symbols + 
                      defensive_symbols + bond_symbols + commodity_symbols + stocks + 
                      additional_symbols)
        
        for ticker in all_symbols:
            equity = self.add_equity(ticker, Resolution.MINUTE)
            equity.set_fee_model(ConstantFeeModel(0))
            self._symbols[ticker] = equity.symbol
    
    def _setup_indicators(self):
        """Setup indicators for all symbols - manual update"""
        for ticker, symbol in self._symbols.items():
            # Create indicators without consolidators
            self._indicators[ticker] = {
                'rsi_5': RelativeStrengthIndex(5),
                'rsi_10': RelativeStrengthIndex(10),
                'rsi_11': RelativeStrengthIndex(11),
                'rsi_12': RelativeStrengthIndex(12),
                'rsi_14': RelativeStrengthIndex(14),
                'rsi_16': RelativeStrengthIndex(16),
                'rsi_20': RelativeStrengthIndex(20),
                'rsi_21': RelativeStrengthIndex(21),
                'rsi_30': RelativeStrengthIndex(30),
                'rsi_45': RelativeStrengthIndex(45),
                'rsi_60': RelativeStrengthIndex(60),
                'rsi_70': RelativeStrengthIndex(70),
                'rsi_90': RelativeStrengthIndex(90),
                'rsi_126': RelativeStrengthIndex(126),
                'rsi_200': RelativeStrengthIndex(200),
                'sma_9': SimpleMovingAverage(9),
                'sma_10': SimpleMovingAverage(10),
                'sma_15': SimpleMovingAverage(15),
                'sma_20': SimpleMovingAverage(20),
                'sma_21': SimpleMovingAverage(21),
                'sma_24': SimpleMovingAverage(24),
                'sma_25': SimpleMovingAverage(25),
                'sma_30': SimpleMovingAverage(30),
                'sma_50': SimpleMovingAverage(50),
                'sma_60': SimpleMovingAverage(60),
                'sma_65': SimpleMovingAverage(65),
                'sma_100': SimpleMovingAverage(100),
                'sma_130': SimpleMovingAverage(130),
                'sma_135': SimpleMovingAverage(135),
                'sma_150': SimpleMovingAverage(150),
                'sma_200': SimpleMovingAverage(200),
                'sma_210': SimpleMovingAverage(210),
                'sma_252': SimpleMovingAverage(252),
                'sma_350': SimpleMovingAverage(350),
                'sma_400': SimpleMovingAverage(400),
                'sma_450': SimpleMovingAverage(450),
                'sma_500': SimpleMovingAverage(500),
                'sma_550': SimpleMovingAverage(550),
                'ema_5': ExponentialMovingAverage(5),
                'ema_8': ExponentialMovingAverage(8),
                'ema_9': ExponentialMovingAverage(9),
                'ema_10': ExponentialMovingAverage(10),
                'ema_25': ExponentialMovingAverage(25),
                'ema_30': ExponentialMovingAverage(30),
                'ema_50': ExponentialMovingAverage(50),
                'ema_100': ExponentialMovingAverage(100),
                'ema_200': ExponentialMovingAverage(200),
                'std_10': StandardDeviation(10),
                'std_20': StandardDeviation(20),
                'std_21': StandardDeviation(21)
            }
        
        # Track last update date for each symbol
        self._last_update = {}
    
    def _get_rsi(self, ticker: str, window: int) -> float:
        """Get RSI value for a ticker"""
        if ticker not in self._indicators:
            return 50
        key = f'rsi_{window}'
        if key in self._indicators[ticker] and self._indicators[ticker][key].is_ready:
            return self._indicators[ticker][key].current.value
        return 50
    
    def _get_price(self, ticker: str) -> float:
        """Get current price for ticker"""
        if ticker in self._symbols:
            return self.securities[self._symbols[ticker]].price
        return 0
    
    def _get_volatility(self, ticker: str, window: int = 10) -> float:
        """Get volatility (standard deviation of returns) for a ticker"""
        if ticker not in self._indicators:
            return 0.01
        
        key = f'std_{window}'
        if key in self._indicators[ticker] and self._indicators[ticker][key].is_ready:
            vol = self._indicators[ticker][key].current.value
            return max(vol, 0.001)  # Avoid division by zero
        return 0.01
    
    def _calculate_inverse_volatility_weights(self, tickers: list, window: int = 10) -> dict:
        """Calculate inverse volatility weights for a list of tickers with validation
        
        Args:
            tickers: List of ticker symbols
            window: Lookback window for volatility calculation
            
        Returns:
            Dictionary of ticker -> weight
        """
        if not tickers:
            return {}
        
        # Remove duplicates and filter valid tickers
        valid_tickers = [t for t in set(tickers) if t in self._symbols]
        
        if not valid_tickers:
            return {}
        
        # Get volatilities for all tickers
        volatilities = {}
        for ticker in valid_tickers:
            vol = self._get_volatility(ticker, window)
            if vol > 0 and not np.isnan(vol) and not np.isinf(vol):
                volatilities[ticker] = vol
        
        if not volatilities:
            # Equal weight fallback
            equal_weight = 1.0 / len(valid_tickers)
            return {ticker: equal_weight for ticker in valid_tickers}
        
        # Calculate inverse volatilities with bounds
        inverse_vols = {ticker: 1.0 / max(vol, 0.0001) for ticker, vol in volatilities.items()}
        
        # Normalize to sum to 1.0
        total_inverse_vol = sum(inverse_vols.values())
        
        if total_inverse_vol <= 0:
            # Fallback to equal weight
            equal_weight = 1.0 / len(volatilities)
            return {ticker: equal_weight for ticker in volatilities.keys()}
        
        weights = {ticker: inv_vol / total_inverse_vol for ticker, inv_vol in inverse_vols.items()}
        
        # Validate weights
        weights = {ticker: max(0, min(1, weight)) for ticker, weight in weights.items()}
        
        return weights
    
    def _blend_with_inverse_volatility(self, allocations: dict, window: int = 10) -> dict:
        """Apply inverse volatility weighting to existing allocations
        
        Args:
            allocations: Dictionary of ticker -> base_weight
            window: Lookback window for volatility
            
        Returns:
            Dictionary with adjusted weights
        """
        if not allocations:
            return {}
        
        tickers = list(allocations.keys())
        inv_vol_weights = self._calculate_inverse_volatility_weights(tickers, window)
        
        # Blend the allocations with inverse volatility weights
        adjusted = {}
        for ticker in tickers:
            base_weight = allocations.get(ticker, 0)
            inv_vol_weight = inv_vol_weights.get(ticker, 0)
            # Use inverse volatility weighting
            adjusted[ticker] = base_weight * inv_vol_weight
        
        # Renormalize
        total = sum(adjusted.values())
        if total > 0:
            adjusted = {ticker: weight / total for ticker, weight in adjusted.items()}
        
        return adjusted
    
    def _get_sma(self, ticker: str, window: int) -> float:
        """Get SMA value"""
        if ticker not in self._indicators:
            return 0
        key = f'sma_{window}'
        if key in self._indicators[ticker] and self._indicators[ticker][key].is_ready:
            return self._indicators[ticker][key].current.value
        return 0
    
    def _get_ema(self, ticker: str, window: int) -> float:
        """Get EMA value"""
        if ticker not in self._indicators:
            return 0
        key = f'ema_{window}'
        if key in self._indicators[ticker] and self._indicators[ticker][key].is_ready:
            return self._indicators[ticker][key].current.value
        return 0
    
    def _get_max_drawdown(self, ticker: str, window: int) -> float:
        """Get maximum drawdown over window period as percentage with caching"""
        if ticker not in self._symbols:
            return 0
        
        # Check cache
        cache_key = f"max_dd_{ticker}_{window}"
        if self._cache_date == self.time.date() and cache_key in self._cache:
            return self._cache[cache_key]
        
        history = self.history(self._symbols[ticker], window + 1, Resolution.DAILY)
        if history.empty or len(history) < 2:
            return 0
        
        prices = history['close'].values
        running_max = np.maximum.accumulate(prices)
        drawdowns = (prices - running_max) / running_max * 100
        result = abs(float(np.min(drawdowns)))
        
        # Cache result
        self._cache[cache_key] = result
        return result
    
    def _get_moving_average_return(self, ticker: str, window: int) -> float:
        """Get moving average return over window period"""
        if ticker not in self._symbols:
            return 0
        
        current_price = self._get_price(ticker)
        ma = self._get_sma(ticker, window)
        
        if ma > 0:
            return ((current_price - ma) / ma) * 100
        return 0
    
    def _get_stdev_price(self, ticker: str, window: int) -> float:
        """Get standard deviation of price over window"""
        if ticker not in self._indicators:
            return 0.01
        
        key = f'std_{window}'
        if key in self._indicators[ticker] and self._indicators[ticker][key].is_ready:
            return self._indicators[ticker][key].current.value
        return 0.01
    
    def on_data(self, data):
        """Update indicators at 15:45 and rebalance"""
        # Update indicators at 15:45 and immediately rebalance
        if self.time.hour == 15 and self.time.minute == 45:
            current_date = self.time.date()
            
            # Update all indicators
            for ticker, symbol in self._symbols.items():
                if data.bars.contains_key(symbol):
                    bar = data.bars[symbol]
                    
                    # Only update once per day
                    if ticker not in self._last_update or self._last_update[ticker] != current_date:
                        # Update all indicators for this symbol
                        for indicator in self._indicators[ticker].values():
                            indicator.update(bar.end_time, bar.close)
                        
                        self._last_update[ticker] = current_date
            
            # Rebalance immediately after updating indicators
            self._rebalance()
    
    def _rebalance(self):
        """Main rebalancing logic - implements the Symphony DSL strategy structure"""
        if self.is_warming_up:
            return
        
        # Check if indicators are ready
        if not self._indicators_ready():
            self.debug("Indicators not ready, skipping rebalance")
            return
        
        # Clear cache for new day
        if self._cache_date != self.time.date():
            self._cache = {}
            self._cache_date = self.time.date()
        
        # Calculate portfolio allocations using the strategy logic
        allocations = self._calculate_allocations()
        
        # Validate allocations
        allocations = self._validate_allocations(allocations)
        
        if not allocations:
            self.debug("No valid allocations, skipping rebalance")
            return
        
        # Execute the portfolio targets
        targets = [PortfolioTarget(self._symbols[ticker], weight) 
                    for ticker, weight in allocations.items() 
                    if ticker in self._symbols and weight > 0.001]
        
        if targets:
            self.set_holdings(targets, liquidate_existing_holdings=True)
            self._rebalance_count += 1
            self._last_rebalance_time = self.time
            
            # Log summary every 30 days
            if self._rebalance_count % 30 == 0:
                self._log_portfolio_summary(allocations)
    
    def _validate_allocations(self, allocations: dict) -> dict:
        """Validate and normalize allocations"""
        if not allocations:
            return {}
        
        # Remove invalid allocations
        valid_allocations = {ticker: weight for ticker, weight in allocations.items() 
                            if weight > 0 and ticker in self._symbols}
        
        if not valid_allocations:
            return {}
        
        # Check total weight
        total_weight = sum(valid_allocations.values())
        
        if total_weight < 0.01:
            self.debug(f"Total weight too small: {total_weight}")
            return {}
        
        # Normalize to 1.0 if needed
        if abs(total_weight - 1.0) > 0.01:
            self.debug(f"Normalizing allocations from {total_weight} to 1.0")
            valid_allocations = {ticker: weight / total_weight 
                                for ticker, weight in valid_allocations.items()}
        
        # Filter out very small positions
        valid_allocations = {ticker: weight for ticker, weight in valid_allocations.items() 
                            if weight >= 0.001}
        
        return valid_allocations
    
    def _log_portfolio_summary(self, allocations: dict):
        """Log portfolio summary for monitoring"""
        top_positions = sorted(allocations.items(), key=lambda x: x[1], reverse=True)[:10]
        self.debug(f"=== Rebalance #{self._rebalance_count} ===")
        self.debug(f"Portfolio Value: ${self.portfolio.total_portfolio_value:,.2f}")
        self.debug(f"Top 10 Positions:")
        for ticker, weight in top_positions:
            self.debug(f"  {ticker}: {weight*100:.2f}%")
        self.debug(f"Total Positions: {len(allocations)}")
        self.debug(f"Cash: {self.portfolio.cash:,.2f}")
    
    def _indicators_ready(self) -> bool:
        """Check if key indicators are ready"""
        key_tickers = ["SPY", "QQQ", "VIXY"]
        for ticker in key_tickers:
            if ticker in self._indicators:
                if not self._indicators[ticker]['rsi_10'].is_ready:
                    return False
        return True
    
    def _calculate_allocations(self) -> dict:
        """Main allocation logic - full DSL implementation"""
        allocations = defaultdict(float)
        
        # Top-level structure: Two main branches with equal weight
        branch1_weight = 0.5
        branch2_weight = 0.5
        
        # Branch 1: Black Swan Check (BSC) or Complex Equity Strategy
        branch1_alloc = self._branch1_black_swan_or_equities()
        for ticker, weight in branch1_alloc.items():
            allocations[ticker] += weight * branch1_weight
        
        # Branch 2: Steadfast Portfolio, Bonds, Commodities
        branch2_alloc = self._branch2_full_portfolio()
        for ticker, weight in branch2_alloc.items():
            allocations[ticker] += weight * branch2_weight
        
        return dict(allocations)
    
    def _branch1_black_swan_or_equities(self) -> dict:
        """Implements the first major branch: BSC or complex equity strategies"""
        allocations = defaultdict(float)
        
        # Check for black swan conditions
        vixy_rsi_5 = self._get_rsi("VIXY", 5)
        
        if vixy_rsi_5 > 84:
            # Black Swan Catcher: 97% BIL, 3% UVXY
            allocations["BIL"] = 0.97
            allocations["UVXY"] = 0.03
        else:
            # Complex equity strategy split
            # Simplified version: 72% equities, 9% international, 87% main strategy
            us_equities_alloc = self._us_equities_strategy()
            for ticker, weight in us_equities_alloc.items():
                allocations[ticker] += weight * 0.72 * 0.09
            
            intl_alloc = self._international_equities()
            for ticker, weight in intl_alloc.items():
                allocations[ticker] += weight * 0.04
            
            steadfast_alloc = self._steadfast_hedged()
            for ticker, weight in steadfast_alloc.items():
                allocations[ticker] += weight * 0.87
        
        return dict(allocations)
    
    def _us_equities_strategy(self) -> dict:
        """Full US equities strategy with all nested conditions"""
        allocations = defaultdict(float)
        
        spy_rsi_10 = self._get_rsi("SPY", 10)
        spy_rsi_70 = self._get_rsi("SPY", 70)
        vixy_rsi_60 = self._get_rsi("VIXY", 60)
        schx_rsi_10 = self._get_rsi("SCHX", 10)
        mgc_rsi_10 = self._get_rsi("MGC", 10)
        ioo_rsi_10 = self._get_rsi("IOO", 10)
        xlp_rsi_10 = self._get_rsi("XLP", 10)
        vtv_rsi_10 = self._get_rsi("VTV", 10)
        vox_rsi_10 = self._get_rsi("VOX", 10)
        xlf_rsi_10 = self._get_rsi("XLF", 10)
        soxx_rsi_10 = self._get_rsi("SOXX", 10)
        
        # Check SPY overbought (RSI > 79)
        if spy_rsi_10 > 79:
            # Scale-In - 60d
            if vixy_rsi_60 > 40:
                # VIX Blend 75/25
                smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                allocations["VIXY"] = 0.75
                for ticker, weight in smooth_safety.items():
                    allocations[ticker] = weight * 0.25
            else:
                # VIX Blend 50/50
                smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                allocations["VIXY"] = 0.5
                for ticker, weight in smooth_safety.items():
                    allocations[ticker] = weight * 0.5
        else:
            # Check individual sector RSIs
            if schx_rsi_10 > 79:
                if schx_rsi_10 > 80:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.5
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.5
                else:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.1
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.9
            elif mgc_rsi_10 > 79:
                if mgc_rsi_10 > 80:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.5
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.5
                else:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.1
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.9
            elif ioo_rsi_10 > 79:
                if ioo_rsi_10 > 80:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.5
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.5
                else:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.1
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.9
            elif xlp_rsi_10 > 76:
                if xlp_rsi_10 > 77:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.5
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.5
                else:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.1
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.9
            elif vtv_rsi_10 > 78:
                if vtv_rsi_10 > 79:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.5
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.5
                else:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.1
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.9
            elif vox_rsi_10 > 78:
                if vox_rsi_10 > 79:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.5
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.5
                else:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.1
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.9
            elif xlf_rsi_10 > 80:
                if xlf_rsi_10 > 81:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.5
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.5
                else:
                    smooth_safety = self._calculate_inverse_volatility_weights(["EUM", "BTAL"], 10)
                    allocations["VIXY"] = 0.1
                    for ticker, weight in smooth_safety.items():
                        allocations[ticker] = weight * 0.9
            elif soxx_rsi_10 > 83:
                # Short SOXX
                allocations["SOXS"] = 0.34
                allocations["BIL"] = 0.66
            else:
                # Main market strategy
                main_alloc = self._us_equities_main_strategy()
                for ticker, weight in main_alloc.items():
                    allocations[ticker] = weight
        
        return dict(allocations)
    
    def _international_equities(self) -> dict:
        """International equity allocation - full DSL implementation"""
        allocations = defaultdict(float)
        
        # EDC strategy (50%)
        edc_alloc = self._strategy_components.edc_strategy()
        for ticker, weight in edc_alloc.items():
            allocations[ticker] += weight * 0.5
        
        # EEM V2 BWC strategy (50%)
        eem_alloc = self._strategy_components.eem_v2_bwc_strategy()
        for ticker, weight in eem_alloc.items():
            allocations[ticker] += weight * 0.5
        
        return dict(allocations)
    

    
    def _steadfast_portfolio_hedged(self) -> dict:
        """Steadfast portfolio - full structure"""
        allocations = defaultdict(float)
        
        # 2007 FTLT (30.6% * 70%)
        ftlt_alloc = self._ftlt_2007()
        for ticker, weight in ftlt_alloc.items():
            allocations[ticker] += weight * 0.306 * 0.7
        
        # Alt Blocks (30.6% * 30%)
        alt_blocks = self._alt_blocks()
        for ticker, weight in alt_blocks.items():
            allocations[ticker] += weight * 0.306 * 0.3
        
        # Basic Portfolio (33.4%)
        basic_alloc = self._basic_portfolio()
        for ticker, weight in basic_alloc.items():
            allocations[ticker] += weight * 0.334
        
        return dict(allocations)
    
    def _ftlt_2007(self) -> dict:
        """FTLT 2007 strategy - with JRT 2 inverse volatility weighting"""
        allocations = defaultdict(float)
        
        spy_price = self._get_price("SPY")
        spy_sma_200 = self._get_sma("SPY", 200)
        spy_rsi_10 = self._get_rsi("SPY", 10)
        qqq_rsi_10 = self._get_rsi("QQQ", 10)
        
        if spy_price > spy_sma_200:
            if spy_rsi_10 > 80 or qqq_rsi_10 > 80:
                allocations["SHV"] = 0.4
                allocations["PSQ"] = 0.3
                allocations["SH"] = 0.3
            else:
                # Normal bull market - use JRT 2 with inverse volatility weighting (21-day window)
                jrt_stocks = ["COKE", "COST", "LLY", "NVO", "GE", "PGR"]
                jrt_weights = self._calculate_inverse_volatility_weights(jrt_stocks, 21)
                
                for ticker, weight in jrt_weights.items():
                    allocations[ticker] = weight * 0.8
                
                allocations["GLD"] = 0.2
        else:
            # Bear market
            if qqq_rsi_10 < 30:
                allocations["XLK"] = 0.6
                allocations["QLD"] = 0.4
            else:
                allocations["PSQ"] = 0.5
                allocations["SHV"] = 0.5
        
        return dict(allocations)
    
    def _basic_portfolio(self) -> dict:
        """Basic portfolio with equities and bonds - full DSL"""
        allocations = defaultdict(float)
        
        # Equities portion (80%)
        equity_alloc = self._basic_portfolio_equities()
        for ticker, weight in equity_alloc.items():
            allocations[ticker] += weight * 0.8
        
        # Ballast Block (20%)
        ballast_alloc = self._basic_portfolio_ballast()
        for ticker, weight in ballast_alloc.items():
            allocations[ticker] += weight * 0.2
        
        return dict(allocations)
    
    def _basic_portfolio_equities(self) -> dict:
        """Basic Portfolio equities - FTLT logic"""
        allocations = {}
        
        spy_price = self._get_price("SPY")
        spy_sma_200 = self._get_sma("SPY", 200)
        
        if spy_price > spy_sma_200:
            # Bull market - check for overbought conditions
            spy_rsi_10 = self._get_rsi("SPY", 10)
            
            if spy_rsi_10 > 80:
                allocations["VIXY"] = 1.0
            else:
                qqq_rsi_10 = self._get_rsi("QQQ", 10)
                
                if qqq_rsi_10 > 79:
                    allocations["VIXY"] = 1.0
                else:
                    # Check individual sectors
                    xlk_rsi_10 = self._get_rsi("XLK", 10)
                    
                    if xlk_rsi_10 > 79:
                        allocations["VIXY"] = 1.0
                    else:
                        iyw_rsi_10 = self._get_rsi("IYY", 10)  # Using IYY as proxy
                        
                        if iyw_rsi_10 > 79:
                            allocations["VIXY"] = 1.0
                        else:
                            vtv_rsi_10 = self._get_rsi("VTV", 10)
                            
                            if vtv_rsi_10 > 79:
                                allocations["VIXY"] = 1.0
                            else:
                                xlp_rsi_10 = self._get_rsi("XLP", 10)
                                
                                if xlp_rsi_10 > 75:
                                    allocations["VIXY"] = 1.0
                                else:
                                    tqqq_rsi_10 = self._get_rsi("TQQQ", 10)
                                    
                                    if tqqq_rsi_10 > 79:
                                        allocations["VIXY"] = 1.0
                                    else:
                                        xlf_rsi_10 = self._get_rsi("XLF", 10)
                                        
                                        if xlf_rsi_10 > 80:
                                            allocations["VIXY"] = 1.0
                                        else:
                                            vox_rsi_10 = self._get_rsi("VOX", 10)
                                            
                                            if vox_rsi_10 > 79:
                                                allocations["VIXY"] = 1.0
                                            else:
                                                # Normal conditions - main equity allocation
                                                allocations["QQQ"] = 1.0
        else:
            # Bear market - check for oversold
            soxx_rsi_10 = self._get_rsi("SOXX", 10)
            
            if soxx_rsi_10 < 30:
                allocations["SOXX"] = 1.0
            else:
                qqq_rsi_10 = self._get_rsi("QQQ", 10)
                
                if qqq_rsi_10 < 30:
                    allocations["XLK"] = 1.0
                else:
                    # Check QQQ momentum
                    qqq_price = self._get_price("QQQ")
                    qqq_sma_30 = self._get_sma("QQQ", 30)
                    
                    if qqq_price > qqq_sma_30:
                        # Check PSQ RSI
                        psq_rsi_10 = self._get_rsi("PSQ", 10)
                        
                        if psq_rsi_10 > 35:
                            allocations["SPHB"] = 1.0
                        else:
                            allocations["BTAL"] = 1.0
                    else:
                        psq_rsi_10 = self._get_rsi("PSQ", 10)
                        
                        if psq_rsi_10 > 65:
                            allocations["SPHB"] = 1.0
                        else:
                            allocations["BTAL"] = 1.0
        
        return allocations
    
    def _basic_portfolio_ballast(self) -> dict:
        """Basic Portfolio ballast - bonds and commodities"""
        allocations = defaultdict(float)
        
        # Bond Block (70%)
        bond_alloc = self._basic_bond_block()
        for ticker, weight in bond_alloc.items():
            allocations[ticker] += weight * 0.7
        
        # Commodity Block (30%)
        commodity_alloc = self._basic_commodity_block()
        for ticker, weight in commodity_alloc.items():
            allocations[ticker] += weight * 0.3
        
        return dict(allocations)
    
    def _basic_bond_block(self) -> dict:
        """Basic portfolio bond strategies"""
        allocations = {}
        
        # TMF Simplified Momentum (50%)
        tmf_rsi_10 = self._get_rsi("TMF", 10)
        
        if tmf_rsi_10 < 32:
            allocations["TMF"] = 0.5
        else:
            tmf_sma_15 = self._get_sma("TMF", 15)
            tmf_sma_50 = self._get_sma("TMF", 50)
            
            if tmf_sma_15 > tmf_sma_50:
                if tmf_rsi_10 < 75:
                    allocations["TMF"] = 0.25
                    allocations["BIL"] = 0.25
                else:
                    allocations["BIL"] = 0.5
            else:
                allocations["BIL"] = 0.5
        
        # TMV Simplified Momentum (50%)
        tmv_sma_15 = self._get_sma("TMV", 15)
        tmv_sma_50 = self._get_sma("TMV", 50)
        
        if tmv_sma_15 > tmv_sma_50:
            tmv_rsi_10 = self._get_rsi("TMV", 10)
            
            if tmv_rsi_10 < 70:
                tmv_std_10 = self._get_stdev_price("TMV", 10)
                
                if tmv_std_10 < 3:
                    allocations["TMV"] = 0.5
                else:
                    allocations["BIL"] = 0.5
            else:
                allocations["BIL"] = 0.5
        else:
            allocations["BIL"] = 0.5
        
        return allocations
    
    def _basic_commodity_block(self) -> dict:
        """Basic portfolio commodity strategies"""
        allocations = defaultdict(float)
        
        # Commodities (35%)
        dbc_rsi_10 = self._get_rsi("DBC", 10)
        
        if dbc_rsi_10 < 15:
            allocations["DBC"] = 0.175
            allocations["XME"] = 0.175
        else:
            # Short-term momentum
            dbc_ema_8 = self._get_ema("DBC", 8)
            dbc_sma_70 = self._get_sma("DBC", 70)  # Using 70 as proxy for DSL 70
            
            if dbc_ema_8 > dbc_sma_70:
                allocations["DBC"] = 0.175
                allocations["XME"] = 0.175
            else:
                # Long-term momentum check
                dbc_sma_100 = self._get_sma("DBC", 100)
                dbc_sma_252 = self._get_sma("DBC", 252)
                
                if dbc_sma_100 > dbc_sma_252:
                    dbc_sma_50 = self._get_sma("DBC", 50)
                    
                    if dbc_sma_50 > dbc_sma_100:
                        dbc_rsi_60 = self._get_rsi("DBC", 60)
                        
                        if dbc_rsi_60 < 60:
                            allocations["DBC"] = 0.175
                            allocations["XME"] = 0.175
                        else:
                            allocations["BIL"] = 0.35
                    else:
                        allocations["BIL"] = 0.35
                else:
                    allocations["BIL"] = 0.35
        
        # Natural Gas (25%)
        fcg_sma_100 = self._get_sma("FCG", 100)
        fcg_sma_500 = self._get_sma("FCG", 500)
        
        if fcg_sma_100 > fcg_sma_500:
            allocations["BIL"] = 0.25
        else:
            fcg_sma_50 = self._get_sma("FCG", 50)
            fcg_sma_400 = self._get_sma("FCG", 400)
            
            if fcg_sma_50 > fcg_sma_400:
                allocations["FCG"] = 0.25
            else:
                # Check FCG price vs SMA
                fcg_price = self._get_price("FCG")
                fcg_sma_10 = self._get_sma("FCG", 10)
                
                if fcg_price > fcg_sma_10:
                    allocations["FCG"] = 0.25
                else:
                    # KOLD wrapper
                    ung_rsi_10 = self._get_rsi("UNG", 10)
                    
                    if ung_rsi_10 < 25:
                        allocations["BIL"] = 0.25
                    else:
                        allocations["KOLD"] = 0.25
        
        # Gold (20%)
        gld_sma_200 = self._get_sma("GLD", 200)
        gld_sma_350 = self._get_sma("GLD", 350)
        
        if gld_sma_200 > gld_sma_350:
            gld_sma_60 = self._get_sma("GLD", 60)
            gld_sma_150 = self._get_sma("GLD", 150)
            
            if gld_sma_60 > gld_sma_150:
                allocations["GLD"] = 0.2
            else:
                allocations["BIL"] = 0.2
        else:
            allocations["BIL"] = 0.2
        
        # Oil (20%)
        uco_rsi_10 = self._get_rsi("UCO", 10)
        
        if uco_rsi_10 < 15:
            allocations["DBO"] = 0.2
        else:
            dbo_price = self._get_price("DBO")
            dbo_sma_130 = self._get_sma("DBO", 130)
            
            if dbo_price > dbo_sma_130:
                dbo_ema_8 = self._get_ema("DBO", 8)
                dbo_sma_70 = self._get_sma("DBO", 70)  # Using 70 as close to 65
                
                if dbo_ema_8 > dbo_sma_70:
                    allocations["DBO"] = 0.2
                else:
                    allocations["BIL"] = 0.2
            else:
                allocations["BIL"] = 0.2
        
        return dict(allocations)
    
    def _hedgers(self) -> dict:
        """Hedging strategies - full DSL implementation"""
        allocations = defaultdict(float)
        
        # DereckN Hedge System - TMV Momentum (16.67%)
        tmv_alloc = self._tmv_momentum_hedge()
        for ticker, weight in tmv_alloc.items():
            allocations[ticker] += weight * 0.1667
        
        # TMF Momentum (16.67%)
        tmf_alloc = self._tmf_momentum_hedge()
        for ticker, weight in tmf_alloc.items():
            allocations[ticker] += weight * 0.1667
        
        # SVXY FTLT (16.67%)
        svxy_alloc = self._svxy_ftlt_hedge()
        for ticker, weight in svxy_alloc.items():
            allocations[ticker] += weight * 0.1667
        
        # TINA (16.67%)
        tina_alloc = self._tina_strategy()
        for ticker, weight in tina_alloc.items():
            allocations[ticker] += weight * 0.1667
        
        # Shorting SPY (16.67%)
        short_spy_alloc = self._shorting_spy_hedge()
        for ticker, weight in short_spy_alloc.items():
            allocations[ticker] += weight * 0.1667
        
        # SVXY FTLT V2 (16.65%)
        svxy_v2_alloc = self._svxy_ftlt_v2_hedge()
        for ticker, weight in svxy_v2_alloc.items():
            allocations[ticker] += weight * 0.1665
        
        return dict(allocations)
    
    def _tmv_momentum_hedge(self) -> dict:
        """TMV Momentum hedge strategy"""
        allocations = {}
        
        tmf_rsi_10 = self._get_rsi("TMF", 10)
        
        if tmf_rsi_10 < 32:
            allocations["TMF"] = 1.0
        else:
            tmv_sma_15 = self._get_sma("TMV", 15)
            tmv_sma_50 = self._get_sma("TMV", 50)
            
            if tmv_sma_15 > tmv_sma_50:
                tmv_price = self._get_price("TMV")
                tmv_sma_135 = self._get_sma("TMV", 135)
                
                if tmv_price > tmv_sma_135:
                    tmv_rsi_10 = self._get_rsi("TMV", 10)
                    
                    if tmv_rsi_10 > 71:
                        allocations["SHV"] = 1.0
                    else:
                        tmv_rsi_60 = self._get_rsi("TMV", 60)
                        
                        if tmv_rsi_60 > 59:
                            allocations["TLT"] = 1.0
                        else:
                            allocations["TMV"] = 1.0
                else:
                    allocations["BND"] = 1.0
            else:
                allocations["BND"] = 1.0
        
        return allocations
    
    def _tmf_momentum_hedge(self) -> dict:
        """TMF Momentum hedge strategy"""
        allocations = {}
        
        qqq_rsi_10 = self._get_rsi("QQQ", 10)
        
        if qqq_rsi_10 > 80:
            allocations["VIXY"] = 1.0
        else:
            spy_rsi_10 = self._get_rsi("SPY", 10)
            
            if spy_rsi_10 > 80:
                allocations["VIXY"] = 1.0
            else:
                tmf_rsi_10 = self._get_rsi("TMF", 10)
                
                if tmf_rsi_10 < 32:
                    allocations["TMF"] = 1.0
                else:
                    bil_rsi_30 = self._get_rsi("BIL", 30)
                    tlt_rsi_20 = self._get_rsi("TLT", 20)
                    
                    if bil_rsi_30 < tlt_rsi_20:
                        tmf_ema_8 = self._get_ema("TMF", 8)
                        tmf_sma_10 = self._get_sma("TMF", 10)
                        
                        if tmf_ema_8 < tmf_sma_10:
                            tmf_rsi_10 = self._get_rsi("TMF", 10)
                            
                            if tmf_rsi_10 > 72:
                                allocations["SHV"] = 1.0
                            else:
                                allocations["TMF"] = 1.0
                        else:
                            tqqq_rsi_10 = self._get_rsi("TQQQ", 10)
                            
                            if tqqq_rsi_10 < 31:
                                allocations["TECL"] = 1.0
                            else:
                                allocations["SHV"] = 1.0
                    else:
                        tqqq_rsi_10 = self._get_rsi("TQQQ", 10)
                        
                        if tqqq_rsi_10 < 31:
                            allocations["TECL"] = 1.0
                        else:
                            allocations["SHV"] = 1.0
        
        return allocations
    
    def _svxy_ftlt_hedge(self) -> dict:
        """SVXY FTLT hedge strategy"""
        allocations = {}
        
        qqq_rsi_10 = self._get_rsi("QQQ", 10)
        
        if qqq_rsi_10 > 80:
            allocations["VIXY"] = 1.0
        else:
            spy_rsi_10 = self._get_rsi("SPY", 10)
            
            if spy_rsi_10 > 80:
                allocations["VIXY"] = 1.0
            else:
                if qqq_rsi_10 < 30:
                    allocations["XLK"] = 1.0
                else:
                    svxy_price = self._get_price("SVXY")
                    svxy_sma_24 = self._get_sma("SVXY", 24)
                    
                    if svxy_price > svxy_sma_24:
                        # Select top 1 by MA return: SVXY vs VTI
                        svxy_ma_ret = self._get_moving_average_return("SVXY", 20)
                        vti_ma_ret = self._get_moving_average_return("VTI", 20)
                        
                        if svxy_ma_ret > vti_ma_ret:
                            allocations["SVXY"] = 1.0
                        else:
                            allocations["VTI"] = 1.0
                    else:
                        allocations["BTAL"] = 1.0
        
        return allocations
    
    def _tina_strategy(self) -> dict:
        """TINA (There Is No Alternative) strategy"""
        allocations = {}
        
        qqq_price = self._get_price("QQQ")
        qqq_sma_20 = self._get_sma("QQQ", 20)
        
        if qqq_price > qqq_sma_20:
            qqq_cum_ret_10 = self._get_cumulative_return("QQQ", 10)
            
            if qqq_cum_ret_10 > 5.5:
                allocations["PSQ"] = 1.0
            else:
                tqqq_cum_ret_62 = self._get_cumulative_return("TQQQ", 62)
                
                if tqqq_cum_ret_62 < -33:
                    allocations["TQQQ"] = 1.0
                else:
                    allocations["SHV"] = 1.0
        else:
            qqq_rsi_10 = self._get_rsi("QQQ", 10)
            
            if qqq_rsi_10 < 30:
                allocations["TECL"] = 1.0
            else:
                tqqq_cum_ret_62 = self._get_cumulative_return("TQQQ", 62)
                
                if tqqq_cum_ret_62 < -33:
                    allocations["TQQQ"] = 1.0
                else:
                    # Select top 1 by RSI(20): PSQ, BSV, TLT
                    psq_rsi_20 = self._get_rsi("PSQ", 20)
                    bsv_rsi_20 = self._get_rsi("BSV", 20)
                    tlt_rsi_20 = self._get_rsi("TLT", 20)
                    
                    max_rsi = max(psq_rsi_20, bsv_rsi_20, tlt_rsi_20)
                    
                    if max_rsi == psq_rsi_20:
                        allocations["PSQ"] = 1.0
                    elif max_rsi == bsv_rsi_20:
                        allocations["BSV"] = 1.0
                    else:
                        allocations["TLT"] = 1.0
        
        return allocations
    
    def _shorting_spy_hedge(self) -> dict:
        """Shorting SPY hedge with BND vs SH logic"""
        allocations = {}
        
        bnd_rsi_20 = self._get_rsi("BND", 20)
        sh_rsi_60 = self._get_rsi("SH", 60)
        
        if bnd_rsi_20 > sh_rsi_60:
            spy_price = self._get_price("SPY")
            spy_sma_200 = self._get_sma("SPY", 200)
            
            if spy_price > spy_sma_200:
                allocations["SHV"] = 1.0
            else:
                qqq_rsi_10 = self._get_rsi("QQQ", 10)
                
                if qqq_rsi_10 < 30:
                    allocations["XLK"] = 1.0
                else:
                    allocations["SHV"] = 1.0
        else:
            qqq_rsi_10 = self._get_rsi("QQQ", 10)
            
            if qqq_rsi_10 < 30:
                allocations["XLK"] = 1.0
            else:
                spy_ema_10 = self._get_ema("SPY", 10)
                spy_sma_10 = self._get_sma("SPY", 10)
                
                if spy_ema_10 < spy_sma_10:
                    allocations["SH"] = 1.0
                else:
                    allocations["SHV"] = 1.0
        
        return allocations
    
    def _svxy_ftlt_v2_hedge(self) -> dict:
        """SVXY FTLT V2 hedge strategy"""
        allocations = {}
        
        qqq_rsi_10 = self._get_rsi("QQQ", 10)
        
        if qqq_rsi_10 > 80:
            allocations["UVXY"] = 1.0
        else:
            spy_rsi_10 = self._get_rsi("SPY", 10)
            
            if spy_rsi_10 > 80:
                allocations["UVXY"] = 1.0
            else:
                if qqq_rsi_10 < 30:
                    allocations["XLK"] = 1.0
                else:
                    svxy_price = self._get_price("SVXY")
                    svxy_sma_21 = self._get_sma("SVXY", 21)
                    
                    if svxy_price > svxy_sma_21:
                        # Select top 1 by MA return: SVXY vs VTI (70%)
                        svxy_ma_ret = self._get_moving_average_return("SVXY", 20)
                        vti_ma_ret = self._get_moving_average_return("VTI", 20)
                        
                        if svxy_ma_ret > vti_ma_ret:
                            allocations["SVXY"] = 0.7
                        else:
                            allocations["VTI"] = 0.7
                        
                        # VIXM (30%)
                        allocations["VIXM"] = 0.3
                    else:
                        # Select top 1 by MA return: BTAL
                        allocations["BTAL"] = 1.0
        
        return allocations
    
    def _branch2_full_portfolio(self) -> dict:
        """Second major branch - full implementation"""
        allocations = defaultdict(float)
        
        # Steadfast Portfolio Hedged: 87% * 0.72
        steadfast_alloc = self._steadfast_portfolio_hedged()
        for ticker, weight in steadfast_alloc.items():
            allocations[ticker] += weight * 0.87 * 0.72
        
        # 2007 FTLT Hedged: 36% weight
        ftlt_2007_hedged = self._ftlt_2007_hedged()
        for ticker, weight in ftlt_2007_hedged.items():
            allocations[ticker] += weight * 0.36
        
        # Bonds: 23% weight
        bond_alloc = self._treasury_bonds_full()
        for ticker, weight in bond_alloc.items():
            allocations[ticker] += weight * 0.23
        
        # Commodities and Volatility: 5% weight
        commodity_alloc = self._commodities_and_volatility_full()
        for ticker, weight in commodity_alloc.items():
            allocations[ticker] += weight * 0.05
        
        # Infrastructure/Hedge: 0% in DSL but keep structure
        
        return dict(allocations)
    
    def _treasury_bonds_full(self) -> dict:
        """Treasury bonds - full structure"""
        allocations = defaultdict(float)
        
        # TIP/TMV (20%)
        tip_tmv = self._tip_tmv_strategy()
        for ticker, weight in tip_tmv.items():
            allocations[ticker] += weight * 0.2
        
        # TIP (20%)
        tip_alloc = self._tip_strategy()
        for ticker, weight in tip_alloc.items():
            allocations[ticker] += weight * 0.2
        
        # TLT (20%)
        tlt_alloc = self._tlt_strategy()
        for ticker, weight in tlt_alloc.items():
            allocations[ticker] += weight * 0.2
        
        # IEF (10%)
        ief_alloc = self._ief_strategy()
        for ticker, weight in ief_alloc.items():
            allocations[ticker] += weight * 0.1
        
        # IEI (10%)
        iei_alloc = self._iei_strategy()
        for ticker, weight in iei_alloc.items():
            allocations[ticker] += weight * 0.1
        
        # BIL (20%)
        bil_alloc = self._bil_volatility_hedge()
        for ticker, weight in bil_alloc.items():
            allocations[ticker] += weight * 0.2
        
        return dict(allocations)
    
    def _commodities_and_volatility_full(self) -> dict:
        """Commodities and volatility - full implementation"""
        allocations = defaultdict(float)
        
        # US Dollar Strength (weight-equal component)
        usd_alloc = self._usd_strength()
        for ticker, weight in usd_alloc.items():
            allocations[ticker] += weight * 0.2
        
        # Energy Momentum V3
        energy_alloc = self._energy_momentum_v3()
        for ticker, weight in energy_alloc.items():
            allocations[ticker] += weight * 0.2
        
        # Commodities Macro Momentum
        commodity_macro = self._commodities_macro_momentum()
        for ticker, weight in commodity_macro.items():
            allocations[ticker] += weight * 0.2
        
        # Shorting SPY
        short_spy = self._shorting_spy()
        for ticker, weight in short_spy.items():
            allocations[ticker] += weight * 0.1
        
        # Volatility
        vol_alloc = self._volatility_strategies()
        for ticker, weight in vol_alloc.items():
            allocations[ticker] += weight * 0.2
        
        # UVXY 100% Win Rate
        uvxy_alloc = self._uvxy_win_rate_strategy()
        for ticker, weight in uvxy_alloc.items():
            allocations[ticker] += weight * 0.1
        
        return dict(allocations)
    
    def _us_equities_main_strategy(self) -> dict:
        """Main equity strategy - delegates to helper"""
        return self._helper_strategies.us_equities_main_strategy()
    
    def _steadfast_hedged(self) -> dict:
        return self._steadfast_portfolio_hedged()
    
    def _alt_blocks(self) -> dict:
        allocations = {}
        eem_price = self._get_price("EEM")
        eem_sma_200 = self._get_sma("EEM", 200)
        if eem_price > eem_sma_200:
            allocations["EEM"] = 0.5
        else:
            allocations["EUM"] = 0.5
        tlt_rsi_10 = self._get_rsi("TLT", 10)
        tlt_sma_15 = self._get_sma("TLT", 25)
        tlt_sma_50 = self._get_sma("TLT", 50)
        if tlt_rsi_10 < 35:
            allocations["TLT"] = 0.5
        elif tlt_sma_15 > tlt_sma_50:
            allocations["TLT"] = 0.5
        else:
            allocations["SHV"] = 0.5
        return allocations
    
    def _ftlt_2007_hedged(self) -> dict:
        allocations = {}
        ftlt_alloc = self._ftlt_2007()
        for ticker, weight in ftlt_alloc.items():
            allocations[ticker] = weight * 0.12
        hedge_alloc = self._hedgers()
        for ticker, weight in hedge_alloc.items():
            if ticker in allocations:
                allocations[ticker] += weight * 0.88
            else:
                allocations[ticker] = weight * 0.88
        return allocations
    
    def _tip_tmv_strategy(self) -> dict:
        allocations = {}
        tlt_price = self._get_price("TLT")
        tlt_sma_200 = self._get_sma("TLT", 200)
        tmf_rsi_10 = self._get_rsi("TMF", 10)
        if tlt_price > tlt_sma_200:
            if tmf_rsi_10 < 32:
                allocations["TMF"] = 1.0
            else:
                allocations["TIP"] = 0.5
                allocations["BIL"] = 0.5
        else:
            allocations["BIL"] = 1.0
        return allocations
    
    def _tip_strategy(self) -> dict:
        allocations = {}
        iei_sma_50 = self._get_sma("IEI", 50)
        iei_sma_25 = self._get_sma("IEI", 25)
        iei_sma_9 = self._get_sma("IEI", 10)
        if iei_sma_50 > iei_sma_25 > iei_sma_9:
            allocations["BIL"] = 1.0
        else:
            allocations["TIP"] = 1.0
        return allocations
    
    def _tlt_strategy(self) -> dict:
        allocations = {}
        tlt_sma_350 = self._get_sma("TLT", 200)
        tlt_rsi_60 = self._get_rsi("TLT", 60)
        if tlt_sma_350 > 0:
            if tlt_rsi_60 > 62:
                allocations["SHY"] = 1.0
            else:
                allocations["TLT"] = 1.0
        else:
            if tlt_rsi_60 > 53:
                allocations["TLT"] = 1.0
            else:
                allocations["SHV"] = 1.0
        return allocations
    
    def _ief_strategy(self) -> dict:
        allocations = {}
        iei_sma_50 = self._get_sma("IEI", 50)
        iei_sma_25 = self._get_sma("IEI", 25)
        if iei_sma_50 > iei_sma_25:
            allocations["IEF"] = 1.0
        else:
            allocations["BIL"] = 1.0
        return allocations
    
    def _iei_strategy(self) -> dict:
        allocations = {}
        iei_sma_50 = self._get_sma("IEI", 50)
        iei_sma_25 = self._get_sma("IEI", 25)
        if iei_sma_50 > iei_sma_25:
            allocations["IEI"] = 1.0
        else:
            allocations["BIL"] = 1.0
        return allocations
    
    def _bil_volatility_hedge(self) -> dict:
        """BIL volatility hedge - uses comprehensive strategy"""
        return self._strategy_components.bil_full_strategy()
    
    def _usd_strength(self) -> dict:
        allocations = {}
        spy_rsi_60 = self._get_rsi("SPY", 60)
        if spy_rsi_60 > 60:
            allocations["TLT"] = 1.0
        else:
            allocations["SHY"] = 1.0
        return allocations
    
    def _energy_momentum_v3(self) -> dict:
        allocations = {}
        uco_rsi_10 = self._get_rsi("UCO", 10)
        dbo_price = self._get_price("DBO")
        dbo_sma_130 = self._get_sma("DBO", 50)
        if uco_rsi_10 < 14:
            allocations["UCO"] = 0.5
        elif dbo_price > dbo_sma_130:
            allocations["DBO"] = 0.5
        else:
            allocations["SHV"] = 0.5
        fcg_sma_100 = self._get_sma("FCG", 50)
        fcg_sma_500 = self._get_sma("FCG", 200)
        if fcg_sma_100 > fcg_sma_500:
            allocations["FCG"] = 0.5
        else:
            allocations["SHV"] = 0.5
        return allocations
    
    def _commodities_macro_momentum(self) -> dict:
        allocations = {}
        dbc_sma_100 = self._get_sma("DBC", 50)
        dbc_sma_252 = self._get_sma("DBC", 200)
        dbc_sma_50 = self._get_sma("DBC", 50)
        if dbc_sma_100 > dbc_sma_252:
            if dbc_sma_50 > dbc_sma_100:
                allocations["DBC"] = 1.0
            else:
                allocations["SHY"] = 1.0
        else:
            allocations["SHY"] = 1.0
        return allocations
    
    def _shorting_spy(self) -> dict:
        allocations = {}
        spy_price = self._get_price("SPY")
        spy_sma_200 = self._get_sma("SPY", 200)
        qqq_rsi_10 = self._get_rsi("QQQ", 10)
        if spy_price > spy_sma_200:
            allocations["SHV"] = 1.0
        elif qqq_rsi_10 < 30:
            allocations["XLK"] = 1.0
        else:
            allocations["SH"] = 0.5
            allocations["SHV"] = 0.5
        return allocations
    
    def _volatility_strategies(self) -> dict:
        allocations = {}
        tqqq_rsi_10 = self._get_rsi("TQQQ", 10)
        spy_rsi_10 = self._get_rsi("SPY", 10)
        if tqqq_rsi_10 > 79 or spy_rsi_10 > 80:
            allocations["UVXY"] = 1.0
        else:
            allocations["SHY"] = 1.0
        return allocations
    
    def _uvxy_win_rate_strategy(self) -> dict:
        allocations = {}
        tqqq_rsi_10 = self._get_rsi("TQQQ", 10)
        uvxy_rsi_60 = self._get_rsi("UVXY", 60)
        spy_rsi_10 = self._get_rsi("SPY", 10)
        if tqqq_rsi_10 > 81 and uvxy_rsi_60 > 40:
            allocations["UVXY"] = 1.0
        elif spy_rsi_10 > 80 and uvxy_rsi_60 > 40:
            allocations["UVXY"] = 1.0
        else:
            allocations["SHV"] = 1.0
        return allocations
    
    def _get_cumulative_return(self, ticker: str, window: int) -> float:
        """Get cumulative return over window period with caching"""
        if ticker not in self._symbols:
            return 0
        
        # Check cache
        cache_key = f"cum_ret_{ticker}_{window}"
        if self._cache_date == self.time.date() and cache_key in self._cache:
            return self._cache[cache_key]
        
        history = self.history(self._symbols[ticker], window + 1, Resolution.DAILY)
        if history.empty or len(history) < window + 1:
            return 0
        
        start_price = float(history.iloc[0]['close'])
        end_price = float(history.iloc[-1]['close'])
        result = ((end_price - start_price) / start_price) * 100
        
        # Cache result
        self._cache[cache_key] = result
        return result
    
    def _high_volatility_strategy(self) -> dict:
        """High volatility strategy - delegates to helper"""
        return self._helper_strategies.high_volatility_strategy()
    
    def _tech_vs_utilities_strategy(self) -> dict:
        """Tech vs Utilities momentum strategy - delegates to helper"""
        return self._helper_strategies.tech_vs_utilities_strategy()
    
    def _agg_sh_strategy(self, leverage: float) -> dict:
        """AGG vs SH momentum with leverage control - delegates to helper"""
        return self._helper_strategies.agg_sh_strategy(leverage)
# region imports
from AlgorithmImports import *
from collections import defaultdict
import numpy as np
# endregion

class StrategyComponents:
    """Additional strategy components for the DSL implementation"""
    
    def __init__(self, algorithm):
        self.algo = algorithm
        self._strategy_cache = {}
        self._error_counts = defaultdict(int)
        self._max_errors_per_strategy = 3
    
    def _safe_execute(self, strategy_name: str, strategy_func, default_return=None):
        """Safely execute a strategy with error handling"""
        if self._error_counts[strategy_name] >= self._max_errors_per_strategy:
            # Strategy has failed too many times, return default
            return default_return if default_return is not None else {}
        
        try:
            return strategy_func()
        except Exception as e:
            self._error_counts[strategy_name] += 1
            self.algo.debug(f"Error in {strategy_name}: {str(e)}")
            return default_return if default_return is not None else {}
    
    def edc_strategy(self) -> dict:
        """EDC strategy with TQQQ/BlackSwan/Mean Rev logic"""
        return self._safe_execute("edc_strategy", self._edc_strategy_impl, {})
    
    def _edc_strategy_impl(self) -> dict:
        """EDC strategy implementation"""
        allocations = {}
        
        vixm_rsi_14 = self.algo._get_rsi("VIXM", 14)
        
        if vixm_rsi_14 > 70:
            # Huge volatility - TQQQ or not | BlackSwan MeanRev BondSignal
            tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
            
            if tqqq_rsi_10 > 79:
                # Safety assets
                allocations["BIL"] = 0.33
                allocations["VIXY"] = 0.33
                allocations["BTAL"] = 0.34
            else:
                # Check for huge crash
                tqqq_cum_ret_6 = self.algo._get_cumulative_return("TQQQ", 6)
                
                if tqqq_cum_ret_6 < -13:
                    # Mean reversion check
                    tqqq_cum_ret_1 = self.algo._get_cumulative_return("TQQQ", 1)
                    
                    if tqqq_cum_ret_1 > 6:
                        allocations["BIL"] = 0.33
                        allocations["BTAL"] = 0.33
                        allocations["VIXY"] = 0.34
                    else:
                        # Mean Rev logic
                        tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
                        
                        if tqqq_rsi_10 < 32:
                            allocations["TQQQ"] = 1.0
                        else:
                            # Check TMF drawdown
                            tmf_dd_10 = self.algo._get_max_drawdown("TMF", 10)
                            
                            if tmf_dd_10 < 7:
                                allocations["TQQQ"] = 1.0
                            else:
                                allocations["BIL"] = 1.0
                else:
                    # Normal market - check QQQ drawdown
                    qqq_dd_10 = self.algo._get_max_drawdown("QQQ", 10)
                    
                    if qqq_dd_10 > 6:
                        allocations["BIL"] = 1.0
                    else:
                        # Check TMF drawdown
                        tmf_dd_10 = self.algo._get_max_drawdown("TMF", 10)
                        
                        if tmf_dd_10 > 7:
                            allocations["BIL"] = 1.0
                        else:
                            # Check QQQ momentum
                            qqq_price = self.algo._get_price("QQQ")
                            qqq_sma_25 = self.algo._get_sma("QQQ", 25)
                            
                            if qqq_price > qqq_sma_25:
                                allocations["TQQQ"] = 1.0
                            else:
                                # Check bond vs stock strength
                                spy_rsi_60 = self.algo._get_rsi("SPY", 60)
                                
                                if spy_rsi_60 > 50:
                                    bnd_rsi_45 = self.algo._get_rsi("BND", 45)
                                    spy_rsi_45 = self.algo._get_rsi("SPY", 45)
                                    
                                    if bnd_rsi_45 > spy_rsi_45:
                                        allocations["TQQQ"] = 1.0
                                    else:
                                        allocations["BIL"] = 1.0
                                else:
                                    # Check IEF vs TLT
                                    ief_rsi_200 = self.algo._get_rsi("IEF", 200)
                                    tlt_rsi_200 = self.algo._get_rsi("TLT", 200)
                                    
                                    if ief_rsi_200 < tlt_rsi_200:
                                        bnd_rsi_45 = self.algo._get_rsi("BND", 45)
                                        spy_rsi_45 = self.algo._get_rsi("SPY", 45)
                                        
                                        if bnd_rsi_45 > spy_rsi_45:
                                            allocations["TQQQ"] = 1.0
                                        else:
                                            allocations["BIL"] = 1.0
                                    else:
                                        allocations["BIL"] = 1.0
        else:
            # Normal volatility - check EEM trend
            eem_price = self.algo._get_price("EEM")
            eem_sma_200 = self.algo._get_sma("EEM", 200)
            
            if eem_price > eem_sma_200:
                # Check IEI vs IWM for EDC/EDZ
                iei_rsi_11 = self.algo._get_rsi("IEI", 11)
                iwm_rsi_16 = self.algo._get_rsi("IWM", 16)
                
                if iei_rsi_11 > iwm_rsi_16:
                    allocations["EDC"] = 1.0
                else:
                    allocations["EDZ"] = 1.0
            else:
                # Check IEI vs EEM for EDC/EDZ
                iei_rsi_11 = self.algo._get_rsi("IEI", 11)
                eem_rsi_16 = self.algo._get_rsi("EEM", 16)
                
                if iei_rsi_11 > eem_rsi_16:
                    allocations["EDC"] = 1.0
                else:
                    allocations["EDZ"] = 1.0
        
        return allocations
    
    def eem_v2_bwc_strategy(self) -> dict:
        """V2 BWC: Emerging Markets (EEM) strategy"""
        return self._safe_execute("eem_v2_bwc", self._eem_v2_bwc_impl, {})
    
    def _eem_v2_bwc_impl(self) -> dict:
        """EEM V2 BWC implementation"""
        allocations = {}
        
        eem_ma_ret_50 = self.algo._get_moving_average_return("EEM", 50)
        
        if eem_ma_ret_50 < 0:
            # Check EMB vs BWZ (use TLT as BWZ proxy)
            emb_cum_ret_60 = self.algo._get_cumulative_return("EMB", 60)
            tlt_cum_ret_60 = self.algo._get_cumulative_return("TLT", 60)
            
            if emb_cum_ret_60 > tlt_cum_ret_60:
                # Check EMB vs EEM RSI
                emb_rsi_10 = self.algo._get_rsi("EMB", 10)
                eem_rsi_10 = self.algo._get_rsi("EEM", 10)
                
                if emb_rsi_10 < eem_rsi_10:
                    allocations["EDZ"] = 1.0
                else:
                    # Check if EEM oversold
                    if eem_rsi_10 < 25:
                        allocations["EEM"] = 1.0
                    else:
                        allocations["EEMV"] = 1.0
            else:
                # BWZ stronger
                emb_rsi_10 = self.algo._get_rsi("EMB", 10)
                eem_rsi_10 = self.algo._get_rsi("EEM", 10)
                
                if emb_rsi_10 < eem_rsi_10:
                    allocations["EEMV"] = 1.0
                else:
                    # Check if EEM overbought
                    if eem_rsi_10 > 70:
                        allocations["EDZ"] = 1.0
                    else:
                        allocations["EDC"] = 1.0
        else:
            # EEM trending up
            eem_rsi_10 = self.algo._get_rsi("EEM", 10)
            
            if eem_rsi_10 > 75:
                allocations["EDZ"] = 1.0
            else:
                allocations["EEMV"] = 1.0
        
        return allocations
    
    def dereck_nielsen_strategies(self) -> dict:
        """Dereck Nielsen 0 Beta strategies"""
        allocations = defaultdict(float)
        
        # US Dollar Strength (20%)
        usd_alloc = self._usd_strength_strategy()
        for ticker, weight in usd_alloc.items():
            allocations[ticker] += weight * 0.2
        
        # Energy Momentum V3 (20%)
        energy_alloc = self._energy_momentum_v3_full()
        for ticker, weight in energy_alloc.items():
            allocations[ticker] += weight * 0.2
        
        # Commodities Macro Momentum (20%)
        commodity_alloc = self._commodities_macro_full()
        for ticker, weight in commodity_alloc.items():
            allocations[ticker] += weight * 0.2
        
        # Shorting SPY (20%)
        short_alloc = self._shorting_spy_full()
        for ticker, weight in short_alloc.items():
            allocations[ticker] += weight * 0.2
        
        # Bonds (10%)
        bond_alloc = self._bonds_strategy()
        for ticker, weight in bond_alloc.items():
            allocations[ticker] += weight * 0.1
        
        # Volatility (5%)
        vol_alloc = self._volatility_strategy()
        for ticker, weight in vol_alloc.items():
            allocations[ticker] += weight * 0.05
        
        # SVXY FTLT V2 (5%)
        svxy_alloc = self._svxy_ftlt_v2_full()
        for ticker, weight in svxy_alloc.items():
            allocations[ticker] += weight * 0.05
        
        return dict(allocations)
    
    def _usd_strength_strategy(self) -> dict:
        """US Dollar Strength strategy"""
        allocations = {}
        
        uup_sma_21 = self.algo._get_sma("UUP", 21)
        uup_sma_210 = self.algo._get_sma("UUP", 210)
        
        if uup_sma_21 > uup_sma_210:
            spy_rsi_60 = self.algo._get_rsi("SPY", 60)
            
            if spy_rsi_60 > 60:
                allocations["TLT"] = 1.0
            else:
                allocations["UUP"] = 1.0
        else:
            allocations["SHY"] = 1.0
        
        return allocations
    
    def _energy_momentum_v3_full(self) -> dict:
        """Full energy momentum strategies"""
        return self.algo._energy_momentum_v3()
    
    def _commodities_macro_full(self) -> dict:
        """Commodities Macro Momentum strategies"""
        allocations = {}
        
        # Commodities Macro Momentum (50%)
        dbc_sma_100 = self.algo._get_sma("DBC", 100)
        dbc_sma_252 = self.algo._get_sma("DBC", 252)
        
        if dbc_sma_100 > dbc_sma_252:
            dbc_sma_50 = self.algo._get_sma("DBC", 50)
            
            if dbc_sma_50 > dbc_sma_100:
                allocations["DBC"] = 0.5
            else:
                allocations["SHY"] = 0.5
        else:
            allocations["SHY"] = 0.5
        
        # Commodities Macro Momentum V2 (50%)
        if dbc_sma_100 > dbc_sma_252:
            dbc_sma_50 = self.algo._get_sma("DBC", 50)
            
            if dbc_sma_50 > dbc_sma_100:
                allocations["DBC"] = 0.167
                allocations["XME"] = 0.167
                allocations["DBA"] = 0.166
            else:
                allocations["SHV"] = 0.5
        else:
            # Use filter select top 2 by MA return 252
            # Simplified: use GLD and DBC
            allocations["GLD"] = 0.25
            allocations["DBC"] = 0.25
        
        return allocations
    
    def _shorting_spy_full(self) -> dict:
        """Full shorting SPY strategy"""
        return self.algo._shorting_spy()
    
    def _bonds_strategy(self) -> dict:
        """Bonds strategy for Dereck Nielsen"""
        allocations = {}
        
        # TMV Momentum (50%)
        tmv_alloc = self.algo._tmv_momentum_hedge()
        for ticker, weight in tmv_alloc.items():
            allocations[ticker] = weight * 0.5
        
        # TMF Momentum (50%)
        tmf_alloc = self.algo._tmf_momentum_hedge()
        for ticker, weight in tmf_alloc.items():
            if ticker in allocations:
                allocations[ticker] += weight * 0.5
            else:
                allocations[ticker] = weight * 0.5
        
        return allocations
    
    def _volatility_strategy(self) -> dict:
        """Volatility strategy"""
        allocations = {}
        
        tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
        
        if tqqq_rsi_10 > 79:
            allocations["UVXY"] = 1.0
        else:
            spy_rsi_10 = self.algo._get_rsi("SPY", 10)
            
            if spy_rsi_10 > 80:
                allocations["UVXY"] = 1.0
            else:
                allocations["SHY"] = 1.0
        
        return allocations
    
    def _svxy_ftlt_v2_full(self) -> dict:
        """SVXY FTLT V2 full strategy"""
        return self.algo._svxy_ftlt_v2_hedge()
    
    def interstellar_agriculture(self) -> dict:
        """Interstellar Agriculture strategy"""
        allocations = {}
        
        dba_price = self.algo._get_price("DBA")
        dba_sma_450 = self.algo._get_sma("DBA", 450)
        
        if dba_price > dba_sma_450:
            dba_ema_8 = self.algo._get_ema("DBA", 8)
            dba_sma_200 = self.algo._get_sma("DBA", 200)
            
            if dba_ema_8 > dba_sma_200:
                allocations["DBA"] = 1.0
            else:
                allocations["SHV"] = 1.0
        else:
            allocations["SHV"] = 1.0
        
        return allocations
    
    def black_swan_catcher(self) -> dict:
        """Black Swan Catcher strategy"""
        allocations = {}
        
        spy_cum_ret_20 = self.algo._get_cumulative_return("SPY", 20)
        
        if spy_cum_ret_20 < -10:
            if spy_cum_ret_20 < -25:
                tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
                
                if tqqq_rsi_10 < 31:
                    allocations["TECL"] = 1.0
                else:
                    allocations["BIL"] = 1.0
            else:
                tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
                
                if tqqq_rsi_10 < 31:
                    allocations["TECL"] = 1.0
                else:
                    allocations["VIXM"] = 1.0
        else:
            # 100% Win Rate UVXY
            tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
            
            if tqqq_rsi_10 > 81:
                uvxy_rsi_60 = self.algo._get_rsi("UVXY", 60)
                
                if uvxy_rsi_60 > 40:
                    allocations["UVXY"] = 1.0
                else:
                    allocations["SHV"] = 1.0
            else:
                spy_rsi_10 = self.algo._get_rsi("SPY", 10)
                
                if spy_rsi_10 > 80:
                    uvxy_rsi_60 = self.algo._get_rsi("UVXY", 60)
                    
                    if uvxy_rsi_60 > 40:
                        allocations["UVXY"] = 1.0
                    else:
                        allocations["SHV"] = 1.0
                else:
                    allocations["SHV"] = 1.0
        
        return allocations
    
    def infrastructure_hedge(self) -> dict:
        """Infrastructure/Hedge strategies"""
        allocations = defaultdict(float)
        
        # Black Swan Catcher (weight)
        bsc_alloc = self.black_swan_catcher()
        for ticker, weight in bsc_alloc.items():
            allocations[ticker] += weight * 0.0
        
        # Hedge components
        # Commodities Macro Momentum (10%)
        dbc_sma_100 = self.algo._get_sma("DBC", 100)
        dbc_sma_252 = self.algo._get_sma("DBC", 252)
        
        if dbc_sma_100 > dbc_sma_252:
            dbc_sma_50 = self.algo._get_sma("DBC", 50)
            
            if dbc_sma_50 > dbc_sma_100:
                allocations["DBC"] = 0.1
            else:
                allocations["SHV"] = 0.1
        else:
            allocations["SHV"] = 0.1
        
        # GLD Macro Momentum (10%)
        gld_sma_200 = self.algo._get_sma("GLD", 200)
        gld_sma_350 = self.algo._get_sma("GLD", 350)
        
        if gld_sma_200 > gld_sma_350:
            gld_sma_60 = self.algo._get_sma("GLD", 60)
            gld_sma_150 = self.algo._get_sma("GLD", 150)
            
            if gld_sma_60 > gld_sma_150:
                allocations["GLD"] = 0.1
            else:
                allocations["SHV"] = 0.1
        else:
            allocations["SHV"] = 0.1
        
        # IEF Macro Momentum (10%)
        ief_sma_200 = self.algo._get_sma("IEF", 200)
        ief_sma_450 = self.algo._get_sma("IEF", 450)
        
        if ief_sma_200 > ief_sma_450:
            allocations["IEF"] = 0.1
        else:
            allocations["SHV"] = 0.1
        
        # Equities Momentum (40%)
        equities_alloc = self._infrastructure_equities()
        for ticker, weight in equities_alloc.items():
            allocations[ticker] += weight * 0.4
        
        # US Dollar (20%)
        uup_ema_50 = self.algo._get_ema("UUP", 50)
        uup_ema_100 = self.algo._get_ema("UUP", 100)
        
        if uup_ema_50 > uup_ema_100:
            allocations["UUP"] = 0.2
        else:
            allocations["SHV"] = 0.2
        
        # XLP Easy Money (10%)
        xlp_ema_8 = self.algo._get_ema("XLP", 8)
        xlp_sma_50 = self.algo._get_sma("XLP", 50)
        
        if xlp_ema_8 > xlp_sma_50:
            allocations["XLP"] = 0.1
        else:
            allocations["SHV"] = 0.1
        
        return dict(allocations)
    
    def bil_full_strategy(self) -> dict:
        """BIL strategy with comprehensive overbought checks"""
        return self._safe_execute("bil_full", self._bil_full_impl, {"BIL": 0.5, "SCHD": 0.5})
    
    def _bil_full_impl(self) -> dict:
        """BIL full strategy implementation"""
        allocations = {}
        
        qqq_rsi_10 = self.algo._get_rsi("QQQ", 10)
        
        if qqq_rsi_10 > 79:
            allocations["UVXY"] = 1.0
        else:
            vtv_rsi_10 = self.algo._get_rsi("VTV", 10)
            
            if vtv_rsi_10 > 79:
                allocations["BIL"] = 1.0
            else:
                vox_rsi_10 = self.algo._get_rsi("VOX", 10)
                
                if vox_rsi_10 > 79:
                    allocations["BIL"] = 1.0
                else:
                    tecl_rsi_10 = self.algo._get_rsi("TECL", 10)
                    
                    if tecl_rsi_10 > 79:
                        allocations["BIL"] = 1.0
                    else:
                        voog_rsi_10 = self.algo._get_rsi("VOOG", 10)
                        
                        if voog_rsi_10 > 79:
                            allocations["BIL"] = 1.0
                        else:
                            voov_rsi_10 = self.algo._get_rsi("VOOV", 10)
                            
                            if voov_rsi_10 > 79:
                                allocations["BIL"] = 1.0
                            else:
                                xlp_rsi_10 = self.algo._get_rsi("XLP", 10)
                                
                                if xlp_rsi_10 > 75:
                                    allocations["BIL"] = 1.0
                                else:
                                    tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
                                    
                                    if tqqq_rsi_10 > 79:
                                        allocations["BIL"] = 1.0
                                    else:
                                        fas_rsi_10 = self.algo._get_rsi("FAS", 10)
                                        
                                        if fas_rsi_10 > 80:
                                            allocations["BIL"] = 1.0
                                        else:
                                            spy_rsi_10 = self.algo._get_rsi("SPY", 10)
                                            
                                            if spy_rsi_10 > 80:
                                                allocations["UVXY"] = 1.0
                                            else:
                                                uvxy_rsi_21 = self.algo._get_rsi("UVXY", 21)
                                                
                                                if uvxy_rsi_21 > 65:
                                                    spy_rsi_21 = self.algo._get_rsi("SPY", 21)
                                                    
                                                    if spy_rsi_21 > 30:
                                                        allocations["VIXM"] = 1.0
                                                    else:
                                                        allocations["UPRO"] = 1.0
                                                else:
                                                    allocations["SCHD"] = 0.5
                                                    allocations["BIL"] = 0.5
        
        return allocations
    
    def _infrastructure_equities(self) -> dict:
        """Infrastructure equities momentum"""
        allocations = {}
        
        spy_price = self.algo._get_price("SPY")
        spy_sma_200 = self.algo._get_sma("SPY", 200)
        
        if spy_price > spy_sma_200:
            qqq_rsi_10 = self.algo._get_rsi("QQQ", 10)
            
            if qqq_rsi_10 > 80:
                allocations["SHV"] = 1.0
            else:
                spy_rsi_10 = self.algo._get_rsi("SPY", 10)
                
                if spy_rsi_10 > 80:
                    allocations["SHV"] = 1.0
                else:
                    spy_rsi_60 = self.algo._get_rsi("SPY", 60)
                    
                    if spy_rsi_60 > 60:
                        allocations["SHV"] = 1.0
                    else:
                        allocations["QQQ"] = 0.5
                        allocations["SPY"] = 0.5
        else:
            qqq_rsi_10 = self.algo._get_rsi("QQQ", 10)
            
            if qqq_rsi_10 < 30:
                allocations["XLK"] = 1.0
            else:
                allocations["SHV"] = 0.6
                # Bear Market Sideways Protection omitted for brevity
                allocations["PSQ"] = 0.4
        
        return allocations
    
    def xlp_momentum_complete(self) -> dict:
        """XLP Easy Money - complete version"""
        allocations = {}
        
        xlp_ema_8 = self.algo._get_ema("XLP", 8)
        xlp_sma_50 = self.algo._get_sma("XLP", 50)
        
        if xlp_ema_8 > xlp_sma_50:
            allocations["XLP"] = 1.0
        else:
            allocations["SHV"] = 1.0
        
        return allocations
    
    def mean_reversion_qqq(self) -> dict:
        """Mean Reversion for QQQ"""
        allocations = {}
        
        qqq_cum_ret_5 = self.algo._get_cumulative_return("QQQ", 5)
        
        if qqq_cum_ret_5 < -4.75:
            qqq_rsi_10 = self.algo._get_rsi("QQQ", 10)
            
            if qqq_rsi_10 < 30:
                allocations["XLK"] = 1.0
            else:
                allocations["SHV"] = 1.0
        else:
            qqq_rsi_10 = self.algo._get_rsi("QQQ", 10)
            
            if qqq_rsi_10 < 30:
                allocations["QLD"] = 0.5
                allocations["TLT"] = 0.5
            else:
                # Continue with normal logic
                allocations["QQQ"] = 1.0
        
        return allocations
    
    def bear_market_sideways_protection_full(self) -> dict:
        """Bear Market Sideways Protection 2008 Edition - Complete"""
        allocations = {}
        
        qqq_cum_ret_252 = self.algo._get_cumulative_return("QQQ", 252)
        
        if qqq_cum_ret_252 < -20:
            # Nasdaq in crash territory - deleverage
            qqq_price = self.algo._get_price("QQQ")
            qqq_sma_20 = self.algo._get_sma("QQQ", 20)
            
            if qqq_price < qqq_sma_20:
                qqq_cum_ret_60 = self.algo._get_cumulative_return("QQQ", 60)
                
                if qqq_cum_ret_60 <= -12:
                    # Sideways Market Deleverage
                    spy_price = self.algo._get_price("SPY")
                    spy_sma_20 = self.algo._get_sma("SPY", 20)
                    tlt_rsi_10 = self.algo._get_rsi("TLT", 10)
                    psq_rsi_10 = self.algo._get_rsi("PSQ", 10)
                    
                    if spy_price > spy_sma_20:
                        allocations["SPY"] = 0.5
                    else:
                        if tlt_rsi_10 > psq_rsi_10:
                            allocations["QQQ"] = 0.5
                        else:
                            allocations["PSQ"] = 0.5
                    
                    # Second half
                    if tlt_rsi_10 > psq_rsi_10:
                        allocations["QQQ"] = 0.5 if "QQQ" not in allocations else allocations["QQQ"] + 0.5
                    else:
                        allocations["PSQ"] = 0.5 if "PSQ" not in allocations else allocations["PSQ"] + 0.5
                else:
                    tlt_rsi_10 = self.algo._get_rsi("TLT", 10)
                    psq_rsi_10 = self.algo._get_rsi("PSQ", 10)
                    
                    if tlt_rsi_10 > psq_rsi_10:
                        allocations["QLD"] = 1.0
                    else:
                        allocations["QID"] = 1.0
            else:
                psq_rsi_10 = self.algo._get_rsi("PSQ", 10)
                
                if psq_rsi_10 < 31:
                    allocations["PSQ"] = 1.0
                else:
                    qqq_cum_ret_10 = self.algo._get_cumulative_return("QQQ", 10)
                    
                    if qqq_cum_ret_10 > 5.5:
                        allocations["PSQ"] = 1.0
                    else:
                        # Select top 1 by RSI(10): QQQ, SOXX
                        qqq_rsi_10 = self.algo._get_rsi("QQQ", 10)
                        soxx_rsi_10 = self.algo._get_rsi("SOXX", 10)
                        
                        if qqq_rsi_10 > soxx_rsi_10:
                            allocations["QQQ"] = 1.0
                        else:
                            allocations["SOXX"] = 1.0
        else:
            # Not in crash territory
            qqq_price = self.algo._get_price("QQQ")
            qqq_sma_20 = self.algo._get_sma("QQQ", 20)
            
            if qqq_price < qqq_sma_20:
                tlt_rsi_10 = self.algo._get_rsi("TLT", 10)
                psq_rsi_10 = self.algo._get_rsi("PSQ", 10)
                
                if tlt_rsi_10 > psq_rsi_10:
                    allocations["QLD"] = 1.0
                else:
                    allocations["QID"] = 1.0
            else:
                psq_rsi_10 = self.algo._get_rsi("PSQ", 10)
                
                if psq_rsi_10 < 31:
                    allocations["QID"] = 1.0
                else:
                    qqq_cum_ret_10 = self.algo._get_cumulative_return("QQQ", 10)
                    
                    if qqq_cum_ret_10 > 5.5:
                        allocations["QID"] = 1.0
                    else:
                        # Select top 1 by RSI(10): QLD, USD
                        qld_rsi_10 = self.algo._get_rsi("QLD", 10)
                        usd_rsi_10 = self.algo._get_rsi("USD", 10)
                        
                        if qld_rsi_10 > usd_rsi_10:
                            allocations["QLD"] = 1.0
                        else:
                            allocations["USD"] = 1.0
        
        return allocations
    
    def jedi_v12_full(self) -> dict:
        """v1.2 | Jedi - Complete strategy with all branches"""
        allocations = {}
        
        # Bull or Safety determination
        bnd_ma_ret_10 = self.algo._get_moving_average_return("BND", 10)
        pst_ma_ret_10 = self.algo._get_moving_average_return("PST", 10)
        
        if bnd_ma_ret_10 > pst_ma_ret_10:
            # Bullish environment
            allocations["TECL"] = 0.49
            
            # Select bottom 1 by RSI(12): TMF, SVXY
            tmf_rsi_12 = self.algo._get_rsi("TMF", 12)
            svxy_rsi_12 = self.algo._get_rsi("SVXY", 12)
            
            if tmf_rsi_12 < svxy_rsi_12:
                allocations["TMF"] = 0.21
            else:
                allocations["SVXY"] = 0.21
        else:
            # Safety environment
            # Select bottom 1 by RSI(12): BTAL, UGL, SVXY
            btal_rsi_12 = self.algo._get_rsi("BTAL", 12)
            ugl_rsi_12 = self.algo._get_rsi("UGL", 12)
            svxy_rsi_12 = self.algo._get_rsi("SVXY", 12)
            
            min_rsi = min(btal_rsi_12, ugl_rsi_12, svxy_rsi_12)
            
            if min_rsi == btal_rsi_12:
                allocations["BTAL"] = 0.49
            elif min_rsi == ugl_rsi_12:
                allocations["UGL"] = 0.49
            else:
                allocations["SVXY"] = 0.49
            
            # Select bottom 1 by RSI(12): DBC, TMV, VIXM
            dbc_rsi_12 = self.algo._get_rsi("DBC", 12)
            tmv_rsi_12 = self.algo._get_rsi("TMV", 12)
            vixm_rsi_12 = self.algo._get_rsi("VIXM", 12)
            
            min_rsi2 = min(dbc_rsi_12, tmv_rsi_12, vixm_rsi_12)
            
            if min_rsi2 == dbc_rsi_12:
                allocations["DBC"] = 0.21
            elif min_rsi2 == tmv_rsi_12:
                allocations["TMV"] = 0.21
            else:
                allocations["VIXM"] = 0.21
        
        # SCHD always gets 30%
        allocations["SCHD"] = 0.3
        
        return allocations
    
    def dividends_jedi_full(self) -> dict:
        """Dividends Jedi - Complete implementation"""
        allocations = {}
        
        xlk_rsi_126 = self.algo._get_rsi("XLK", 126)
        xlp_rsi_126 = self.algo._get_rsi("XLP", 126)
        
        if xlk_rsi_126 > xlp_rsi_126:
            # Tech stronger
            tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
            
            if tqqq_rsi_10 < 31:
                # Dip buy - select bottom 1 by MA return (5)
                tecl_ma_ret = self.algo._get_moving_average_return("TECL", 5)
                soxl_ma_ret = self.algo._get_moving_average_return("SOXL", 5)
                tmf_ma_ret = self.algo._get_moving_average_return("TMF", 5)
                
                min_ret = min(tecl_ma_ret, soxl_ma_ret, tmf_ma_ret)
                
                if min_ret == tecl_ma_ret:
                    allocations["TECL"] = 1.0
                elif min_ret == soxl_ma_ret:
                    allocations["SOXL"] = 1.0
                else:
                    allocations["TMF"] = 1.0
            else:
                # Check if overbought
                tqqq_cum_ret_1 = self.algo._get_cumulative_return("TQQQ", 1)
                
                if tqqq_cum_ret_1 > 5.5:
                    # Volatility or Short
                    vixy_ma_ret_5 = self.algo._get_moving_average_return("VIXY", 5)
                    
                    if vixy_ma_ret_5 < 0:
                        vixy_rsi_10 = self.algo._get_rsi("VIXY", 10)
                        
                        if vixy_rsi_10 > 50:
                            allocations["VIXM"] = 1.0
                        else:
                            # Select bottom 1 by EMA(5): VIXM, SH
                            vixm_ema_5 = self.algo._get_ema("VIXM", 5)
                            sh_ema_5 = self.algo._get_ema("SH", 5)
                            
                            if vixm_ema_5 < sh_ema_5:
                                allocations["VIXM"] = 1.0
                            else:
                                allocations["SH"] = 1.0
                    else:
                        # Select bottom 1 by EMA(5): UVXY, SH
                        uvxy_ema_5 = self.algo._get_ema("UVXY", 5)
                        sh_ema_5 = self.algo._get_ema("SH", 5)
                        
                        if uvxy_ema_5 < sh_ema_5:
                            allocations["UVXY"] = 1.0
                        else:
                            allocations["SH"] = 1.0
                else:
                    # v1.2 Jedi
                    jedi_alloc = self.jedi_v12_full()
                    for ticker, weight in jedi_alloc.items():
                        allocations[ticker] = weight
        else:
            # Utilities stronger
            tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
            
            if tqqq_rsi_10 < 31:
                # Dip Buy
                vixy_rsi_10 = self.algo._get_rsi("VIXY", 10)
                
                if vixy_rsi_10 > 50:
                    # Select bottom 1 by stdev price (5)
                    svxy_std = self.algo._get_stdev_price("SVXY", 5)
                    soxl_std = self.algo._get_stdev_price("SOXL", 5)
                    tmv_std = self.algo._get_stdev_price("TMV", 5)
                    
                    min_std = min(svxy_std, soxl_std, tmv_std)
                    
                    if min_std == svxy_std:
                        allocations["SVXY"] = 1.0
                    elif min_std == soxl_std:
                        allocations["SOXL"] = 1.0
                    else:
                        allocations["TMV"] = 1.0
                else:
                    allocations["SVXY"] = 1.0
            else:
                # v1.2 Jedi
                jedi_alloc = self.jedi_v12_full()
                for ticker, weight in jedi_alloc.items():
                    allocations[ticker] = weight
        
        return allocations
    
    def dip_buy_dividends_full(self) -> dict:
        """Dip Buy + Dividends - Complete strategy"""
        allocations = {}
        
        tqqq_rsi_10 = self.algo._get_rsi("TQQQ", 10)
        
        if tqqq_rsi_10 < 30:
            allocations["TECL"] = 1.0
        else:
            soxl_rsi_10 = self.algo._get_rsi("SOXL", 10)
            
            if soxl_rsi_10 < 30:
                allocations["SOXL"] = 1.0
            else:
                upro_rsi_10 = self.algo._get_rsi("UPRO", 10)
                
                if upro_rsi_10 < 30:
                    allocations["UPRO"] = 1.0
                else:
                    allocations["SCHD"] = 1.0
        
        return allocations