DEV Community

tomasz dobrowolski
tomasz dobrowolski

Posted on • Originally published at flashalpha.com

Replay any minute of SPY options back to 2018 - historical GEX, DEX, VEX, CHEX in one API

TL;DR

Same JSON as the live FlashAlpha options analytics API. Add one query parameter - at - and you get historical gamma exposure (GEX), delta exposure (DEX), vanna (VEX), charm (CHEX), max pain, VRP, the SVI surface, the 0DTE block, and the full stock summary as they stood at that minute, with no future leakage. 6.7 billion option rows going back to April 2018.

  • Host: historical.flashalpha.com
  • Endpoints: every live analytics route, mirrored
  • Dataset start: 2018-04-16
  • Resolution: 1 minute for quotes + greeks; EOD for OI, macro, SVI

Why a separate host instead of one URL with ?at=

So your SDK doesn't need to know anything new. Point your existing client at a different base URL, add at=, done. Same auth header (X-Api-Key), same response shapes, same code path - literally the same analytics service, reading from minute-level archives instead of the live feed.

This matters when you're backtesting. You don't want to port a strategy onto a second set of response parsers just to replay history.

The at parameter

It's ET wall-clock. Don't apply a UTC offset.

Format Example Meaning
yyyy-MM-ddTHH:mm:ss 2026-03-05T15:30:00 Minute-level
yyyy-MM-dd 2026-03-05 Defaults to 16:00 ET (close)

Example: historical GEX at the COVID low

curl -H "X-Api-Key: $FA_KEY" \
  "https://historical.flashalpha.com/v1/exposure/summary/SPY?at=2020-03-16T15:30:00"
Enter fullscreen mode Exit fullscreen mode
{
  "symbol": "SPY",
  "underlying_price": 246.01,
  "as_of": "2020-03-16T15:30:00",
  "gamma_flip": 270.92,
  "regime": "negative_gamma",
  "exposures": {
    "net_gex":  -2633970601,
    "net_dex": -169419489077,
    "net_vex":  152461756844,
    "net_chex":   -13122349
  }
}
Enter fullscreen mode Exit fullscreen mode

Real dealer positioning at 15:30 ET on the day SPY closed -12%. Not a reconstruction - the same greeks that existed on the tape, run through today's analytics.

What moves per minute vs per day

Not every series is worth storing at minute granularity:

Layer Granularity
Option quotes + greeks (iv, δ, γ, θ, ν, vanna, charm) 1 minute
Stock bid/ask/mid 1 minute
Open interest EOD
SVI params, forward prices EOD
VIX / VVIX / SKEW / MOVE / DGS10 EOD

OI barely moves intraday and is dealer-positioning context - so applying one EOD value to every intraday at= on that day is defensible. Intraday exposure shifts are driven by greek + spot changes anyway.

No future leakage on VRP

The /v1/vrp/{symbol} endpoint computes percentile and z-score using only history prior to at. Query VRP at 2020-03-16T15:30 and the percentile is ranked against the distribution as it existed on that day, not against the full 2018–today window.

Backtests don't lie when the data doesn't.

Endpoints

Every live endpoint is mirrored:

  • /v1/stockquote/{ticker} — bid/ask/mid at a minute
  • /v1/optionquote/{ticker} — option quote + greeks + OI
  • /v1/exposure/gex|dex|vex|chex/{symbol} — exposure by strike (historical GEX, DEX, VEX, CHEX)
  • /v1/exposure/summary/{symbol} — regime, flip, net exposures
  • /v1/exposure/levels/{symbol} — flip, walls, magnets
  • /v1/exposure/narrative/{symbol} — verbal regime + prior-day comparison
  • /v1/exposure/zero-dte/{symbol} — historical 0DTE block
  • /v1/maxpain/{symbol} — max pain + pin probability
  • /v1/volatility/{symbol} — RV ladder, IV-RV spread, skew
  • /v1/adv_volatility/{symbol} — SVI params, variance surface, arbitrage flags
  • /v1/vrp/{symbol} — VRP dashboard, date-bounded
  • /v1/stock/{symbol}/summary — everything in one call

Plus one historical-specific route:

  • /v1/tickers — coverage map (first date, last date, gaps, healthy-day count) per symbol

Honest field coverage gaps

Upfront about what's zero/null vs what's real:

Field Status Why
bidSize, askSize, volume 0 Minute quotes don't carry sizes
call_oi_change, put_oi_change null Prior-day per-strike diff not yet computed
0DTE per-strike greeks often 0 / null Near-expiry minute greeks still backfilling
summary.macro.vix_futures null CME futures curves aren't archived historically
optionquote.svi_vol null Per-contract SVI derivation not yet exposed — use /v1/adv_volatility

Everything else — greeks, IV, exposures, flip, walls, regime, narrative, VRP percentiles, SVI fits, variance surface, arbitrage flags — is real data at at.

Coverage

SPY is fully backfilled 2018-04-16 → 2026-04-02 and extends on every refresh. Additional symbols are backfilled on request. Query the live coverage map anytime:

curl -H "X-Api-Key: $FA_KEY" \
  "https://historical.flashalpha.com/v1/tickers"
Enter fullscreen mode Exit fullscreen mode

Latency

Point-in-time reads are ~50–300 ms typical. Composite endpoints (/v1/adv_volatility, /v1/stock/{symbol}/summary) rebuild surfaces on demand and take ~500–1500 ms cold. Responses are deterministic for a given (symbol, at) tuple - cache indefinitely.

Links

Top comments (0)