From 5ad5640ad1736564fbd7fbf8e0ac9e57d9d979fd Mon Sep 17 00:00:00 2001 From: harwinder Date: Thu, 21 May 2026 19:36:15 -0400 Subject: [PATCH] Cache economic calendar for 1 hour, fix SCAN_BUTTONS test for EUR-only The weekly calendar JSON was re-fetched on every scan cycle (~288 calls/day). Now cached per-instance with 1-hour TTL, cutting to ~24. Currency filtering still applied on each read so cached events stay correct across pairs. Co-Authored-By: Claude Opus 4.6 --- news_engine.py | 12 ++++++++++++ test_all.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/news_engine.py b/news_engine.py index f8622c0..80eb6a7 100755 --- a/news_engine.py +++ b/news_engine.py @@ -127,6 +127,7 @@ class NewsEngine: } _calendar_backoff_until: float = 0.0 + _CALENDAR_CACHE_TTL: float = 3600.0 def __init__(self, config: NewsConfig): self.config = config @@ -134,6 +135,8 @@ class NewsEngine: self._session.headers.update({ "User-Agent": "Mozilla/5.0 (compatible; ForexIntel/1.0)" }) + self._calendar_cache: List[EconomicEvent] = [] + self._calendar_cache_time: float = 0.0 def get_fundamental_context( self, currencies: Optional[List[str]] = None @@ -278,11 +281,20 @@ class NewsEngine: Tries Forex Factory first, falls back to MyFXBook RSS. Returns an empty list (with a log warning) if unavailable — we never generate fake events since that causes constant false alarms. + + Results are cached for 1 hour since the weekly calendar rarely changes. """ + now = time.time() + if self._calendar_cache and (now - self._calendar_cache_time) < self._CALENDAR_CACHE_TTL: + return [e for e in self._calendar_cache if e.currency in currencies] + for fetcher in (self._try_fetch_calendar_api, self._try_fetch_myfxbook_rss): try: events = fetcher() if events: + self._calendar_cache = events + self._calendar_cache_time = now + logger.debug(f"Calendar cached: {len(events)} events (TTL {self._CALENDAR_CACHE_TTL:.0f}s)") return [e for e in events if e.currency in currencies] except Exception as e: logger.debug(f"Calendar fetch exception ({fetcher.__name__}): {e}") diff --git a/test_all.py b/test_all.py index 28f62c3..13e7184 100644 --- a/test_all.py +++ b/test_all.py @@ -1475,7 +1475,7 @@ def _(): @test("SCAN_BUTTONS and SCAN_LOOKUP consistency") def _(): - assert len(SCAN_BUTTONS) == 10 # 5 per pair (4 TFs + All) × 2 pairs + assert len(SCAN_BUTTONS) == 5 # 4 TFs + All for EUR/USD for btn in SCAN_BUTTONS: assert btn["cb"] in SCAN_LOOKUP assert "symbol" in btn