Adds FinnhubDataProvider as a drop-in replacement for ForexDataProvider.
Rate limit or API errors raise DataUnavailableError immediately — the
Telegram bot shows a clean per-TF error card rather than fake prices.
- data_provider_finnhub.py: Finnhub client, OANDA symbol mapping,
4h resampled from 60-min candles, shared module-level rate limiter
(60 calls/min free tier), full OHLCV validation copied from original
- signal_aggregator.py: import FinnhubDataProvider alias ForexDataProvider
- config.py: add finnhub_api_key field (FINNHUB_API_KEY env var overrides)
- telegram_bot.py: remove synthetic-data warning and _SUPPORTED_PAIRS;
unsupported pairs now show the engine's "data unavailable" card
- requirements.txt: add finnhub-python>=1.0
Set FINNHUB_API_KEY env var before running. main branch is untouched.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
data_provider:
- Remove _generate_synthetic_data entirely — no more fake prices
- Raise DataUnavailableError instead of falling back to synthetic data
(no API key, daily limit hit, API returns no values, fetch failure)
- Move rate limiter to module-level globals (_rate_lock, _rate_request_times,
_rate_daily_credits) so all ForexDataProvider instances running in parallel
threads share the same 8-credit/min and 800-credit/day accounting
- _throttle now raises DataUnavailableError on daily limit (was silent return False)
- Remove _no_api_data tracking, numpy/hashlib imports
telegram_bot:
- Detect F-grade reports caused by data unavailability and show clean
"Data unavailable" line per TF instead of a garbled zero-price card
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
/signal: one combined message with all 4 TF sections stacked (────── dividers),
entry/TP/SL always preserved, indicators per TF, MTF folded to one footer line,
disclaimer once at bottom, news/warnings only when relevant
/scan: single compact message — one header+trade line per pair, full entry/TP/SL
kept, no indicator list (use /signal to drill in), danger events shown inline
Both commands show price pull time as EST (e.g. 09:42 AM EST · Mon 04 May 2026)
Scanning progress message no longer shows a single TF in parentheses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- /signal EURUSD sends one card per timeframe (M15, H1, H4, D1) concurrently
- /scan analyzes all pairs across all TFs, shows best-grade card per pair (B+ only)
- All TFs run in parallel via ThreadPoolExecutor (one worker per TF)
- Remove /tf command and per-chat state — no longer needed
- Executor pool sized to len(SCAN_TIMEFRAMES) for true concurrency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace /scan+/pair commands with /signal (single pair) and /scan (all pairs, B+ only)
- Implement exact visual template: grade dot (🟢/🟡/🔴), TRADE ALERT header, Entry/TP/SL/R:R block, full indicator list with value + condition
- Grade dot enforced: A/A+=🟢, B=🟡, C/D/F=🔴
- /scan filters to minimum Grade B confidence before sending alerts
- HTML parse mode with html.escape() on all dynamic content
- Per-chat default timeframe state preserved
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
data_provider:
- Switch to Authorization header (recommended over apikey query param)
- Enforce 800 credits/day daily limit with warning at 80%
- Fall back to synthetic data when daily limit is reached
- Fix null OHLC field handling (API can return null for any field)
telegram_bot:
- Register commands with set_my_commands so Telegram shows / menu
- Add /credits command to show daily API credit usage and limits
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>