ifieryarrows commited on
Commit
a242cd4
·
verified ·
1 Parent(s): ec96278

Sync from GitHub (tests passed)

Browse files
screener/feature_screener/orchestrator.py CHANGED
@@ -467,7 +467,7 @@ class FeatureScreener:
467
  return {"selected": [], "limits_applied": {}}
468
 
469
  # Selection rules version (increment when limits/logic changes)
470
- SELECTION_RULES_VERSION = "3.0.0" # v3: whitelist + global cap
471
 
472
  # Global cap - hard limit on total selected
473
  MAX_SELECTED_TOTAL = 20
@@ -476,7 +476,8 @@ class FeatureScreener:
476
  oos_quality_gates = {
477
  "min_oos_n_obs": 52, # ~1 year of weekly data
478
  "min_oos_abs_pearson": 0.30, # abs() to include negative correlations
479
- "max_oos_rolling_std": 0.25 # stability requirement
 
480
  }
481
 
482
  # Category limits - WHITELIST approach (default=0)
@@ -512,6 +513,7 @@ class FeatureScreener:
512
  "oos_n_obs_too_low": 0,
513
  "oos_abs_pearson_too_low": 0,
514
  "oos_rolling_std_too_high": 0,
 
515
  "oos_metrics_missing": 0,
516
  "category_not_whitelisted": 0,
517
  "category_limit_reached": 0,
@@ -541,6 +543,13 @@ class FeatureScreener:
541
  excluded_reasons["oos_rolling_std_too_high"] += 1
542
  continue
543
 
 
 
 
 
 
 
 
544
  quality_passed.append(candidate)
545
 
546
  # Step 2: Apply category limits (whitelist) + global cap
 
467
  return {"selected": [], "limits_applied": {}}
468
 
469
  # Selection rules version (increment when limits/logic changes)
470
+ SELECTION_RULES_VERSION = "3.1.0" # v3.1: + target redundancy filter
471
 
472
  # Global cap - hard limit on total selected
473
  MAX_SELECTED_TOTAL = 20
 
476
  oos_quality_gates = {
477
  "min_oos_n_obs": 52, # ~1 year of weekly data
478
  "min_oos_abs_pearson": 0.30, # abs() to include negative correlations
479
+ "max_oos_rolling_std": 0.25, # stability requirement
480
+ "max_target_corr": 0.95 # exclude target copies (only at lag=0)
481
  }
482
 
483
  # Category limits - WHITELIST approach (default=0)
 
513
  "oos_n_obs_too_low": 0,
514
  "oos_abs_pearson_too_low": 0,
515
  "oos_rolling_std_too_high": 0,
516
+ "oos_target_redundant": 0, # high corr + lag=0 = target copy
517
  "oos_metrics_missing": 0,
518
  "category_not_whitelisted": 0,
519
  "category_limit_reached": 0,
 
543
  excluded_reasons["oos_rolling_std_too_high"] += 1
544
  continue
545
 
546
+ # Gate 4: Target redundancy filter (only for contemporaneous, lag=0)
547
+ # High correlation AT LAG=0 means "target copy", not "leading signal"
548
+ frozen_lag = oos.frozen_lag if oos.frozen_lag is not None else candidate.is_metrics.best_lead_lag
549
+ if frozen_lag == 0 and abs(oos.pearson) > oos_quality_gates["max_target_corr"]:
550
+ excluded_reasons["oos_target_redundant"] += 1
551
+ continue
552
+
553
  quality_passed.append(candidate)
554
 
555
  # Step 2: Apply category limits (whitelist) + global cap