Help us double down on what's working, instead of guessing. Takes 5 seconds, totally optional.
0DTE Pin and Range Probability: Calibrated Odds for Today's Expiry
A 0-100 pin score tells you a magnet is strong; it does not tell you the odds. The FlashAlpha 0DTE snapshot adds a probabilities block - a calibrated pin probability plus the chance price closes inside 1-sigma and 2-sigma by the close - each tagged with its calibration method. This guide documents the math, how to turn the odds into iron condor wings and short strikes, and how to compare them to option premium for edge. Growth plan.
If you want a 0DTE pin probability, the odds price closes inside the expected move today, or a way to price an iron condor's win rate from live dealer positioning, the probabilities block in GET /v1/flow/zero-dte/snapshot/{symbol} is the answer. It sits inside the live 0DTE flow family — the full surface is in the pillar, The Live 0DTE Flow API.
Read this first. These are calibrated model probabilities, not backtested frequencies. The pin probability is a closed-form heuristic (tagged heuristic_v1); the range probabilities are a normal-distribution approximation (normal_cdf_v1). They are a consistent, structure-aware estimate of the odds — useful for sizing and comparison — not a guarantee. The calibration_method tag exists precisely so a future historically-fitted model can replace them without breaking your integration.
The pin probability starts from a distance-decay kernel and scales it by the two things that actually make a pin hold — the dealer regime and how concentrated open interest is at the magnet:
pin = clamp( exp( -d / (σ · √t) ) · regime_boost · conc_boost , 0 , 0.95 )
d = |spot − magnet| / spot (fractional distance to magnet)
σ = remaining 1σ move, as a fraction (shrinks through the day)
t = clamp(hours_to_close / 6.5, 0, 1)
regime_boost = 1.20 if positive_gamma, 0.70 if negative_gamma, else 1.00
conc_boost = 1 + clamp((top3_OI_concentration% − 30) / 100, −0.30, +0.50)
The intuition reads straight off the formula:
Closer to the magnet → higher odds. As d shrinks toward zero, the kernel rises toward 1.
Less room left to move → higher odds. Both σ and t shrink into the close, tightening the denominator, so a pin that survives to the final hour gets more probable, not less.
Positive gamma helps, negative gamma hurts. A long-gamma dealer book damps moves (boost 1.20); a short-gamma book amplifies them and works against the pin (0.70).
Concentrated OI helps. When the top-3 strikes hold a big share of open interest, there is real hedging mass to hold price (boost up to 1.50); a diffuse book pulls it down.
Capped at 0.95. The model never claims certainty.
How the Range Probabilities Are Built
The range odds are the clean part: the probability price closes inside spot ± k·σ under a normal distribution, which is the standard 2Φ(k) − 1.
range_kσ = 2 · Φ(k) − 1
k = 1 → ≈ 0.6827 (≈ 68%)
k = 2 → ≈ 0.9545 (≈ 95%)
low = spot − k · remaining_1σ_dollars
high = spot + k · remaining_1σ_dollars
The number itself is the textbook normal value; what makes it useful intraday is that remaining_1σ_dollars is the untraded portion of the expected move — it shrinks as the session burns time, so the band tightens around spot through the day. The low/high bounds are exactly the strikes you would anchor a range trade to.
Turning Odds into Strikes and Edge
Three concrete uses:
Size a pin trade by its probability, not its score. A pin score of 70 with pin.value 0.83 is a different bet from the same score at 0.45 (further from the magnet, or a negative-gamma drag). Scale position size to the probability.
Set iron-condor short strikes at the σ band. The range_1sigma.low/high bounds are a natural place for the short legs of a condor: roughly a 68% chance price finishes inside them. Want a higher win rate? Sell at the 2σ bounds (~95%) for less premium.
Compare the odds to the option premium for edge. If the market is pricing a wider implied move than the model's range band implies — or paying you more for a short strike than its breach probability warrants — that gap is the edge. The probability block is the model side of that comparison.
from flashalpha import FlashAlpha
fa = FlashAlpha("YOUR_KEY")
snap = fa.flow_zero_dte_snapshot("SPY")
if snap.get("body") is None:
raise SystemExit(snap.get("message", "no 0DTE session"))
prob = snap["probabilities"]
pin = prob["pin"]
r1 = prob["range_1sigma"]
print(f"Pin prob: {pin['value']:.0%} ({pin['inputs_summary']})")
print(f"1σ range: {r1['value']:.1%} close inside [{r1['low']:.2f}, {r1['high']:.2f}]")
# Iron condor: short legs at the 1σ band, ~68% inside
print(f"Condor shorts ~ {r1['low']:.0f} put / {r1['high']:.0f} call")
# Only take the pin trade above your probability floor
if pin["value"] >= 0.60:
print("Pin probability clears the 60% floor — size the pin trade")
# The probabilities block rides inside the snapshot response
curl -H "X-Api-Key: YOUR_KEY" \
"https://lab.flashalpha.com/v1/flow/zero-dte/snapshot/SPY" | jq '.probabilities'
$ probabilities is a field on the snapshot — no separate call needed
Why Every Result Is Tagged
The calibration_method string is not decoration. The pin model today is heuristic_v1 and the range model is normal_cdf_v1; a future release will fit the pin probability to historical 0DTE outcomes and ship it as historical_v1. Because every number carries its method, that swap is non-breaking — your code keeps reading pin.value, and you can branch on the method if you want to treat a historically-calibrated number differently from a heuristic one. Pin to the method you tested against.
API Access and Pricing
The probabilities block is part of GET /v1/flow/zero-dte/snapshot/{symbol}, on the Growth plan and higher — it rides inside every snapshot, no separate call.
Yes. The probabilities block in GET /v1/flow/zero-dte/snapshot/{symbol} returns a calibrated pin probability — the estimated chance price closes near the magnet strike — alongside the odds of closing inside the ±1σ and ±2σ bands. The pin number is a structure-aware heuristic that factors distance to the magnet, remaining expected move, time to close, dealer regime, and OI concentration. It is on the Growth plan.
They are calibrated model probabilities, not historical frequencies. The pin number is a closed-form heuristic tagged heuristic_v1; the range numbers are a normal-distribution approximation tagged normal_cdf_v1. They give a consistent, structure-aware estimate you can size and price against. Each result carries its calibration_method so a future historically-fitted model (historical_v1) can replace it without breaking your code.
The range_1sigma low and high bounds are the price band with roughly a 68% chance of containing the close, so they are a natural place for the short legs of an iron condor. For a higher win rate and less premium, sell at the range_2sigma bounds (around 95%). Then compare the credit the market pays against the breach probability the model implies — when the premium overpays the odds, that is your edge.
Because both the remaining expected move and the time factor shrink as the session burns down. In the pin kernel, those two terms form the denominator, so as they fall the exponent rises toward 1 — a pin that is still holding with an hour to go has less room to escape than the same pin at noon. The model encodes that with a time factor scaled to a 6.5-hour session, clamped between 0 and 1.
The probabilities block is part of the 0DTE snapshot endpoint, so it is on the Growth plan (from $239/mo, 2,500 requests/day) and Alpha (from $1,199/mo, unlimited). There is no separate endpoint — it rides inside every snapshot response. Free and Basic do not include the flow family.