work · a stock-trading desk · 2026

Trading-desk platform: screener, alerts, trade journal, desktop client

I built and ran the platform about 20 traders use every day: a live screener, alerts, a broker-CSV trade journal and an Electron client. v1.5.0 went to production on 2026-08-27.

problemconstraintswhat I builtoutcomestackredacted screenshot

Problem

The desk needed one workspace for live top-gainer screening, price alerts, trade review and per-trader reporting, fed by market-data vendors and broker exports. It runs on a self-hosted server with a single engineer, and that engineer is also a user of the desk's automated trading system.

Constraints

What I built

fig 1. Data path from vendors and broker exports to the trader's screen.

Outcome

dateresult
2026-02-18Phases 1-8 tested and passing: market data 47/47, screener 25/25, alerts and sharing 49/49, admin 37/37
2026-02-25Load test: 20 users for 10 min, 0 errors. 30-min memory test: heap growth -0.060 MB/min, peak RSS 117 MB
2026-04-22v1.3.0 adds an admin trade dashboard and weekly DB backups
2026-08-10Read-only mathematical audit reconciled daily reports across all 149 selectable dates
2026-08-26Platform status page covering 26 services, with run-length uptime history
2026-08-27v1.5.0 deployed, prod migrations 70 -> 80. An order-attribution data loss was found and backfilled the same day

Numbers and incidents

whenwhat
v1.2.044 tables, 78 migrations, 442 tests in 32 suites
2026-05-13~6 h outage after a Windows Update reboot (PM2 had no auto-start). Fix: a boot-time scheduled task per user
2026-08-05A poller ran ~9,600 requests/day against ~6,400 in-session because of a session-gate timer bug. The PM2 log reached 1.07 GB
2026-08-06A vendor INT64_MAX "no value" sentinel had persisted bars priced in the billions, and a warning fired ~1,500 times/day. Fix: a 0 < price < 1e7 ingest guard
2026-08-17Investor SVG charts were wrong on most trades. Six root causes fixed
2026-08-271,154 of 5,686 trades (20.3%) had lost their linked orders: the replace-on-upload delete was scoped to user+date but not account. Backfilled; 356 remain unrecoverable because the source data does not exist

Stack

Node.jsExpress 5PostgreSQLRedisWebSockets (ws)React 18Vite 6Electron 33node-pg-migratePM2Jest

Redacted screenshot

fig 2. Mock workspace. Fake tickers (AAAA, BBBB) and fake prices; black bars mark fields that are redacted in the real app (accounts, P&L, trader names, hosts).
INCIDENT 2026-08-27 · order attribution
impact   1,154 / 5,686 trades (20.3%) lost their linked orders
cause    replace-on-upload delete scoped to user+date, not account
fix      found and backfilled the same day
residual 356 unrecoverable, because the source data does not exist
evidence: brain/projects/stock-screener.md · stock-screener/context.md · known-issues.md · decisions.md · brain/profile.md · brain/cv.md