- data_provider: new fetch_historical() that paginates /time_series in
5000-bar chunks (1 credit/chunk) for arbitrary date ranges. Tolerates
the API's "no data on specified dates" boundary error gracefully when
prior chunks succeeded — that error is just the marker that we walked
past the symbol's earliest available bar.
- seed_history.py: one-shot CLI that downloads OHLCV for the configured
pairs/TFs into history/<PAIR>_<TF>.csv. Skips existing files unless
--force.
- backtest.py: walk-forward replay through SignalAggregator with strict
no-look-ahead semantics. Each bar is only visible to the engine after
it has fully closed (`df.index + interval <= as_of`). Trade simulation
is first-touch (SL vs TP1) with worst-case (SL first if both touched
same bar), spread cost deducted from R, max-hold timeout, no-overlap.
Reports per-grade win-rate / avg-R / profit-factor / max-DD, plus
optional matplotlib equity + by-grade plots.
- requirements: add matplotlib (lazy-imported, only needed for --plot).
- .gitignore: history/ and backtest_results/ regenerable, kept untracked.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- data_provider: strip yfinance imports, _YF_FALLBACK_MAP, _YF_INTERVALS,
_YF_SESSION, _fetch_yfinance_fallback, _resample_h1_to_h4. Twelve Data
is the sole data source. Raises DataUnavailableError if a pair isn't
on the configured plan.
- config: remove XAU/USD and XAG/USD from SYMBOL_DISPLAY and PIP_VALUES.
PIP_VALUES is now empty (defaults: 0.01 JPY pairs, 0.0001 forex).
- signal_aggregator: clear _PER_SYMBOL_TFS overrides (was XAU/XAG-only).
- telegram_bot: replace XAUUSD with AUDUSD in SCAN_PAIRS. Auto-load .env
via python-dotenv so TELEGRAM_BOT_TOKEN/GEMINI_API_KEY are picked up.
- requirements: drop yfinance and curl_cffi dependencies.
End-to-end pipeline test passes: data freshness, news engine (Gemini live),
signal aggregator, and the /signal+/scan code paths in telegram_bot.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Migrate news_engine to google-genai SDK with gemini-2.5-flash-lite
- Batch all headlines into one API call per scan (30 calls -> 1)
- In-memory cache keyed by headline hash; fallback to keyword scoring
- Update requirements.txt: add google-genai, python-dotenv; remove transformers
- Add .gitignore; update CLAUDE.md with Gemini live section
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- yfinance>=0.2.40 added as a hard dependency
- _fetch_yfinance_fallback(): pulls OHLCV from Yahoo for symbols not on
the Twelve Data free tier (XAUUSD → GC=F, XAGUSD → SI=F)
- Hooked into both batch and single-symbol fetch paths; logs as [yf]
to distinguish from Twelve Data [live]
- Fail-loud: if both providers return nothing, the pair is skipped with
the existing "data unavailable" message
- _analyze_all_tfs accepts an async progress callback; both /signal and
/scan now show coarse milestones via message edits:
"📡 Fetching market data..." → "🧠 Analyzing pairs..." → result
- prefetch_batch is now run in a thread so it doesn't block the event loop
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add telegram_bot.py: full bot interface with /scan, /signals, /pair,
/all, /tf, /watch, /unwatch, /status, /help commands; per-chat state;
background thread pool for analysis; auto message splitting
- Fix data_provider: warn once per symbol with no API data and cache
synthetic fallback to prevent redundant individual API calls
- Fix signal_aggregator: derive spread estimate from already-fetched
primary DataFrame instead of making a separate M5 API call per pair
- Add python-telegram-bot[job-queue]>=20.0 to requirements.txt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>