Per-timeframe cache TTLs — D1 cached 4h, H1 30m, M15 5m

A single 5-minute refresh_interval applied to every timeframe wasted
API credits: a daily candle was being refetched every 5 minutes even
though it only changes once per day. Now each TF caches for roughly
its bar interval, so repeat scans within an hour skip D1 entirely
(saves ~60s of throttle wait) and within 30 min also skip H1.

config.py: new cache_ttl_per_tf dict on PlatformConfig with sensible
defaults for every timeframe; refresh_interval kept as fallback.

data_provider.py: _cache_ttl() helper used by both fetch_ohlcv and
prefetch_batch instead of the global refresh_interval.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Harwinder
2026-05-05 14:55:05 -04:00
parent 8a1e57f682
commit 4c1d839a1a
2 changed files with 26 additions and 4 deletions
+9 -3
View File
@@ -125,6 +125,10 @@ class ForexDataProvider:
clean = symbol.replace("=X", "")
return f"{clean[:3]}/{clean[3:]}"
def _cache_ttl(self, timeframe: Timeframe) -> int:
"""Cache TTL for a given timeframe — falls back to refresh_interval."""
return self.config.cache_ttl_per_tf.get(timeframe, self.config.refresh_interval)
def fetch_ohlcv(
self,
symbol: str,
@@ -142,10 +146,11 @@ class ForexDataProvider:
cache_key = f"{symbol}_{timeframe.value}"
now = time.time()
ttl = self._cache_ttl(timeframe)
if (
cache_key in self._cache_timestamps
and (now - self._cache_timestamps[cache_key]) < self.config.refresh_interval
and (now - self._cache_timestamps[cache_key]) < ttl
and cache_key in self._cache
):
cached = self._cache.get(cache_key)
@@ -178,14 +183,15 @@ class ForexDataProvider:
now = time.time()
for tf in timeframes:
ttl = self._cache_ttl(tf)
cached = all(
f"{s}_{tf.value}" in self._cache_timestamps
and (now - self._cache_timestamps[f"{s}_{tf.value}"]) < self.config.refresh_interval
and (now - self._cache_timestamps[f"{s}_{tf.value}"]) < ttl
and not self._cache.get(f"{s}_{tf.value}", pd.DataFrame()).empty
for s in symbols
)
if cached:
logger.debug(f"Skipping prefetch for {tf.value} — all {len(symbols)} symbols cached")
logger.debug(f"Skipping prefetch for {tf.value} — all {len(symbols)} symbols cached (TTL {ttl}s)")
continue
try:
self._batch_fetch_timeframe(symbols, tf, lookback_days)