How the at-the-money call finished, June 2026 expiries
Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-09-18, from Are 0DTE Options High Risk? What the Greeks Say.
| outcome | expiries |
|---|---|
| 1. Finished at or near zero (5% of the premium or less) | 10 |
| 2. Lost more than half | 1 |
| 3. Lost up to half | 5 |
| 4. Gained, less than doubled | 1 |
| 5. Doubled or better | 4 |
- Rows × columns
- 5 × 2
- Computed
- Completeness
- No missing values
- Source
- US exchange, SIP and OPRA market data
- Licence
- Strasmore terms · free, no signup
What each column holds
| Column | Type | Range | Notes |
|---|---|---|---|
outcome |
text | 5 distinct values | |
expiries |
number | 1 to 10 |
Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.
Run it yourself
This is the exact query behind the result above. Change a ticker, a date or a column and run it against the warehouse — no account, no key. The no-signup tier is smaller than the one this page was computed on; a query that reaches past it comes back saying which plan runs it.
WITH spy_by_day AS
(
SELECT
toDate(date) AS d,
medianExact(toFloat64(underlying_close)) AS spot
FROM global_markets.options_greeks
WHERE underlying_symbol = 'SPY'
AND date >= toDate('2026-06-01')
AND date < toDate('2026-07-01')
AND underlying_close > 0
GROUP BY d
),
last_sessions AS
(
SELECT
toDate(expiration_date) AS exp_date,
max(toDate(date)) AS prior_session
FROM global_markets.options_greeks
WHERE underlying_symbol = 'SPY'
AND expiration_date >= toDate('2026-06-01')
AND expiration_date < toDate('2026-07-01')
AND date >= toDate('2026-05-22')
AND date < expiration_date
AND volume > 0
GROUP BY exp_date
),
atm AS
(
SELECT
toDate(g.expiration_date) AS exp_date,
argMin(toFloat64(g.strike_price), abs(toFloat64(g.strike_price) - toFloat64(g.underlying_close))) AS strike,
argMin(toFloat64(g.option_close), abs(toFloat64(g.strike_price) - toFloat64(g.underlying_close))) AS premium_before
FROM global_markets.options_greeks AS g
INNER JOIN last_sessions AS ls
ON ls.exp_date = toDate(g.expiration_date) AND ls.prior_session = toDate(g.date)
WHERE g.underlying_symbol = 'SPY'
AND lower(toString(g.option_type)) IN ('call', 'c')
AND g.date >= toDate('2026-05-22')
AND g.date < toDate('2026-07-01')
AND g.volume > 0
AND g.option_close > 0
GROUP BY exp_date
),
outcomes AS
(
SELECT
a.exp_date AS exp_date,
greatest(s.spot - a.strike, 0.0) / a.premium_before AS premium_ratio
FROM atm AS a
INNER JOIN spy_by_day AS s
ON s.d = a.exp_date
)
SELECT
tupleElement(b, 1) AS outcome,
countIf(o.premium_ratio >= tupleElement(b, 2) AND o.premium_ratio < tupleElement(b, 3)) AS expiries
FROM
(
SELECT arrayJoin([
('1. Finished at or near zero (5% of the premium or less)', -1.0, 0.05),
('2. Lost more than half', 0.05, 0.5),
('3. Lost up to half', 0.5, 1.0),
('4. Gained, less than doubled', 1.0, 2.0),
('5. Doubled or better', 2.0, 1000000.0)
]) AS b
) AS buckets
CROSS JOIN outcomes AS o
GROUP BY outcome
ORDER BY outcome
Travaillez ces données dans votre assistant IA
S'ouvre prêt à interroger, avec les données de cette page. Gratuit, sans compte.