Skip to content
08Case studySW · 08 of 10

Earnings calendar and SPX gamma exposure, fused into one dashboard.

A quant trading firm needed to see two things on one screen — an earnings calendar accurate enough to trade against, and live SPX dealer-gamma exposure. Neither existed off-the-shelf. We built both and wired them together.

ClientConfidential
Year2022 — 2026
Duration5 yrs
StackTypeScript · Next.js · React · Node · Python · FastAPI · Redis
Hero image for earnings-gamma-dashboardFIG 01 · HERO

Two surfaces. One trading decision.

A quant trading firm was working with a real but mundane frustration: the data they needed to make a single decision was sitting in two separate tools that had no idea the other existed.

On one side, an earnings calendar. Four major public-facing sources, each slightly different — different symbols, different call-time conventions, occasional duplicates, occasional contradictions. The team was hand-reconciling across them before anything traded.

On the other side, SPX dealer-gamma exposure. The options market-structure indicator that tells you where systematic hedging pressure concentrates — which strikes become magnetic as the market moves toward them, where dealers will buy weakness and sell strength, how much buffer the index has before mechanical selling kicks in. There is no Bloomberg field for this. You derive it. Fresh, from the exchange's options chain, with Black-Scholes gamma computed by strike and aggregated by delta-adjustment. And you do it every fifteen minutes during the cash session, or the number you have is already wrong.

The brief was specific: one screen, both signals, synchronised. Hover over an earnings event. See the gamma picture for that date. Off-the-shelf products do one or the other. Nobody was doing both in a single view.

A fused view: event calendar on top, gamma exposure underneath.

The dashboard gave the firm's traders an earnings calendar surfacing symbols from four independent data sources — deduped, reconciled, with call-time indicators — layered over a live gamma exposure chart for SPX. The two surfaces were synchronised: hover over an earnings date, and the gamma chart snapped to the exposure picture for that session.

The gamma chart showed aggregate dealer exposure by strike, delta-adjusted, with a net-gamma line that made the positive/negative flip visible at a glance. Zero gamma — the point where dealer hedging flips from stabilising to amplifying — was marked as a constant. The daily open and prior close were reference lines. Strike clusters where exposure concentrated showed up as spikes.

The earnings calendar showed confirmed and tentative events with call-time indicators (BMO, AMC, unconfirmed). Symbol-level filtering, a date-range selector, and a watchlist view let a trader scope the calendar to their book without touching the gamma layer. The two views shared the same date axis. That was the whole point.

The frontend ran on Next.js 16 and React 19, with D3.js handling the gamma rendering and Zustand managing the shared calendar/chart state. Vercel Analytics was wired in from the first week of production.

F · 01Multi-source earnings calendar
Four independent sources deduplicated by symbol, date, and call-time. Per-source retry-and-backoff handling degrades the calendar gracefully when a source breaks — the trader's view never goes dark.
F · 02Live SPX gamma exposure chart
Black-Scholes gamma computed fresh on the full SPX options chain every fifteen minutes during market hours. Aggregated by strike, delta-adjusted. Zero-gamma and key reference lines marked.
F · 03Synchronised date axis
Hover an earnings event and the gamma chart snaps to the exposure picture for that session. The fusion is in the interaction, not just in the layout.
F · 04Redis-only hot store
No cold database. Both pipelines write into Redis JSON, keyed by date and symbol. Sub-millisecond frontend reads. The access pattern never needed anything more.
F · 05Per-source telemetry
Each earnings parser exposes its retry state as a metric. A broken parser surfaces in the monitoring dashboard within one refresh cycle — before anyone trading against the data notices.
F · 06Two-language backend
Node/Express for scraping and deduplication. Python/FastAPI for the quant layer — scipy.stats, numpy, pandas. Each language owns the problem it fits. One cache holds the result.

One cache, two pipelines, two languages.

The data-fusion problem underneath the dashboard was an architecture choice with a clear answer: two independent pipelines, neither blocking the other, writing into a single hot store.

The earnings pipeline ran in Node and Express. A scraper service pulled from four independent public-facing calendars every three hours. Each source had its own parser — isolated, with retry-and-backoff handling so a transient failure on one source didn't corrupt the others. Deduplication ran by symbol plus date plus call-time; a symbol appearing in three sources with minor date-formatting differences resolved to one canonical record. Per-source telemetry meant a broken parser was visible in the monitoring dashboard before a trader noticed anything wrong.

The gamma pipeline ran in Python. FastAPI served the quant layer: a fresh SPX options chain pulled from the exchange CSV feed every fifteen minutes during market hours, passed through Black-Scholes gamma calculation using scipy.stats and numpy, aggregated by strike and delta-adjusted. Python was the right tool here — scipy.stats, the scientific Python ecosystem, and the way the quant team already reasoned about the calculation. Rewriting it in TypeScript would have added friction with no upside.

Once there was no cold database to fall back to, every pipeline had to be correct at write time. That pressure produced cleaner parsers and a sharper on-call story.

Both pipelines wrote into Redis. No cold database — by design, not by omission. Telemetry from the first weeks of production confirmed what the architecture assumed: the access pattern was always 'what does the picture look like right now', never 'what did it look like six weeks ago'. Redis JSON, keyed by date and symbol, gave the frontend sub-millisecond reads on the current state. The cache was the whole store.

Four years in production. Still refreshing every fifteen minutes.

The dashboard shipped its first production deployment in 2022 and has run continuously since. The two-pipeline architecture has survived three years of selector churn on the earnings sources, exchange feed format changes on the gamma side, and a complete frontend rebuild when the React 19 migration landed.

Earnings coverage sits at 5,000-plus symbols across four independent sources. The gamma engine processes 3,000-plus SPX strikes per expiration cycle. The refresh cadences have not changed: earnings every three hours, gamma every fifteen minutes during the cash session.

The per-source circuit-breaker telemetry has been the most operationally useful feature. Source parsers break silently — a calendar redesign or an API change with no announcement. The telemetry flags a degraded source within one refresh cycle. The trader's view of the calendar degrades gracefully; it doesn't go dark.

The frontend codebase reached 325 commits by the end of 2024. The backend crossed 541. The gamma engine, which has changed the least, stands at 59. The ratio is a fair map of where the work actually was: not in the quant maths — that settled early — but in the continuous maintenance of the data layer underneath it.

PULL QUOTE / 04
We stopped maintaining a separate spreadsheet for this within a week of it going live. It does the reconciliation we were doing by hand, and it knows what the market looks like when it does it.
Portfolio managerQuant trading firm
Outcome
Earnings sources reconciled
4
Symbols covered
5,000+
Gamma refresh (market hours)
every 15 min
Years in continuous production
4
NEXTCase study 09SW · 09 of 10
AdTech2026

Three runtimes, one team, one month: a digital signage network for venue, advertiser, and screen.