Zero-DTE API: Complete Guide to the 0DTE Analytics Endpoint | FlashAlpha

Zero-DTE API: Complete Guide to the 0DTE Analytics Endpoint

Complete guide to the FlashAlpha Zero-DTE API endpoint. Every field explained - gamma regime, expected move, pin risk scoring, dealer hedging estimates, theta decay acceleration, volatility context, flow data, key levels, and per-strike breakdown. Python examples included.

T
Tomasz Dobrowolski Quant Engineer
Mar 20, 2026
19 min read
0DTE API GammaExposure PinRisk DealerHedging IntradayTrading

The Endpoint

GET https://lab.flashalpha.com/v1/exposure/zero-dte/{symbol}

Requires the Growth plan ($239/mo) or higher. Auth via X-Api-Key header. One parameter: the underlying symbol (SPY, QQQ, SPX, TSLA, etc.).

import requests

resp = requests.get(
    "https://lab.flashalpha.com/v1/exposure/zero-dte/SPY",
    headers={"X-Api-Key": "YOUR_API_KEY"}
)
data = resp.json()

The response contains 10 top-level sections. Let's walk through each one.

1. Context - Time and Market State

Every 0DTE decision depends on where you are in the trading day. These fields tell you:

FieldTypeDescription
underlying_pricenumberCurrent spot price of the underlying
expirationstringToday's 0DTE expiry date (yyyy-MM-dd)
market_openboolWhether the market is currently open
time_to_close_hoursnumberHours until 4:00 PM ET - the most important 0DTE context variable
time_to_close_pctnumberPercentage of trading day elapsed (0 = open, 100 = close)
print(f"SPY @ ${data['underlying_price']}")
print(f"Time to close: {data['time_to_close_hours']:.1f}h ({data['time_to_close_pct']:.0f}% elapsed)")

2. Gamma Regime

The regime object tells you whether dealers are suppressing or amplifying moves - the single most important intraday signal.

FieldDescription
regime.labelpositive_gamma (dealers dampen moves), negative_gamma (dealers amplify), or undetermined
regime.gamma_flipPrice where 0DTE net GEX crosses zero - the key intraday pivot
regime.spot_vs_flip"above" or "below" the flip point
regime.spot_to_flip_pctDistance from spot to gamma flip as a percentage
Trading Rule

Above the gamma flip: expect range-bound, mean-reverting action - fade moves toward high-GEX strikes. Below the flip: expect trending, volatile moves - trade breakouts, not mean reversion.

regime = data["regime"]
print(f"Regime: {regime['label']}")
print(f"Gamma flip: ${regime['gamma_flip']}")
print(f"Spot is {regime['spot_vs_flip']} flip by {regime['spot_to_flip_pct']:.2f}%")

3. Exposure Aggregates

The exposures object gives you the 0DTE Greek exposure totals and how they compare to the full options chain.

FieldDescription
net_gexNet 0DTE gamma exposure in dollars
net_dexNet 0DTE delta exposure
net_vexNet 0DTE vanna exposure
net_chexNet 0DTE charm exposure
pct_of_total_gex0DTE GEX as % of full-chain GEX - above 50% means 0DTE dominates intraday
total_chain_net_gexFull-chain net GEX for comparison
exp = data["exposures"]
pct = exp["pct_of_total_gex"]
print(f"0DTE Net GEX: ${exp['net_gex']:,.0f}")
print(f"0DTE accounts for {pct:.1f}% of total GEX")

if pct > 50:
    print("→ 0DTE dominates  -  use 0DTE levels for intraday trading")
else:
    print("→ Full chain dominates  -  check /v1/exposure/levels for broader levels")
Per-Strike GEX Calculation $$ GEX_k = \sum_{j \in \text{0DTE}} \Gamma_{k,j} \times OI_{k,j} \times 100 \times S^2 $$

4. Expected Move

The expected_move object gives you the market-implied range for the rest of the day - it shrinks in real-time as the close approaches.

FieldDescription
implied_1sd_dollarsFull-day 1σ expected move (from open)
implied_1sd_pctSame as above, in percent
remaining_1sd_dollarsRemaining 1σ expected move from now until close
remaining_1sd_pctSame as above, in percent
upper_boundCurrent price + remaining 1σ move
lower_boundCurrent price − remaining 1σ move
straddle_priceATM 0DTE straddle mid - the market's direct expected move price
atm_iv0DTE at-the-money implied volatility (decimal)
Remaining Expected Move $$ E[\text{move}] = S \cdot \sigma_{\text{ATM}} \cdot \sqrt{\frac{t_{\text{remaining}}}{252}} $$
em = data["expected_move"]
print(f"Expected range: ${em['lower_bound']:.2f} - ${em['upper_bound']:.2f}")
print(f"Remaining 1σ: ±${em['remaining_1sd_dollars']:.2f} ({em['remaining_1sd_pct']:.2f}%)")
print(f"Straddle price: ${em['straddle_price']:.2f}")

5. Pin Risk

The pin_risk object quantifies the probability of price being "pinned" to a high-OI strike near the close.

