CryptoCross Radar — symbol hover tooltip (rank / market cap / 24h) — 2026-06-24
Small feature on the Crypto Cross Radar page (/root/crypto_bots/cryptocrossradar.py, Flask on
127.0.0.1:5054, served behind nginx at /cryptocrossradar/). Jacques asked that
hovering a symbol in the table bring up a little pop-up table next to it showing
the coin's current rank, market cap, and 24h % move.
The data-gap finding (why this needed an external source)
Two of the three requested fields aren't in our data at all:
- The candle DB (crypto_cross.db) is OHLCV only — no market-cap, no supply.
- The "rank" we do store (universe_snapshots.rank) is a 24h trading-volume
rank within the tracked top-200 perps, not the market-cap rank Jacques means
by "position in the top 100/200 cryptocurrencies."
So a true market-cap rank + market cap had to come from outside. Decision (agreed with Jacques): pull all three from CoinGecko's free public API (no key — fits the "no keys" rule), so rank / cap / 24h are mutually consistent and match what he'd see on CoinMarketCap-style sites.
Implementation
Backend. Added a market-context layer to /root/crypto_bots/cryptocrossradar.py:
- A daemon thread fetches the top ~1,000 coins by market cap (/coins/markets,
4 pages of 250) and keeps an in-memory map base-symbol -> {rank, cap, chg}.
Refreshed every 10 min. Primed once at startup so tooltips have data immediately.
- Tolerant + non-regressing. The free endpoint rate-limits bursts, so each page
is retried once then skipped on failure — we keep whatever pages loaded instead
of discarding everything (the first naive version was all-or-nothing and showed
zero data whenever a single page 429'd). A full 4-page fetch replaces the map;
a partial fetch merges into the last good map, so coverage only ever grows.
On any error we keep the last good map and never crash the radar.
- Symbol matching is by upper-cased base; a leading thousands-prefix is stripped as
a fallback (1000PEPE -> PEPE). /api/scan rows gained mc_rank/mc_cap/mc_chg24.
- Reads nothing from our databases for this — zero extra load on the live DB writer.
Frontend. Each symbol cell carries the three values as data-attributes; a single
delegated mouseover/mouseout handler shows a fixed-position cream pop-up (groovy
theme, pointer-events:none so it never blocks the row's click-to-TradingView).
Market cap formats as $T/$B/$M; 24h is green/red. Symbols got a faint dotted
underline to hint they're hoverable.
Coverage (honest)
On the 1h "approaching-cross" list, ~24 of 31 rows resolve. The misses are mostly tokenized stocks on Bybit (IBM, SAMSUNG, GOOGL, NOKIA) which have no crypto market cap by definition, plus a few sub-1000 alts — all show "—", which is correct, not a bug. Verified the auto-heal in production: right after deploy a test-induced rate-limit left only 8/31; one refresh cycle later it was back to 24/31 with no intervention.
Ops
- Backed up the original to
/root/crypto_bots/cryptocrossradar.py.bak_1782327315before editing. - Tested end-to-end on a throwaway port (5077) first, then restarted
cryptocrossradar.service(with Jacques' explicit OK) — active and healthy. - Live: the radar page, hover any symbol.
Files
/root/crypto_bots/cryptocrossradar.py (market layer + tooltip), backup
/root/crypto_bots/cryptocrossradar.py.bak_1782327315. Data source: CoinGecko /coins/markets
(public, no key).