Expiry Impact API - SPY/QQQ Gamma Concentration Without One Expiry - FlashAlpha Lab API
Lab API Expiry Impact

Expiry Impact API

How much of SPY or QQQ gamma concentration depends on one expiry? Compare the captured chain with and without that expiry: gross share removed, net GEX change, sign change and the strikes that lose the most gamma.

Endpoint

GET /v1/exposure/expiry-impact/{symbol}
Auth required (X-Api-Key) Rate Limited: Yes Growth plan+

Parameters

Name In Required Default Description
symbolpathyes - SPY or QQQ
expiryquerynonearest active expiryyyyy-MM-dd; must be one of available_expiries
limitqueryno51-20 ranked strike rows; totals always use the full eligible chain
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://lab.flashalpha.com/v1/exposure/expiry-impact/SPY?limit=5"
import requests

resp = requests.get(
    "https://lab.flashalpha.com/v1/exposure/expiry-impact/SPY",
    headers={"X-Api-Key": "YOUR_API_KEY"},
    params={"limit": 5}
)
data = resp.json()
impact = data["impact"]
print(f"{data['selected_expiry']} holds {impact['removed_gross_share_pct']:.1f}% of gross gamma")
print(f"net sign: {impact['net_sign_before']} before, {impact['net_sign_after']} after")
const resp = await fetch(
  "https://lab.flashalpha.com/v1/exposure/expiry-impact/SPY?limit=5",
  { headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
const data = await resp.json();
console.log(data.selected_expiry + " holds " + data.impact.removed_gross_share_pct.toFixed(1) + "% of gross gamma");

Response

{
  "symbol": "SPY",
  "underlying_price": 663.42,
  "snapshot_id": "4f1c9e...",
  "generated_at": "2026-10-16T18:30:00Z",
  "pricing_basis": "captured_cached_gamma_current_spot",
  "data_status": "partial",
  "reasons": [{ "code": "oi_vintage_unknown", "message": "..." }],
  "gex_unit": "usd_delta_notional_per_1pct_move",
  "sign_convention": "calls_positive_puts_negative",
  "analysis_type": "expiry_removal_sensitivity",
  "selected_expiry": "2026-10-16",
  "selection_source": "nearest_active",
  "available_expiries": ["2026-10-16", "2026-10-19", "2026-10-20"],
  "current":          { "gross_gex_usd": 9100000000, "net_gex_usd": 2300000000, "contract_count": 8412 },
  "excluded_expiry":  { "gross_gex_usd": 1950000000, "net_gex_usd":  650000000, "contract_count": 1906 },
  "excluding_expiry": { "gross_gex_usd": 7150000000, "net_gex_usd": 1650000000, "contract_count": 6506, "status": "available" },
  "impact": {
    "removed_gross_share_pct": 21.43,
    "retained_gross_share_pct": 78.57,
    "net_gex_change_usd": -650000000,
    "net_sign_before": "positive",
    "net_sign_after": "positive",
    "net_sign_changed": false,
    "largest_gross_reductions": [
      { "strike": 665, "excluded_gross_gex_usd": 290000000, "remaining_gross_gex_usd": 320000000, "excluded_share_at_strike_pct": 47.54 }
    ]
  }
}

Key Response Fields

Field Description
currentThe whole eligible chain: gross_gex_usd, net_gex_usd, call_gex_usd, put_gex_usd (USD per 1% move) and contract_count.
excluded_expiryThe same totals for the selected expiry only.
excluding_expiryThe same totals for the chain without it, plus status: available, zero_gross_exposure or no_remaining_contracts.
impactremoved_gross_share_pct = 100 × excluded gross / current gross (null when current gross is zero), retained_gross_share_pct, net_gex_change_usd (remaining net minus current net), net_sign_before / net_sign_after / net_sign_changed, and the top limit strikes in largest_gross_reductions and strongest_remaining_concentrations.
strikes[]Every eligible strike with current, excluded and remaining gross/net GEX and distance from spot.
facts[]Plain-language statements with their supporting values.
pricing_basiscaptured_cached_gamma_current_spot (SPY: cached Greeks at current spot) or qqq_common_anchor_repriced (QQQ: raw quotes repriced at one spot and time).
data_statuspartial in normal operation (open-interest vintage is unknown), stale when an input predates the session freshness cutoff, unavailable when no contract qualifies. reasons[] carry machine codes and excluded-contract counts.
snapshot_idSHA-256 fingerprint of the captured inputs; identical inputs give identical IDs.

Errors

Status Description
400invalid_expiry or invalid_limit (limit outside 1-20)
403Requires Growth plan or higher
404symbol_not_found, expiry_not_found (body lists available_expiries) or no_eligible_contracts
422unsupported_symbol: only SPY and QQQ are supported
503invalid_spot: no finite positive underlying price

About

Expiry impact answers a narrow question: how much of the current SPY or QQQ gamma concentration sits in one expiry? It sums contract-level gamma exposure (gamma × OI × 100 × spot² × 0.01, calls positive and puts negative) for one captured chain, then recomputes the same totals without the selected expiry. Spot, Greeks and open interest are held fixed, so the difference is a sensitivity of today's distribution, not a forecast of the next session's chain or of dealer hedging after expiry.

Gross exposure sums magnitudes, so an expiry can remove a large share of gross gamma while barely moving net. Shares use gross; the net change and sign show what the convention-signed total does. The sign is a convention, not observed dealer inventory. SPY uses cached Greeks at the current spot; QQQ reprices raw quotes at one anchor, as QQQ GEX does. An expiring contract leaves the model at 16:00 ET and early-close expiries are excluded until their clocks are verified.

Every response carries a snapshot_id fingerprint of its inputs, quote and Greek timestamps, rejected-contract counts and data_status. The source does not record when open interest was published, so oi_as_of is null and the status is partial in normal operation.

Replay the same view at a past minute on historical.flashalpha.com with at= (Alpha). Date-only at resolves to 15:55 ET so same-day Greeks stay defined. See historical trader context.

Common Use Cases

  • Size the 0DTE share - how much of today's gross gamma rolls off at the close
  • Check OPEX roll-off - compare the monthly expiry's share during OPEX week with an ordinary week
  • Find strikes that depend on one expiry - largest_gross_reductions ranks the strikes losing the most gross gamma
  • See whether the modeled net sign flips - net_sign_changed shows whether removing the expiry flips the convention-signed total
  • Pair with strike dependency - drill into one wall to see which expiries hold it

Research

This endpoint was replayed at the close of every 2022-2025 SPY and QQQ session. Sessions where the expiring expiry held the largest gross share were followed by calmer next sessions, not wilder ones.

Related reading

Complementary endpoints

Ready to build with FlashAlpha?

Get your free API key and start pulling live options data in 30 seconds.

No credit card required Setup in 60 seconds Secure & reliable