Why this exists: the prior behavior was that every tick from every source overwrote the canonical price. So a 12-second Stooq poll could overwrite a 1-second Coinbase WebSocket realtime price with stale data. Now: each source gets a composite quality score from built-in priority (WS > REST > refresh), recent reliability (success rate), cross-source agreement, and latency. Only ticks from the equal-or-better source replace canonical.
🏆 Source quality ranking (best → worst)
SourceScorePriorityReliabilityAgreementLatency
Waiting for first ticks... reload in 30s if empty.
🪞 Shadow prices (rejected as canonical, kept for cross-check)
When a lower-quality source ticks for a symbol that already has a higher-quality canonical, the new price is logged as shadow. Big gap = potential source bug.
SymbolCanonical priceCanonical sourceShadow priceShadow sourceGap %
No shadow prices yet. Need at least 2 sources fresh on same symbol.
🔗 Related
📊 Data Reliability 📅 Weekly Refresh ⏪ Historical Bootstrap 💰 Make Money