cushion_outcomes
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-10-02, from why-would-anyone-sell-a-put-option.
| strike_cushion | expired_worthless_pct | avg_loss_when_itm_pct | avg_loss_all_windows_pct | worst_window_pct | sample |
|---|---|---|---|---|---|
| 2% below spot | 68.2 | 4.99 | 1.59 | 22.2 | 1418 windows |
| 5% below spot | 77.3 | 3.36 | 0.76 | 19.2 | 1418 windows |
| 10% below spot | 95.1 | 2.73 | 0.13 | 14.2 | 1418 windows |
| 15% below spot | 99.4 | 3.42 | 0.02 | 9.2 | 1418 windows |
- Rows × columns
- 4 × 6
- 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 |
|---|---|---|---|
strike_cushion |
text | 4 distinct values | |
expired_worthless_pct |
number | 68.2 to 99.4 | percent |
avg_loss_when_itm_pct |
number | 2.73 to 4.99 | percent |
avg_loss_all_windows_pct |
number | 0.02 to 1.59 | percent |
worst_window_pct |
number | 9.2 to 22.2 | percent |
sample |
text | 1 distinct value (1418 windows) |
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.
SELECT
concat(toString(cushion_pct), '% below spot') AS strike_cushion,
round(100 * countIf(move_pct > -1 * cushion_pct) / count(), 1) AS expired_worthless_pct,
round(avgIf(-1 * (move_pct + cushion_pct), move_pct <= -1 * cushion_pct), 2) AS avg_loss_when_itm_pct,
round(avg(if(move_pct <= -1 * cushion_pct, -1 * (move_pct + cushion_pct), 0)), 2) AS avg_loss_all_windows_pct,
round(-1 * min(move_pct) - cushion_pct, 2) AS worst_window_pct,
concat(toString(count()), ' windows') AS sample
FROM
(
SELECT (end_px / start_px - 1) * 100 AS move_pct
FROM
(
SELECT
close_px AS start_px,
leadInFrame(close_px, 21) OVER (ORDER BY date ROWS BETWEEN CURRENT ROW AND 21 FOLLOWING) AS end_px
FROM
(
SELECT
date,
max(toFloat64(close)) AS close_px
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'AAPL'
AND date BETWEEN '2021-01-04' AND '2026-09-25'
GROUP BY date
) AS daily
) AS shifted
WHERE end_px > 0
) AS windows
CROSS JOIN
(
SELECT arrayJoin([2, 5, 10, 15]) AS cushion_pct
) AS cushions
GROUP BY cushion_pct
HAVING countIf(move_pct <= -1 * cushion_pct) > 0
ORDER BY cushion_pct
Work with this data in your AI assistant
Opens ready to query, with this page's data. Free, no account.