GREEN sprint: S6 asset picker + EsoF regime gate + AEM shadow-complete [S6 sizing suspended — overfitting] #1

Open
hjnormey wants to merge 6 commits from exp/green-s6-esof-aem-shadow-2026-04-21 into master
Showing only changes of commit ce7f3ce8ff - Show all commits

View File

@@ -10,7 +10,7 @@ import math
import numpy as np import numpy as np
from numba import njit from numba import njit
from dataclasses import dataclass from dataclasses import dataclass
from typing import Dict, List, Optional, Tuple from typing import Dict, List, Optional, Set, Tuple
# ── Constants (matching dolphin_vbt_real.py lines 104-115) ──────────────────── # ── Constants (matching dolphin_vbt_real.py lines 104-115) ────────────────────
@@ -195,9 +195,13 @@ class AlphaAssetSelector:
self, self,
lookback_horizon: int = IRP_LOOKBACK, lookback_horizon: int = IRP_LOOKBACK,
ars_weights: Optional[List[float]] = None, ars_weights: Optional[List[float]] = None,
asset_bucket_ban_set: Optional[Set[int]] = None,
asset_bucket_assignments: Optional[Dict[str, int]] = None,
): ):
self.H = lookback_horizon self.H = lookback_horizon
self.weights = ars_weights or ARS_WEIGHTS self.weights = ars_weights or ARS_WEIGHTS
self.asset_bucket_ban_set = asset_bucket_ban_set
self.asset_bucket_assignments = asset_bucket_assignments or {}
def rank_assets( def rank_assets(
self, self,
@@ -236,6 +240,15 @@ class AlphaAssetSelector:
best_eff = valid[ri, 4] best_eff = valid[ri, 4]
asset = asset_names[asset_idx] asset = asset_names[asset_idx]
# GREEN-only bucket-ban filter. BLUE passes None → no-op.
# Skips banned-bucket assets so the next-ranked asset takes the slot
# (preserves capital; a sizer 0× would waste the slot).
if self.asset_bucket_ban_set:
bkt = self.asset_bucket_assignments.get(asset)
if bkt is not None and bkt in self.asset_bucket_ban_set:
continue
action = "SHORT" if trade_dir == -1 else "LONG" action = "SHORT" if trade_dir == -1 else "LONG"
orientation = "DIRECT" if trade_dir == regime_direction else "INVERSE" orientation = "DIRECT" if trade_dir == regime_direction else "INVERSE"