diff --git a/config.py b/config.py index f638681..955ad2e 100644 --- a/config.py +++ b/config.py @@ -196,9 +196,25 @@ class PlatformConfig: # Twelve Data API key (overridden by TWELVE_DATA_API_KEY env var) twelve_data_api_key: str = "f563b22ffdfd4924955decbe1a8c8701" - # Dashboard refresh interval (seconds) + # Dashboard refresh interval (seconds) — used as a fallback when a + # timeframe isn't covered by cache_ttl_per_tf below. refresh_interval: int = 300 # 5 minutes + # Per-timeframe cache TTL (seconds). A 1-week candle changes less + # often than a 15-minute candle, so caching them all for the same + # 5 minutes wastes API credits. Tuned to roughly match each TF's + # bar interval so we re-fetch about once per new bar. + cache_ttl_per_tf: Dict[Timeframe, int] = field(default_factory=lambda: { + Timeframe.M1: 60, # 1 minute + Timeframe.M5: 150, # 2.5 minutes + Timeframe.M15: 300, # 5 minutes + Timeframe.M30: 600, # 10 minutes + Timeframe.H1: 1800, # 30 minutes + Timeframe.H4: 7200, # 2 hours + Timeframe.D1: 14400, # 4 hours + Timeframe.W1: 86400, # 24 hours + }) + # Logging log_level: str = "INFO" log_signals_to_file: bool = True diff --git a/data_provider.py b/data_provider.py index da28e95..aa24073 100644 --- a/data_provider.py +++ b/data_provider.py @@ -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)