"0DTE straddles are overpriced" is the most repeated claim in options trading since daily expirations took over SPY volume. It is also completely testable, and almost nobody tests it, because doing so needs something awkward: the state of the option chain at a specific minute on thousands of past days. Daily OHLC bars will not do it. You need point-in-time quotes.
So I replayed 193 Wednesday sessions from July 2022 through April 2026, snapshotting the SPY same-day straddle at 10:00 ET and comparing what it implied against what SPY actually did into the close.
Here is the method, the numbers, and a script that reproduces the whole thing.
Method
- Sample: every Wednesday from 2022-07-06 to 2026-04-01 with a SPY 0DTE expiry and complete data. 193 sessions, holidays excluded.
-
Snapshot:
GET /v1/exposure/zero-dte/SPY?at={date}T10:00:00, which returns the ATM straddle price and the implied 1-sigma move built from real minute-level NBBO quotes. - Realized: the 16:00 ET quote mid against the 10:00 spot. That is the move the 10:00 straddle actually had to survive.
- Benchmarks: this is the part people skip. A fairly priced 1-sigma move contains the close about 68.3% of the time, and the median absolute move of a normal variable is about 0.674 sigma. Richness gets measured against those numbers, not against zero.
That last point matters. A straddle that "contains the close 71% of the time" sounds like nothing until you know the fair-value number is 68.3%.
The headline numbers
| Metric | Measured | If fairly priced |
|---|---|---|
| Close inside the 10:00 implied 1-sigma band | 71.0% of sessions | ~68.3% |
| Sessions where realized move exceeded implied 1-sigma | 25.9% | ~31.7% |
| Median of realized move / implied move | 0.589 | ~0.674 |
| Median implied 1-sigma move (10:00 ET) | 0.72% of spot | - |
| Median absolute realized move (10:00 to close) | 0.37% | - |
Every line points the same way. The 10:00 straddle priced in slightly more movement than SPY delivered. Realized moves ran roughly 13% below the fair-value benchmark (0.589 against 0.674), the band held about 3 points more often than chance, and breaches happened about 6 points less often than fair pricing implies.
That is a volatility risk premium, alive and measurable at the daily horizon. It is also small. Anyone selling you a "0DTE is free money" course is describing a 13% markup.
Is the edge stable?
The obvious follow-up: 0DTE volume exploded over this window. Did the premium get arbitraged away?
| Year | Sessions | Hit rate (inside 1-sigma) | Median implied | Median abs realized |
|---|---|---|---|---|
| 2022 (H2) | 26 | 69.2% | 1.17% | 0.73% |
| 2023 | 52 | 69.2% | 0.73% | 0.49% |
| 2024 | 50 | 70.0% | 0.60% | 0.32% |
| 2025 | 52 | 71.2% | 0.62% | 0.39% |
| 2026 (Q1) | 13 | 84.6% | 0.71% | 0.26% |
No. The hit rate sits in a tight 69-71% band across four genuinely different vol regimes: the 2022 bear, the 2023-24 grind, the 2025 tariff shock. The absolute level of implied vol moved a lot. The markup did not.
The caveat that pays for everything
The worst session in the sample was April 9, 2025. Here is the actual snapshot, unedited:
{
"symbol": "SPY",
"underlying_price": 499.84,
"as_of": "2025-04-09T10:00:00",
"time_to_close_hours": 6,
"expected_move": {
"implied_1sd_dollars": 17.5691,
"implied_1sd_pct": 3.5149,
"straddle_price": 13.47,
"atm_iv": 1.290367,
"upper_bound": 516.7198,
"lower_bound": 482.9602
}
}
A 3.51% one-sigma move. Already enormous, ATM IV at 129%, mid tariff panic. The market was not asleep.
SPY closed at 543.44 on the tariff-pause headline. That is +8.72%, roughly 2.5x the implied move, and about 27 points above the upper bound the chain had priced at 10:00.
A naked short straddle sized to "collect the premium" that morning gave back weeks of harvest in one afternoon.
This is the whole seller's bargain in one line: about 74% of sessions the implied move is too big, about 26% it is too small, and a handful of those are catastrophically too small. The premium exists precisely because someone has to hold that tail. Selling it naked is a leverage decision, not an edge decision. Defined-risk structures (iron flies, condors) monetize the same overpricing with a worst case you survive.
Reproduce it
Two calls per session. First the 10:00 snapshot, then the close:
curl -H "X-Api-Key: $FLASHALPHA_KEY" \
"https://historical.flashalpha.com/v1/exposure/zero-dte/SPY?at=2025-04-09T10:00:00"
curl -H "X-Api-Key: $FLASHALPHA_KEY" \
"https://historical.flashalpha.com/v1/stockquote/SPY?at=2025-04-09T16:00:00"
The full study is about thirty lines:
import requests
import pandas as pd
HEADERS = {"X-Api-Key": "YOUR_API_KEY"}
BASE = "https://historical.flashalpha.com/v1"
def session_row(date: str):
zd = requests.get(
f"{BASE}/exposure/zero-dte/SPY",
params={"at": f"{date}T10:00:00"},
headers=HEADERS,
).json()
if zd.get("no_zero_dte"):
return None # no same-day expiry, skip
close = requests.get(
f"{BASE}/stockquote/SPY",
params={"at": f"{date}T16:00:00"},
headers=HEADERS,
).json()
spot_10 = zd["underlying_price"]
implied_pct = zd["expected_move"]["implied_1sd_pct"]
realized_pct = (close["mid"] - spot_10) / spot_10 * 100
return {
"date": date,
"implied_pct": implied_pct,
"realized_pct": realized_pct,
"ratio": abs(realized_pct) / implied_pct,
"inside_band": abs(realized_pct) <= implied_pct,
}
dates = pd.date_range("2022-07-06", "2026-04-01", freq="W-WED").strftime("%Y-%m-%d")
df = pd.DataFrame([r for d in dates if (r := session_row(d))])
print(f"sessions: {len(df)}")
print(f"hit rate: {df.inside_band.mean():.1%} (fair value 68.3%)")
print(f"median ratio: {df.ratio.median():.3f} (fair value 0.674)")
print(f"worst miss: {df.ratio.max():.2f}x on {df.loc[df.ratio.idxmax(), 'date']}")
The interesting variations are one-line edits:
- Change
T10:00:00toT11:30:00orT14:00:00and measure how the premium decays across the session.time_to_close_hoursis computed from your timestamp, so the maths stays consistent. - Split by
vol_context.vixto see whether the markup is regime-dependent. - Swap
W-WEDforBto cover every business day instead of one per week.
Honest limitations
Wednesdays only, so one session per week. That avoids weekday-mix effects but samples less than it could. The close is measured against the 10:00 spot, not the intraday high and low that a gamma scalper actually cares about. Quote mids, no fees or slippage. 2026 is a partial year, and its 84.6% hit rate is 13 sessions, so read it as noise until it is not.
FOMC Wednesdays stay in the sample. Worth noting on its own: straddles on Fed days priced roughly double the neighbouring weeks, and the market largely respected them.
The conclusion
The 0DTE volatility risk premium is real, stable, and small. The market pays about a 13% markup on daily movement, session after session, year after year, and that markup is fully earned by whoever eats the April 9ths.
If you trade this, the practical output is a number rather than a slogan: the implied move is wide about 74% of the time, and the way to collect that without donating it back is defined risk and honest sizing.
Rerun it, change the snapshot hour, slice it by VIX regime. Every endpoint replays back to January 2017.
Originally published at flashalpha.com. The historical replay endpoints are documented here.
Top comments (0)