Accuracy audit fixes: alerts carry validated per-TF trail plans + 13 more
Five-agent audit of the signal path; all fixes are delivery/measurement side. Regression-proven behavior-neutral on validated signals: the 5yr M15 replay reproduces the pinned book exactly (+210.65R PF 1.35 WR 57.8% MaxDD 33.90R). Tests 215 -> 221. - TradeSetup carries trail_arm_r/trail_dist_r stamped from the producing config; Telegram trail plan reads them (was showing default 0.6/0.75 instead of the validated M15 arm 0.70 / M5 dist 0.85) - Alert dedup: fingerprint = (signal, quality, direction); entry movement compared against last-ALERTED entry/risk (old SL-dist bucket churned on ATR drift -> near-duplicate alerts every candle) - Fresh fetches enforce the closed-bar boundary check with one 3s grace retry, then warn (feed lag no longer silently analyzes the prior bar) - Backtest max DD includes the zero baseline (opening losing streaks were undercounted; pinned M15 DD unchanged) - Replay loads the regime-filter TF when the H4-ADX gate is on (was a silent no-op for M5/M15 primaries) - clear_cache under _cache_lock; dead ROC zero-cross branches removed from both engines (provably unreachable); RSS dates via parsedate_to_datetime (named zones no longer stamped UTC); event risk grades from the soonest event; .env inline comments stripped; auto-scan skips NEUTRAL like the breach path; report_to_dict honors the weight-0 skip rule and emits strategy/trail params; PB funnel counts spread_gate/accepted; session-filter fail-open paths log loudly - Docs corrected to match validated code (H&S neckline = lower peak, exhaustion anchors farthest tracked swing) with re-validation warnings Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R5soRUeRBi8kHMB99csrJy
This commit is contained in:
+26
-10
@@ -15,6 +15,7 @@ import time
|
||||
import xml.etree.ElementTree as ET
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime, timezone
|
||||
from email.utils import parsedate_to_datetime
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
import requests
|
||||
@@ -281,14 +282,20 @@ class NewsEngine:
|
||||
"""
|
||||
base, quote = self._parse_pair(pair_symbol)
|
||||
|
||||
# Check upcoming high-impact events
|
||||
# Check upcoming high-impact events. Grade from the SOONEST
|
||||
# matching event, not the first listed — an unsorted feed could
|
||||
# otherwise report "caution" for a far event while a nearer one
|
||||
# warrants "danger".
|
||||
soonest = None
|
||||
for event in context.events_upcoming_1h:
|
||||
if event.is_high_impact and event.currency in (base, quote):
|
||||
mins = event.minutes_until
|
||||
if mins <= self.config.pre_event_buffer_minutes:
|
||||
return "danger", f"{event.currency} {event.event} in {mins:.0f}min"
|
||||
else:
|
||||
return "caution", f"{event.currency} {event.event} in {mins:.0f}min"
|
||||
if soonest is None or event.minutes_until < soonest.minutes_until:
|
||||
soonest = event
|
||||
if soonest is not None:
|
||||
mins = soonest.minutes_until
|
||||
if mins <= self.config.pre_event_buffer_minutes:
|
||||
return "danger", f"{soonest.currency} {soonest.event} in {mins:.0f}min"
|
||||
return "caution", f"{soonest.currency} {soonest.event} in {mins:.0f}min"
|
||||
|
||||
# Check for recent high-impact releases. A surprise print (actual
|
||||
# away from forecast) keeps the market unstable longer than an
|
||||
@@ -650,11 +657,20 @@ class NewsEngine:
|
||||
if not date_str:
|
||||
return None
|
||||
|
||||
# RFC 822/2822 forms, with or without seconds, numeric offsets AND
|
||||
# named zones (GMT, EST/EDT, PST…). The old strptime "%Z" path
|
||||
# accepted ANY abbreviation but attached no offset, so e.g. an EST
|
||||
# pubDate was silently stamped UTC — a 5-hour error.
|
||||
try:
|
||||
dt = parsedate_to_datetime(date_str.strip())
|
||||
if dt is not None:
|
||||
if dt.tzinfo is None: # unknown zone name — assume UTC
|
||||
return dt.replace(tzinfo=timezone.utc)
|
||||
return dt.astimezone(timezone.utc)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
formats = [
|
||||
"%a, %d %b %Y %H:%M:%S %z", # RFC 822 with numeric tz offset
|
||||
"%a, %d %b %Y %H:%M:%S %Z", # RFC 822 with tz abbreviation (GMT/UTC)
|
||||
"%a, %d %b %Y %H:%M %Z", # RFC 822 without seconds (MyFXBook)
|
||||
"%a, %d %b %Y %H:%M %z", # RFC 822 without seconds, numeric offset
|
||||
"%Y-%m-%dT%H:%M:%S%z", # ISO 8601 with offset
|
||||
"%Y-%m-%d %H:%M:%S", # ISO 8601 naive (assume UTC)
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user