Add session filter + auto-toggle, extend trade journal diagnostics
Session filter restricts trades to a UTC hour window (default 07-16, London + NY) — opt-in via --session-filter, with --session-start / --session-end overrides. Wired into both the backtester (cheap hour check next to the regime gate) and live mode (downgrades signal to NEUTRAL/F when current UTC hour is outside the window). Auto-toggle (--auto-session-filter) tracks rolling mean pnl_pct over the last N closed trades; when it falls below threshold, the session filter activates, releasing once expectancy recovers. Default lookback 10 trades, threshold -0.3%. Trade dataclass extended with diagnostic fields captured at entry: entry_hour, entry_dow, ADX, ATR%, market_regime, volatility_regime, mtf_agreement. These let --journal-csv exports surface loss-pattern clusters when a window underperforms. Validated on 2024 trend / 2023 chop / 2026 recent windows. Auto-toggle preserves ~50% of trend edge while still cutting ~25% of recent-regime losses — pure regime filter is still best on cumulative, so both session flags ship default-off. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -130,8 +130,33 @@ class SignalAggregator:
|
||||
if bt.regime_filter:
|
||||
self._apply_regime_filter_live(report, dfs)
|
||||
|
||||
if bt.session_filter:
|
||||
self._apply_session_filter_live(report)
|
||||
|
||||
return report
|
||||
|
||||
def _apply_session_filter_live(self, report: SignalReport) -> None:
|
||||
"""Skip signals outside the configured UTC trading window."""
|
||||
bt = self.config.backtest
|
||||
now_h = datetime.now(timezone.utc).hour
|
||||
if not (bt.session_start_hour <= now_h < bt.session_end_hour):
|
||||
report.warnings.append(
|
||||
f"SESSION FILTER: {now_h:02}:00 UTC outside "
|
||||
f"{bt.session_start_hour:02}:00-{bt.session_end_hour:02}:00 — skipping"
|
||||
)
|
||||
report.final_signal = SignalStrength.NEUTRAL
|
||||
report.signal_quality = "F"
|
||||
report.action_recommendation = (
|
||||
f"NO TRADE — Outside session "
|
||||
f"({bt.session_start_hour:02}-{bt.session_end_hour:02} UTC; now {now_h:02})"
|
||||
)
|
||||
report.trade_setup = None
|
||||
else:
|
||||
report.warnings.append(
|
||||
f"Session: {now_h:02}:00 UTC inside trading window "
|
||||
f"{bt.session_start_hour:02}-{bt.session_end_hour:02}"
|
||||
)
|
||||
|
||||
def _apply_regime_filter_live(
|
||||
self, report: SignalReport, dfs: Dict[Timeframe, pd.DataFrame]
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user