Tighten signal pipeline: yfinance-only XAU/XAG, leaner Telegram /scan
- XAU/XAG always route to Yahoo Finance and skip Twelve Data entirely (excluded from batch prefetch, served per-symbol via yfinance). - Daily chart cleanly skipped for gold/silver — engine drops it from MTF. - Telegram /scan limited to EURUSD, USDJPY, GBPUSD, XAUUSD. - SCAN_TIMEFRAMES reduced to single H1 primary; engine still pulls M15+H1+D1 internally via confirmation TFs (halves API credits per scan). - Default confirmation TFs swapped H4 -> D1 in config and main.py. - mtf_agreement_threshold kept at 2-of-3. - CLAUDE.md cleaned up — old XAUUSD/synthetic-data bug reports removed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+27
-3
@@ -157,6 +157,24 @@ class ForexDataProvider:
|
||||
if cached is not None and not cached.empty:
|
||||
return cached
|
||||
|
||||
# Symbols not on Twelve Data (gold, silver) always use yfinance.
|
||||
# D1 is intentionally skipped for these — yfinance daily for futures
|
||||
# is unreliable and the engine drops missing confirmation TFs cleanly.
|
||||
if symbol in _YF_FALLBACK_MAP:
|
||||
if timeframe == Timeframe.D1:
|
||||
raise DataUnavailableError(
|
||||
f"Daily chart skipped for {symbol} — gold/silver use M15/H1 only."
|
||||
)
|
||||
yf_df = self._fetch_yfinance_fallback(symbol, timeframe)
|
||||
if yf_df is None:
|
||||
raise DataUnavailableError(
|
||||
f"Yahoo Finance unavailable for {symbol} ({timeframe.value})."
|
||||
)
|
||||
df = self._validate_and_clean(yf_df, symbol, timeframe)
|
||||
self._cache[cache_key] = df
|
||||
self._cache_timestamps[cache_key] = now
|
||||
return df
|
||||
|
||||
df = self._fetch_twelve_data(symbol, timeframe, lookback_days)
|
||||
df = self._validate_and_clean(df, symbol, timeframe)
|
||||
|
||||
@@ -181,6 +199,12 @@ class ForexDataProvider:
|
||||
if lookback_days is None:
|
||||
lookback_days = self.config.data_lookback_days
|
||||
|
||||
# XAU/XAG aren't on Twelve Data — exclude them from the batch call,
|
||||
# they'll be fetched individually via yfinance on demand.
|
||||
td_symbols = [s for s in symbols if s not in _YF_FALLBACK_MAP]
|
||||
if not td_symbols:
|
||||
return
|
||||
|
||||
now = time.time()
|
||||
for tf in timeframes:
|
||||
ttl = self._cache_ttl(tf)
|
||||
@@ -188,13 +212,13 @@ class ForexDataProvider:
|
||||
f"{s}_{tf.value}" in self._cache_timestamps
|
||||
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
|
||||
for s in td_symbols
|
||||
)
|
||||
if cached:
|
||||
logger.debug(f"Skipping prefetch for {tf.value} — all {len(symbols)} symbols cached (TTL {ttl}s)")
|
||||
logger.debug(f"Skipping prefetch for {tf.value} — all {len(td_symbols)} symbols cached (TTL {ttl}s)")
|
||||
continue
|
||||
try:
|
||||
self._batch_fetch_timeframe(symbols, tf, lookback_days)
|
||||
self._batch_fetch_timeframe(td_symbols, tf, lookback_days)
|
||||
time.sleep(1.0) # brief pause between TF requests
|
||||
except Exception as e:
|
||||
logger.warning(f"Batch prefetch failed for {tf.value}: {e}")
|
||||
|
||||
Reference in New Issue
Block a user