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 <noreply@anthropic.com>
This commit is contained in:
@@ -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}")
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user