DEV Community

tomasz dobrowolski
tomasz dobrowolski

Posted on • Originally published at flashalpha.com

0DTE Options Scanner API — Screen Same-Day Contracts by Delta, OI, and Gamma Regime

0DTE options have become the dominant force in intraday market structure. On any given day, same-day expiry contracts on SPY alone can account for 40–50% of total options volume. The problem: scanning for actionable 0DTE setups across dozens of symbols requires pulling chains, filtering by delta and OI, checking gamma regime, and doing it all before the contracts decay to nothing.

I built this with one POST request.

Scanner vs endpoint — different questions

FlashAlpha has a dedicated 0DTE analytics endpoint that returns pin risk, expected move, and gamma regime for one symbol at a time. That's the right tool when you know which name you're trading.

A scanner answers a different question: which symbols have 0DTE setups worth looking at right now?

Instead of looping through 20+ symbols and merging client-side, one screener POST returns only the symbols — and only the contracts within those symbols — that match your criteria.

The key: cascading filters

When you combine stock-level, expiry-level, and contract-level conditions inside an AND group, the server cascades the filter downward. Non-matching children get pruned at each level, and symbols with zero survivors are dropped entirely.

For 0DTE, you set expiries.days_to_expiry = 0 to isolate same-day, then layer contract-level conditions on top:

{
  "filters": {
    "op": "and",
    "conditions": [
      { "field": "expiries.days_to_expiry", "operator": "eq",  "value": 0 },
      { "field": "contracts.type",          "operator": "eq",  "value": "C" },
      { "field": "contracts.delta",         "operator": "gte", "value": 0.3 },
      { "field": "contracts.oi",            "operator": "gte", "value": 1000 }
    ]
  },
  "select": ["*"]
}
Enter fullscreen mode Exit fullscreen mode

The response contains, for every symbol in your universe: only the 0DTE expiry, only the call contracts, only the ones clearing the delta and OI floor. No other expiries, no puts, no low-delta noise. The response is already shaped like the answer.

Five 0DTE scanner recipes

1. 0DTE call seller (positive gamma only)

{
  "filters": {
    "op": "and",
    "conditions": [
      { "field": "regime",                   "operator": "eq",  "value": "positive_gamma" },
      { "field": "expiries.days_to_expiry",  "operator": "eq",  "value": 0 },
      { "field": "contracts.type",           "operator": "eq",  "value": "C" },
      { "field": "contracts.delta",          "operator": "gte", "value": 0.3 },
      { "field": "contracts.oi",             "operator": "gte", "value": 1000 }
    ]
  },
  "select": ["*"]
}
Enter fullscreen mode Exit fullscreen mode

The regime = positive_gamma condition means you're only selling calls where dealers are dampening moves, not amplifying them. Rich theta, friendly regime, liquid contracts.

2. 0DTE put scanner

{
  "filters": {
    "op": "and",
    "conditions": [
      { "field": "expiries.days_to_expiry",  "operator": "eq",      "value": 0 },
      { "field": "contracts.type",           "operator": "eq",      "value": "P" },
      { "field": "contracts.delta",          "operator": "between", "value": [-0.5, -0.2] },
      { "field": "contracts.volume",         "operator": "gte",     "value": 500 }
    ]
  },
  "select": ["*"]
}
Enter fullscreen mode Exit fullscreen mode

Finds 0DTE puts that are actually trading (volume ≥ 500) in the 20–50 delta range. Useful for protective puts or speculative directional bets on names showing intraday weakness.

3. Negative-gamma 0DTE scanner (amplified move risk)

{
  "filters": {
    "op": "and",
    "conditions": [
      { "field": "regime",                   "operator": "eq", "value": "negative_gamma" },
      { "field": "expiries.days_to_expiry",  "operator": "eq", "value": 0 }
    ]
  },
  "sort":   [{ "field": "net_gex", "direction": "asc" }],
  "select": ["symbol", "price", "regime", "net_gex", "gamma_flip", "zero_dte_net_gex", "zero_dte_pct_of_total"]
}
Enter fullscreen mode Exit fullscreen mode

