Files
momentum-system/strategy/evaluation/regime.py
T
momentum devandClaude Opus 4.8 007cd95c79 Baseline before Postgres migration (WS0)
Snapshot before the DuckDB->PostgreSQL migration. data/, archive/, the 232MB
rebuild zip, the Windows .venv, and .env are excluded via .gitignore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 23:39:29 -04:00

56 lines
1.5 KiB
Python

"""Market regime assessment (hot / normal / cold tape)."""
from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
class MarketRegime(str, Enum):
HOT = "hot"
NORMAL = "normal"
COLD = "cold"
@dataclass
class RegimeAssessment:
regime: MarketRegime
score: float
reason: str
def assess_market_regime(
gappers_count: int = 0,
avg_gap_pct: float = 0.0,
spy_change_pct: float = 0.0,
) -> RegimeAssessment:
"""Assess the tape from breadth of gappers and index behavior."""
score = 0.0
score += min(1.0, gappers_count / 10.0) * 0.5
score += min(1.0, max(0.0, avg_gap_pct / 0.15)) * 0.3
score += min(1.0, max(0.0, (spy_change_pct + 0.01) / 0.02)) * 0.2
if score >= 0.65:
regime = MarketRegime.HOT
reason = f"{gappers_count} gappers, avg gap {avg_gap_pct:.1%}"
elif score >= 0.35:
regime = MarketRegime.NORMAL
reason = "moderate breadth"
else:
regime = MarketRegime.COLD
reason = "few gappers / weak tape"
return RegimeAssessment(regime=regime, score=round(score, 3), reason=reason)
def get_regime_adjustment(regime: MarketRegime) -> float:
"""Position-size multiplier for the regime."""
return {MarketRegime.HOT: 1.0, MarketRegime.NORMAL: 0.75, MarketRegime.COLD: 0.5}[
regime
]
def should_trade_in_regime(regime: MarketRegime, allow_cold: bool = False) -> bool:
if regime == MarketRegime.COLD:
return allow_cold
return True