Skip to content

GEX

What it computes

Aggregate dealer gamma exposure at the underlying spot, decomposed by strike. The crate emits the per-strike contribution under the canonical SqueezeMetrics sign convention (dealers are net short calls / net long puts):

GEXcall,i=γiOIimS2GEXput,i=+γiOIimS2GEX=iGEXcall,i+iGEXput,i

where γi is the per-contract Black–Scholes gamma at the option's NBBO mid, OIi is the open interest taken from the boot-time reference-data snapshot hydrated at Client::connect, S is the underlying spot, and m is the contract multiplier (100.0 for US-listed equity options, defaulted server-side to match the standard equity-option contract size). Positive net GEX means dealers are net long gamma (price tends to be pinned); negative net GEX means dealers are net short gamma (moves are amplified). Consumers that want a "dollar gamma per 1 % spot move" scaling apply the per-1 % factor on their side; the engine emits the raw aggregate.

The analytic implements the signed per-contract contribution following the SqueezeMetrics convention.

Methodology

SqueezeMetrics, The GEX Effect (2017). See /methodology/squeeze-metrics for the dealer-positioning convention. Black–Scholes gamma derivation: Hull §19.

Inputs

  • The option chain's NBBO quote stream per strike.
  • The prior-session option open-interest snapshot hydrated at Client::connect (see reference data for the boot-time hydration model).
  • The underlying-spot reference populated from stock NBBO quotes — the same source the Greeks analytic reads from.

Both reference-data surfaces are provisioned by the client at connect time. Callers configure the analytic only through its public knobs (the contract filter and the scalar debounce interval) — every required data dependency is plumbed under the hood.

Contracts without an OI entry, without a spot price, or with an unresolvable IV are skipped — strikes_used reflects only contributing contracts.

Output schema (GexTick)

The field / type / description table below is regenerated from the GexTick Rust source by docs-site/scripts/inject-doc-tables.ts on every npm run docs:build. Do not hand-edit between the sentinels.

FieldTypeDescription
contractContractResolved underlying contract metadata. Subscribers identify the underlying by (symbol, …) on this field — the wire-level contract id is engine-internal and is not surfaced here.
datei32Trading-session date in YYYYMMDD form.
ms_of_dayi32Milliseconds-of-day of the emission.
spotf64Spot price used to scale every contribution.
net_gexf64Net gamma exposure across every contributing contract.
call_gexf64Sum of call-side gamma exposures (positive under the SqueezeMetrics convention — dealers are net long calls).
put_gexf64Sum of put-side gamma exposures (negative — dealers are net short puts).
strikes_usedu32Number of (expiration, strike, right) triples that contributed (i.e. had a resolved γ and an OI hit).
per_strikeVec<GexStrikeContribution>Per-(expiration, strike, right) contributions, sorted lexicographically for deterministic replay.
zero_gamma_strikeOption<i32>Approximate zero-gamma strike: the smallest strike on the chain where cumulative GEX (sorted by strike, summed from below) changes sign — on a typical chain the put-dominated low strikes accumulate negative dealer gamma and the call-dominated high strikes flip the running sum positive. None when no crossing exists in the surveyed range (e.g. when every contribution shares a sign).

Configuration (GexParams)

The caller names the contract universe in the analytic accessor (client.live().gex([...])) — bare symbols expand to the chain plus the underlying — and inherits the standard 100.0 contract multiplier for US-listed equity options as the server-side default. The reference-data dependencies (rate, calendar, the open-interest and spot caches) are wired at Client::connect time and shared with a matched Greeks subscription. The full field set is regenerated from the GexParams Rust source:

FieldTypeDescription
contractsSecurityFilterContracts the subscription tracks. Typically a [SecurityFilter::Symbols] entry naming the underlying roots.
rateArc<dyn RateService>Risk-free rate provider, shared with the Greeks analytic.
calendarArc<dyn MarketCalendar>Market calendar provider, shared with the Greeks analytic.
annual_dividendOption<f64>Annual continuously compounded dividend yield. None (default) treats the underlying as non-dividend-paying.
dividend_cache`std::sync::Arc<crate::reference_data::dividend_yield::
DividendYieldCache>`Engine-wired per-symbol dividend-yield cache. Seated at subscribe time by DefaultSpec via wire_dividend_yield. Consulted on the dispatch path only when annual_dividend is None — the per-tick lookup resolves the continuous-dividend carry yield q = D / S from the live underlying spot the analytic already holds (O(1), lock-light, non-blocking). An explicit annual_dividend override always wins.
oi_cacheArc<OpenInterestCache>Engine-wide market-wide Option open-interest cache. Build at Client::connect via Client::builder() and clone the resulting Arc into the spec.
spot_cacheSpotPriceCacheShared underlying-spot cache, populated by the engine from stock NBBO quotes. The same handle the Greeks analytic reads from.
contract_multiplierf64Contract multiplier. Default 100.0 for US-listed equity options.
min_emit_interval_msi64Minimum interval between emissions, in milliseconds. Defaults to 1_000 (one snapshot per second).
conditionsConditionPolicyTrade-condition admission policy (gates which quote ticks can feed the IV solve).
venuesExchangeFilterExchange / venue admission policy applied to option quotes.
iv_cacheIvCacheConfigIV reuse thresholds for the per-contract γ recompute — the same drift policy the Greeks analytic applies. When the (option_mid, spot) pair drifts below both thresholds the bisection IV solve is skipped and γ is recomputed in closed form from the cached IV; the solver dominates per-quote cost, so the reuse path carries the steady-state throughput. [IvCacheConfig::off] re-solves on every quote.

Operational characteristics

  • Per-tick latency. Incremental per-strike update; emissions debounced by min_emit_interval_ms.
  • Open-interest snapshot. Sealed at Client::connect from the prior session's settlement snapshot. Staleness is the caller's responsibility — the snapshot is captured once at boot and pinned for the session.
  • Allocation discipline. Strike-contribution Vec is reused across emissions; the GexTick payload is the only heap allocation per emit.
  • Replay parity. Deterministic — the open-interest snapshot is immutable post-boot.

Example

rust
// Cargo.toml:
//   kairos = "0.1"

use kairos::{Client, GexRow};

let client = Client::connect(("me@example.com", "secret"))?;

let sub = client
    .live()
    .gex(["QQQ"])
    .on_event(|row: &GexRow| {
        // The callback fires once per emission with a typed `GexRow`.
        println!("net_gex={} spot={}", row.net_gex, row.spot);
    })?;
// ... later ...
sub.unsubscribe();

Proprietary. All rights reserved.