Work/2026
NASDAQ Speculative Screener
Near-real-time trading data platform over IBKR — plus an audited review of the real account behind it: TimescaleDB, dbt contracts, SSE push, a three-source portfolio pipeline and score validation with future returns.

~72msbatch commit to updated UI (SSE)
~1,640 RPSaggregate under load, 0 errors at 200 clients
100+dbt tests + contract on every batch
A screener and opportunity detector for speculative NASDAQ trading, built as a governed, near-real-time data platform: an audited ELT pipeline with dbt over PostgreSQL 18 + TimescaleDB, a polars-based engine, a FastAPI layer with enforced data contracts and server-sent events, and a terminal-style React frontend with live candles, intraday scoring and Telegram push alerts. It runs on a Mac mini against IBKR’s delayed feed, so operating it costs nothing beyond the hardware.
Highlights
- Near-real-time without polling. When a batch lands, the collector emits pg_notify; a single LISTEN/NOTIFY watcher in the API pushes the event to every SSE client (~15ms from commit to event, down from ~14.5s of polling), and the UI refreshes itself in about 72ms measured from commit to DOM. A per-batch single-flight cache serializes the Pydantic contract once per batch, not per request: load-tested at ~1,640 RPS aggregate across five endpoints (the hot screener endpoint at 450 RPS with p95 of 304ms) and zero errors at 200 concurrent clients.
- Time-series storage that scales. Daily and 5-minute bars live in TimescaleDB hypertables with columnar compression (4.1x measured even on random data, 10-20x typical), incremental dbt marts only touch recent chunks, and the whole thing degrades gracefully to plain PostgreSQL if the extension is missing.
- Intraday scoring on top of the daily engine. For the top-N symbols the collector captures 5-minute bars through the same governed pipeline, feeding live candle views with VWAP, EMA 9/20, session-colored extended hours (pre-market and after-hours), an IBKR-style measuring ruler, and a real intraday score: VWAP reclaim + opening range breakout + RVOL relative to time of day.
- Portfolio review over the real account. The newest pillar reconstructs trades FIFO from three sources (the gateway, IBKR’s Flex statements and a macOS screen reader) because no single source knows stop prices, history and cancellations at once. It reports R-multiples against the actually assumed risk, fill/cancel/slippage rates, and equity metrics that deduct deposits and withdrawals.
- A screen reader instead of guesswork. IBKR’s API never exposed the stops actually shown in IBKR Desktop (3k+ stored orders, zero stop prices), so a Swift ScreenCaptureKit + Vision OCR reader captures them: geometry-first column detection, three validation barriers, seven explicit verdict states, and change-only writes so the table is the history. Cold read 3.15s, warm 1.04s, no-change cycle 0.21s.
- The thesis killer feature: score validation. A dedicated page answers “does the score actually predict returns?” with forward returns at D+1, D+5 and D+10 per signal bucket, hit rates, and the information coefficient (rank correlation between score and future return), with no lookahead: signal at close of day D, entry at next open. The Backtesting page adds ATR-based stops and targets, commissions and slippage modeled, and a grid optimizer designed for out-of-sample validation.
- Alerts that reach you. Configurable rules (symbol, metric, threshold or signal) push to Telegram with an attached intraday mini-chart and actionable stats, plus a volume-explosion alert that catches what surges even if you never mapped it. Cooldown per rule and symbol, latency instrumented.
- Governance as the foundation. Append-only raw zone where every row carries batch lineage, strict schema ownership (collector owns raw/meta, dbt owns staging/marts, the API reads only marts), 100+ declared dbt tests plus source freshness persisted to a control plane and surfaced in a Data Ops page, and an enforced dbt contract. 306 Python tests behind an 80% coverage gate in CI.
- Fail-closed public demo. The public site runs a separate demo code path that cannot query the real portfolio tables (a test fails the build if it tries), audience is asserted by an nginx-injected header, and a one-command deploy ends with five assertions, including that a forged private header leaks nothing.