FieldDescription
magnet_strikeStrike with strongest gravitational pull
magnet_gexGEX at the magnet strike
distance_to_magnet_pctHow far spot is from the magnet (percentage)
pin_score0-100 composite score - above 70 is high conviction
max_painStrike minimizing total option holder intrinsic value
oi_concentration_top3_pctWhat percentage of total 0DTE OI sits in the top 3 strikes

The pin score composites four factors:

  • OI Concentration (30%) - top 3 strikes' share of total 0DTE OI
  • Magnet Proximity (25%) - how close spot is to the highest-GEX strike
  • Time Remaining (25%) - pin risk increases as expiration approaches
  • Gamma Magnitude (20%) - higher gamma = stronger hedging force toward the pin
Max Pain $$ K^* = \arg\min_{K} \left[ \sum_{i} OI_i^C \cdot \max(S - K_i, 0) + \sum_{j} OI_j^P \cdot \max(K_j - S, 0) \right] $$
pin = data["pin_risk"]
print(f"Magnet Strike: ${pin['magnet_strike']}")
print(f"Pin Score: {pin['pin_score']}/100")
print(f"Max Pain: ${pin['max_pain']}")
print(f"Distance to magnet: {pin['distance_to_magnet_pct']:.2f}%")
print(f"Top 3 OI concentration: {pin['oi_concentration_top3_pct']}%")

if pin["pin_score"] > 70 and data["time_to_close_hours"] < 2:
    print("→ HIGH PIN RISK  -  price likely gravitates to magnet strike")

6. Dealer Hedging Estimates

The hedging object estimates how many shares dealers must trade to delta-hedge their 0DTE positions for various price move scenarios.

FieldDescription
spot_up_half_pctHedging for a +0.5% move
spot_down_half_pctHedging for a −0.5% move
spot_up_1pctHedging for a +1.0% move
spot_down_1pctHedging for a −1.0% move

Each scenario returns dealer_shares_to_trade, direction (buy/sell), and notional_usd. In positive gamma, dealers sell into rallies and buy dips (liquidity providers). In negative gamma, they chase price (liquidity takers).

for scenario, label in [("spot_up_half_pct", "+0.5%"), ("spot_down_half_pct", "-0.5%"),
                         ("spot_up_1pct", "+1.0%"), ("spot_down_1pct", "-1.0%")]:
    h = data["hedging"][scenario]
    print(f"If SPY moves {label}: dealers {h['direction']} {abs(h['dealer_shares_to_trade']):,} shares (${abs(h['notional_usd']):,.0f})")

7. Theta Decay & Gamma Acceleration

The decay object captures the non-linear time decay of 0DTE options - theta bleeds slowly in the morning and accelerates dramatically into the close.

FieldDescription
net_theta_dollarsTotal 0DTE theta in dollars
theta_per_hour_remainingTheta divided by hours remaining - accelerates as denominator shrinks
gamma_acceleration0DTE ATM gamma / 7DTE ATM gamma - typically 2-5×, can hit 10×+ near close
charm_regimeE.g. time_decay_dealers_buy - direction of charm-driven hedging
charm_descriptionHuman-readable charm interpretation
ATM Gamma Acceleration $$ \Gamma_{\text{ATM}} \propto \frac{1}{\sqrt{T}} \quad \Longrightarrow \quad \frac{\Gamma_{0\text{DTE}}}{\Gamma_{7\text{DTE}}} \approx \sqrt{\frac{7 \times 6.5}{t_{\text{remaining}}}} $$
decay = data["decay"]
print(f"Net Theta: ${decay['net_theta_dollars']:,.0f}")
print(f"Theta/Hour: ${decay['theta_per_hour_remaining']:,.0f}")
print(f"Gamma Acceleration: {decay['gamma_acceleration']}x vs 7DTE")
print(f"Charm: {decay['charm_description']}")
Optimal Premium Selling Window

Enter when gamma_acceleration is above 2× but time_to_close_hours is still above 2 - you capture the steepest part of the decay curve while leaving enough time for mean reversion to work.

8. Volatility Context

The vol_context object compares 0DTE implied volatility to longer-dated vol and vanna exposure.

FieldDescription
zero_dte_atm_iv0DTE ATM implied volatility (%)
seven_dte_atm_iv7DTE ATM implied volatility (%)
iv_ratio_0dte_7dteRatio: <1.0 = 0DTE is "cheap"; >1.0 = event premium
vixCurrent VIX level
vanna_exposure0DTE vanna exposure in dollars
vanna_interpretationE.g. vol_up_dealers_sell - what happens if vol spikes
vc = data["vol_context"]
ratio = vc["iv_ratio_0dte_7dte"]
print(f"0DTE IV: {vc['zero_dte_atm_iv']}% | 7DTE IV: {vc['seven_dte_atm_iv']}%")
print(f"Ratio: {ratio:.2f}  -  {'EVENT PREMIUM' if ratio > 1.0 else 'normal'}")
print(f"Vanna: {vc['vanna_interpretation']}")

