What you will accomplish
- Discover markets dynamically
- Stream and display bid/ask data
- Calculate spread and staleness safely
- Deploy without private credentials
Before you begin
- Node.js or a browser-capable frontend toolchain
- Public Quote.Trade API access
- A decision about server-side proxy versus browser WebSocket
Read active symbols and rate limits
Fetch exchangeInfo at startup and refresh periodically. Use status and quantityScale only as returned; do not infer funding or minimums.
Fetch ticker and depth with timeouts
Record local receive time and any server/update fields. Handle unavailable symbols and malformed responses explicitly.
Calculate spread with Decimal
Keep raw values as strings and convert with Decimal only when calculating.
from decimal import Decimal, InvalidOperation
def spread_bps(bid: str, ask: str) -> Decimal:
try:
b, a = Decimal(bid), Decimal(ask)
except InvalidOperation as exc:
raise ValueError('invalid decimal input') from exc
if not b.is_finite() or not a.is_finite() or b <= 0 or a <= 0 or a < b:
raise ValueError('invalid market')
mid = (a + b) / Decimal('2')
return (a - b) / mid * Decimal('10000')Display freshness and data status
Show endpoint, symbol, receivedAt, update ID or event time, and whether the value is public market data, indicative, or a separately obtained firm all-in quote.
Alert only on clear, repeated failures
Alert on stale receive time, invalid spread, missing side, schema change, or repeated failures. Do not automatically trade from the monitor.
Common problems and fixes
The selected symbol disappears
Refresh exchange information and remove halted or unavailable markets gracefully.
Values flicker due to floating-point precision
Use a decimal library and format according to the symbol’s production precision.
The browser cannot open the stream
Use a server-side relay after confirming current origin and network requirements; never put a private token in the browser.