"""Helpers for shadow-only non-core allocator v2 diagnostics.""" from __future__ import annotations import math def compute_native_rank_pct(rank_index: int, total: int) -> float: if total <= 1: return 1.0 clamped_index = max(0, min(rank_index, total - 1)) return max(0.0, 1.0 - (clamped_index / float(total - 1))) def normalize_hold_days_est(hold_days_est: int | float | None) -> float: hold_days = max(0.0, float(hold_days_est or 0.0)) return min(hold_days, 30.0) / 30.0 def normalize_liquidity_penalty( requested_cash_est: int | float | None, avg_dollar_volume: int | float | None, ) -> float: requested_cash = max(0.0, float(requested_cash_est or 0.0)) adv = max(0.0, float(avg_dollar_volume or 0.0)) denom = max(adv * 0.02, 1.0) return min(requested_cash / denom, 1.0) def classify_parking_class(parking_symbol: str | None) -> str: normalized = str(parking_symbol or "").strip().lower() if normalized == "sgov": return "cash" if normalized == "gld": return "gold" if normalized in {"qqqm", "qqq", "tqqq", "spy"}: return "equity_beta" return "cash" def classify_non_core_overlap_class( family: str, *, trade_symbol_mode: str | None = None, engine_id: str | None = None, symbol: str | None = None, ) -> str: normalized_family = str(family or "").strip().lower() normalized_engine = str(engine_id or "").strip().lower() normalized_symbol = str(symbol or "").strip().lower() normalized_mode = str(trade_symbol_mode or "").strip().lower() if normalized_family == "risk_off_alpha" and normalized_symbol == "gld": return "gold" if normalized_family == "idle_alpha" and ( normalized_engine == "idle_macro_breadth_smh_postalloc" or normalized_mode == "sector_etf" or normalized_symbol == "smh" ): return "equity_beta_high" if normalized_family in {"idle_alpha", "form4", "ownership"}: return "equity_beta_med" if normalized_family == "risk_off_alpha": return "gold" if normalized_symbol == "gld" else "cash" return "cash" def compute_overlap_penalty(candidate_class: str, parking_class: str) -> float: candidate = str(candidate_class or "").strip().lower() parking = str(parking_class or "").strip().lower() if parking == "cash" or candidate == "cash": return 0.0 if candidate == "gold" and parking == "gold": return 1.0 if candidate == "equity_beta_high" and parking == "equity_beta": return 1.0 if candidate == "equity_beta_med" and parking == "equity_beta": return 0.6 return 0.0 def normalize_parking_proxy( parking_symbol: str | None, *, parking_momentum_20: int | float | None, hold_days_est: int | float | None, sgov_annual_rate: int | float | None, ) -> float: normalized_symbol = str(parking_symbol or "").strip().lower() hold_days = max(0.0, float(hold_days_est or 0.0)) if normalized_symbol == "sgov": annual_rate = max(0.0, float(sgov_annual_rate or 0.0)) return min(((annual_rate * hold_days / 252.0) / 0.02), 1.0) momentum = max(0.0, float(parking_momentum_20 or 0.0)) scaled_momentum = momentum * (min(hold_days, 20.0) / 20.0) return min(scaled_momentum / 0.10, 1.0) def compute_marginal_score( *, native_rank_pct: int | float | None, hold_norm: int | float | None, liquidity_penalty_norm: int | float | None, overlap_penalty_norm: int | float | None, parking_proxy_norm: int | float | None, native_strength: int | float = 1.0, hold_penalty: int | float = 0.20, liquidity_penalty: int | float = 0.25, overlap_penalty: int | float = 0.20, parking_opportunity_penalty: int | float = 0.35, ) -> float: values = ( float(native_rank_pct or 0.0), float(hold_norm or 0.0), float(liquidity_penalty_norm or 0.0), float(overlap_penalty_norm or 0.0), float(parking_proxy_norm or 0.0), ) if any(math.isnan(value) or math.isinf(value) for value in values): return 0.0 return ( float(native_strength) * float(native_rank_pct or 0.0) - float(hold_penalty) * float(hold_norm or 0.0) - float(liquidity_penalty) * float(liquidity_penalty_norm or 0.0) - float(overlap_penalty) * float(overlap_penalty_norm or 0.0) - float(parking_opportunity_penalty) * float(parking_proxy_norm or 0.0) )