QUINN

loading quinn...

Things I make
tool2026 – Present

Galyari

Streams live market depth off Schwab's (or a provider of your choosing) API and paints it as a canvas heatmap with wall detection across multiple symbols. Built for actual functionality with no delays and fully open.

  • Python 3.13
  • Schwab API
  • asyncio
  • WebSocket
  • matplotlib
  • HTML Canvas

Commercial order-flow tools assume a Windows box and a subscription. Galyari is the version I wanted on Fedora: a real-time depth-of-market heatmap that renders to canvas at a steady frame budget, detects resting liquidity ("walls"), and follows several symbols at once.

The streaming layer normalizes Schwab's level-2 feed into a compact per-price-level ring buffer, and the render layer paints intensity by resting size over time — so persistent liquidity glows and fleeting quotes fade.

Gallery

Live depth-of-market heatmap — brighter bands are persistent resting liquidity.
Wall detection flags unusually large resting size at a price level.

Code

quickstart.beginbash
# ── Install ──────────────────────────────────────────────
# Requires Python 3.10+ (developed on 3.13).
pip install -r requirements.txt

# ── Run offline (start here — no credentials, no market hours) ──
python schwab_orderflow_heatmap.py --simulate
# Drives a synthetic random-walk book with decaying liquidity
# walls. The always-available test harness.

# ── Go live ──────────────────────────────────────────────
# Drop a .env in this folder (a template ships as .env; the real
# one is gitignored — never commit it):
#   SCHWAB_API_KEY=...        # App Key from developer.schwab.com
#   SCHWAB_APP_SECRET=...     # App Secret
#   SCHWAB_CALLBACK_URL=https://127.0.0.1:8182/   # MUST match the
#       # app registration char-for-char, trailing slash included
#   SCHWAB_ACCOUNT_ID=...     # brokerage account id (digits)
#   SCHWAB_TOKEN_PATH=/abs/path/to/token.json     # reused per run
python schwab_orderflow_heatmap.py --symbol AAPL
# First live run prints an OAuth URL: log in, then paste the full
# redirect URL (https://127.0.0.1:8182/?code=...) back in. The
# browser page looks broken — that's expected; the code is in the
# URL. token.json is written and reused (~7 days between re-auths).

# ── Switch symbols live, no restart ──────────────────────
python schwab_orderflow_heatmap.py --symbol AAPL \
    --watchlist AAPL,GOOG,TSLA,NVDA
# n / p cycle the watchlist; the "go to ▸" box jumps to any symbol.

# ── Record & replay (identical renderer across all modes) ──
python schwab_orderflow_heatmap.py --simulate --record   # -> recordings/SIM_*.jsonl
python schwab_orderflow_heatmap.py --replay recordings/AAPL_*.jsonl --speed 4

# ── Browser renderer: same data, streamed to a canvas ────
pip install websockets
python bridge.py --simulate                      # then open the printed URL
python bridge.py --symbol AAPL --watchlist AAPL,GOOG,TSLA,NVDA   # 2x2 live grid
# Open http://127.0.0.1:8080 — scroll to zoom (lossless), click a
# tile to expand, Esc to return to the grid.

Papers & documents

Galyari — Build NotesOpen ↗

Your browser can't display this PDF inline.

Open the PDF ↗