Align backtest production sim with live runtime config

The portfolio monitor's Production row now replays the live qualification
flag and the Admin exit policy (mode/ATR multiplier/hold days) instead of a
frozen research-variant gate, so Admin tuning is reflected in the next run.
Single-source the 80/20 strategy_rank weights in momentum_service and pin
every dual-defined constant with a parity test. Behavior-preserving today:
the production sim reproduces the README baseline exactly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-09 14:28:50 +02:00
co-authored by Claude Fable 5
parent 65d2dae62a
commit ae1aeb3c84
4 changed files with 169 additions and 10 deletions
+11 -1
View File
@@ -27,6 +27,12 @@ logger = logging.getLogger(__name__)
_MOM_LOOKBACK = 252
_MOM_SKIP = 21
# Promoted production ordering: strategy_rank blends the momentum and realized-
# volatility percentiles. Single source of truth — the backtest's production
# ranking key imports these so live and simulated ordering cannot drift.
STRATEGY_RANK_MOMENTUM_WEIGHT = 0.8
STRATEGY_RANK_VOL_WEIGHT = 1.0 - STRATEGY_RANK_MOMENTUM_WEIGHT
def compute_12_1_momentum(closes: list[float]) -> float | None:
"""Return over the window ending ~1 month ago, starting ~12 months ago.
@@ -199,7 +205,11 @@ async def compute_activation_ranks(db: AsyncSession) -> dict[str, dict[str, floa
momentum_pct = momentum_percentiles.get(sym)
vol_pct = vol_percentiles.get(sym)
strategy_rank = (
round(momentum_pct * 0.8 + vol_pct * 0.2, 2)
round(
momentum_pct * STRATEGY_RANK_MOMENTUM_WEIGHT
+ vol_pct * STRATEGY_RANK_VOL_WEIGHT,
2,
)
if momentum_pct is not None and vol_pct is not None
else momentum_pct
)