9. Flow Data

The flow object provides volume and open interest for 0DTE contracts.

FieldDescription
total_volume / call_volume / put_volume0DTE volume breakdown
total_oi / call_oi / put_oi0DTE open interest breakdown
pc_ratio_volumePut/call ratio by volume
pc_ratio_oiPut/call ratio by open interest
volume_to_oi_ratio>1.0 = heavy day-trading (intraday flow exceeds overnight positioning)

10. Key Levels & Per-Strike Breakdown

The levels object identifies the most important intraday support and resistance from 0DTE positioning.

FieldDescription
call_wall / call_wall_gexStrike with highest call GEX - intraday resistance
put_wall / put_wall_gexStrike with highest put GEX - intraday support
highest_oi_strikeStrike with the most total open interest
max_positive_gammaStrike with highest positive net gamma
max_negative_gammaStrike with highest negative net gamma

The strikes array provides per-strike detail for contracts within strike_range of spot. Each strike includes:

{
    "strike": 590,
    "call_gex": 450000000, "put_gex": -380000000, "net_gex": 70000000,
    "call_dex": 12500000, "put_dex": -15000000, "net_dex": -2500000,
    "call_oi": 25000, "put_oi": 30000,
    "call_volume": 15000, "put_volume": 12000,
    "call_iv": 0.18, "put_iv": 0.19,
    "call_delta": 0.50, "put_delta": -0.50,
    "call_gamma": 0.025, "put_gamma": 0.025,
    "call_theta": -1.0, "put_theta": -1.0
}

Putting It All Together - Intraday Signal Builder

Combine the response fields into a single decision framework:

import requests

def get_0dte_signal(symbol, api_key):
    resp = requests.get(
        f"https://lab.flashalpha.com/v1/exposure/zero-dte/{symbol}",
        headers={"X-Api-Key": api_key}
    )
    d = resp.json()

    if d.get("no_zero_dte"):
        return {"signal": "no_data", "reason": d["message"]}

    regime = d["regime"]["label"]
    pin_score = d["pin_risk"]["pin_score"]
    pct_total = d["exposures"]["pct_of_total_gex"]
    hours_left = d["time_to_close_hours"]

    # High-conviction pin setup
    if pin_score > 70 and hours_left < 2 and regime == "positive_gamma":
        return {
            "signal": "PIN_LIKELY",
            "target": d["pin_risk"]["magnet_strike"],
            "confidence": pin_score,
            "range": [d["expected_move"]["lower_bound"], d["expected_move"]["upper_bound"]],
            "action": "Fade moves toward magnet strike. Sell premium."
        }

    # Negative gamma breakout risk
    if regime == "negative_gamma" and pct_total > 50:
        return {
            "signal": "BREAKOUT_RISK",
            "flip": d["regime"]["gamma_flip"],
            "hedging_at_1pct": d["hedging"]["spot_down_1pct"]["notional_usd"],
            "action": "Trade breakouts, not mean reversion. Dealers amplify moves."
        }

    # Default: range-bound with decay
    return {
        "signal": "RANGE_BOUND",
        "walls": [d["levels"]["put_wall"], d["levels"]["call_wall"]],
        "theta_per_hour": d["decay"]["theta_per_hour_remaining"],
        "action": "Sell premium between put wall and call wall."
    }

signal = get_0dte_signal("SPY", "YOUR_API_KEY")
print(signal)

When There Is No 0DTE Expiry

Not every symbol has 0DTE every day. SPY has 0DTE every trading day; FlashAlpha's SPX 0DTE coverage is limited (it returns no_zero_dte on days SPX has no same-day expiry). When there is no 0DTE expiry today, the API returns:

{
    "symbol": "SPY",
    "no_zero_dte": true,
    "message": "No 0DTE expiry for SPY today (Tuesday). Next expiry: 2026-03-18.",
    "next_zero_dte_expiry": "2026-03-18"
}

Always check for no_zero_dte before accessing other fields.

Access & Pricing

PlanPriceRequests/Day0DTE Access
Starter (Free)$05No
Basic$63/mo100No
Growth$239/mo2,500Yes
Alpha$1,199/moUnlimitedYes

View Pricing & Sign Up Full API Reference Try It in the Playground

Related Reading

The zero-DTE endpoint gives you everything needed to trade same-day expirations with a quantitative edge: gamma regime for direction bias, pin risk for convergence plays, expected move for strike selection, dealer hedging for flow context, and theta acceleration for timing. One API call, one JSON response, all updated in real-time. See the full API reference or try it in the playground.

Live Market Pulse

Get fast visibility into market shifts with full-chain analytics over low-latency REST and MCP polling.

Intelligent Screening

Screen millions of option pairs per second using your custom EV rules, filters, and setups.

Export-Ready

Export structured signals to your own execution stack or broker integration - FlashAlpha delivers the analytics, you keep control of order routing.

Join the Community

Discord

Engage in real time conversations with us!

Twitter / X

Follow us for real-time updates and insights!

GitHub

Explore our open-source SDK, examples, and analytics resources!