Skip to main content

Units and sign convention

All GEX values are USD per 1 % move of the underlying: gex = gamma × open_interest × contract_multiplier × spot² × 0.01, summed per strike. Dealer convention: calls add, puts subtract. call_gex and put_gex are non-negative magnitudes; net_gex = call_gex − put_gex. Numbers are plain decimals (no thousands separators, no scientific notation). Every response repeats the unit string in meta.units ("USD per 1% move of the underlying") and links back to this page in meta.docs_url.

Levels fields

These fields describe one GEX snapshot. They are returned by GET /levels/{exchange}/{coin} (as the whole data object) and as data.levels in GEX by Strike (both view=full and view=levels). Rows marked history are identity columns of stored snapshots. They appear in the history endpoints and files but are not part of the live levels object; the live equivalents are listed with each field and in the note under the table. P/N/A levels are computed over the strike window the app uses for the chart.
In the JSON API, “empty” is null. /levels additionally returns expiration (TOTAL or an expiration code such as 17OCT26) and expiration_iso (YYYY-MM-DD, null for TOTAL) next to the fields above.

Per-strike fields

Live per-strike data comes from GEX by Strike as parallel arrays under data.gex_data (index i refers to the same strike across arrays). The stored history uses one row per strike with these fields, in /history/snapshot (data.strikes) and in the strikes_total and strikes_by_expiry files. Files and snapshot responses include only strikes within +/- 25% of the snapshot’s spot. In the strikes_total file these columns are prefixed with strike_ (strike_call_gex, strike_put_gex, strike_net_gex, strike_call_oi, strike_put_oi), because the snapshot-level call_gex, put_gex and net_gex are repeated on every row of that file.

Daily history files

One set of files per exchange, symbol and completed session, downloaded through /history/files. Common to all three:
  • CSV, UTF-8, comma separated, one header row, gzip compressed (<date>_<file>.csv.gz).
  • Numbers are plain decimals: no thousands separators and no scientific notation. Strikes and open interest have no decimal part when they are whole numbers (3, not 3.0).
  • An empty cell means the value is missing (the JSON API’s null).
  • Rows are sorted by timestamp_utc; within one capture TOTAL comes first, then the expirations by date, then strikes in ascending order.
  • timestamp_utc is ISO 8601 UTC with Z. expiration is an ISO date (YYYY-MM-DD) or TOTAL.
  • schema_version is 1. Rows are never rewritten with later data; see Historical data for the point-in-time rules.
  • Strikes are within +/- 25% of that snapshot’s spot.
  • The last capture of the session has type = close; the others intraday.

levels

One row per capture and expiration, including TOTAL. The columns are the snapshot-level fields from the table above, in this order: schema_version, timestamp_utc, session_date, type, exchange, symbol, expiration, dte, oi_date, spot, flip, flip_count, regime, net_gex, abs_gex, call_gex, put_gex, call_oi_total, put_oi_total, p1_strike, p1_gex, p2_strike, p2_gex, n1_strike, n1_gex, n2_strike, n2_gex, a1_strike, a1_gex, a2_strike, a2_gex, s_price, s_gex, v_price, v_gex, max_pain, atm_iv

strikes_total

One row per capture and strike, for the TOTAL snapshot only. Every row repeats the snapshot-level columns of levels (in the same order), followed by the strike columns: strike, strike_call_gex, strike_put_gex, strike_net_gex, strike_call_oi, strike_put_oi This is the easiest file for backtests: one row has the strike and the context (spot, flip, regime) it was captured in.
The example is illustrative and abbreviated (... replaces columns). dte is empty for TOTAL.

strikes_by_expiry

One row per capture, expiration (including TOTAL) and strike. Narrow on purpose: join to levels on timestamp_utc and expiration for the snapshot-level context. Columns: schema_version, timestamp_utc, expiration, strike, call_gex, put_gex, net_gex, call_oi, put_oi

Reading the files

Pass compression="gzip" explicitly: a presigned link ends in a query string, so pandas cannot infer the compression from the name. See History: Files for the full download flow.

Known gaps

  • Volume is not captured; there are no volume fields, live or in history.
  • Venue subsets (for example deribit+derive) are served live. They are not part of the stored history: per-strike GEX can be summed client-side from single-venue data, but the gamma flip cannot.
  • Rows captured before open interest was stored have empty call_oi / put_oi and call_oi_total / put_oi_total.