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_backoff_until: float = 0.0
|
||||||
|
_CALENDAR_CACHE_TTL: float = 3600.0
|
||||||
|
|
||||||
def __init__(self, config: NewsConfig):
|
def __init__(self, config: NewsConfig):
|
||||||
self.config = config
|
self.config = config
|
||||||
@@ -134,6 +135,8 @@ class NewsEngine:
|
|||||||
self._session.headers.update({
|
self._session.headers.update({
|
||||||
"User-Agent": "Mozilla/5.0 (compatible; ForexIntel/1.0)"
|
"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(
|
def get_fundamental_context(
|
||||||
self, currencies: Optional[List[str]] = None
|
self, currencies: Optional[List[str]] = None
|
||||||
@@ -278,11 +281,20 @@ class NewsEngine:
|
|||||||
Tries Forex Factory first, falls back to MyFXBook RSS.
|
Tries Forex Factory first, falls back to MyFXBook RSS.
|
||||||
Returns an empty list (with a log warning) if unavailable —
|
Returns an empty list (with a log warning) if unavailable —
|
||||||
we never generate fake events since that causes constant false alarms.
|
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):
|
for fetcher in (self._try_fetch_calendar_api, self._try_fetch_myfxbook_rss):
|
||||||
try:
|
try:
|
||||||
events = fetcher()
|
events = fetcher()
|
||||||
if events:
|
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]
|
return [e for e in events if e.currency in currencies]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug(f"Calendar fetch exception ({fetcher.__name__}): {e}")
|
logger.debug(f"Calendar fetch exception ({fetcher.__name__}): {e}")
|
||||||
|
|||||||
+1
-1
@@ -1475,7 +1475,7 @@ def _():
|
|||||||
|
|
||||||
@test("SCAN_BUTTONS and SCAN_LOOKUP consistency")
|
@test("SCAN_BUTTONS and SCAN_LOOKUP consistency")
|
||||||
def _():
|
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:
|
for btn in SCAN_BUTTONS:
|
||||||
assert btn["cb"] in SCAN_LOOKUP
|
assert btn["cb"] in SCAN_LOOKUP
|
||||||
assert "symbol" in btn
|
assert "symbol" in btn
|
||||||
|
|||||||
Reference in New Issue
Block a user