Surfaces names where 0DTE dealer gamma is negative, sorted by most-negative GEX. These are the names where intraday moves will be amplified by dealer hedging. Avoid selling premium here — or use them as breakout candidates where you buy directional 0DTE options and ride the gamma amplification.

4. ATM 0DTE straddle scanner

{
  "filters": {
    "op": "and",
    "conditions": [
      { "field": "expiries.days_to_expiry",  "operator": "eq",      "value": 0 },
      { "field": "contracts.delta",          "operator": "between", "value": [-0.55, 0.55] },
      { "field": "contracts.oi",             "operator": "gte",     "value": 2000 },
      { "field": "atm_spread_pct",           "operator": "lte",     "value": 0.03 }
    ]
  },
  "select": ["*"],
  "limit": 10
}
Enter fullscreen mode Exit fullscreen mode

The atm_spread_pct ≤ 0.03 stock-level filter prunes names with bad microstructure before the contract-level cascade runs. This is your 0DTE iron condor scanner: find which names have the liquidity for a same-day structure.

5. 0DTE + high GEX concentration

{
  "filters": {
    "op": "and",
    "conditions": [
      { "field": "zero_dte_pct_of_total", "operator": "gte", "value": 0.3 },
      { "field": "expiries.days_to_expiry", "operator": "eq",  "value": 0 },
      { "field": "contracts.oi",            "operator": "gte", "value": 500 }
    ]
  },
  "sort":   [{ "field": "zero_dte_pct_of_total", "direction": "desc" }],
  "select": ["symbol", "price", "zero_dte_pct_of_total", "zero_dte_net_gex", "regime"]
}
Enter fullscreen mode Exit fullscreen mode

Surfaces names where 0DTE options account for 30%+ of total gamma. These are the most "0DTE-driven" symbols today — pin risk is elevated, gamma acceleration is concentrated, and theta decay is extreme.

Python workflow: scan then drill

The pattern that works best: screener finds candidates, then the per-symbol 0DTE endpoint gives you pin risk and expected move for the ones you want to trade.

from flashalpha import FlashAlpha

fa = FlashAlpha("YOUR_API_KEY")

# Step 1: scan for 0DTE call-selling candidates
scan = fa.screener(
    filters={
        "op": "and",
        "conditions": [
            {"field": "regime",                  "operator": "eq",  "value": "positive_gamma"},
            {"field": "expiries.days_to_expiry",  "operator": "eq",  "value": 0},
            {"field": "contracts.type",           "operator": "eq",  "value": "C"},
            {"field": "contracts.delta",          "operator": "gte", "value": 0.3},
            {"field": "contracts.oi",             "operator": "gte", "value": 1000},
        ],
    },
    select=["symbol", "price", "regime", "zero_dte_net_gex"],
    limit=5,
)

# Step 2: drill into top candidates
for row in scan["data"]:
    sym = row["symbol"]
    dte = fa.zero_dte(sym)
    print(f"\n{sym}:")
    print(f"  Pin risk:      {dte['pin_risk']['score']}/100")
    print(f"  Expected move: {dte['expected_move']['range_1_sigma']}")
    print(f"  Regime:        {dte['gamma_regime']['regime']}")
Enter fullscreen mode Exit fullscreen mode

Two requests instead of N. The screener finds the best candidates; the 0DTE endpoint gives you pin risk, expected move, and dealer hedging detail for each one.

SDK support

The screener method is available in all five FlashAlpha SDKs (Python, JavaScript, .NET, Java, Go). No need to build the HTTP POST yourself.

# Python
fa.screener(filters=..., select=...)
Enter fullscreen mode Exit fullscreen mode
// JavaScript
fa.screener({ filters, select })
Enter fullscreen mode Exit fullscreen mode
// .NET
await client.ScreenerAsync(new ScreenerRequest { ... })
Enter fullscreen mode Exit fullscreen mode

Full spec: Live Screener docs. More recipes: Screener Cookbook. Per-symbol 0DTE analytics: 0DTE endpoint.

The Live Screener is part of the FlashAlpha Real-Time Options Analytics API. Growth gives you 20 symbols with cascading 0DTE filters. Alpha unlocks ~248 symbols, formulas, and strategy scores. Free tier at 5 requests/day. Compare plans.

Top comments (0)