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