When a Spread Expires Between the Strikes
When a spread expires between the strikes, the short leg is exercised and the long leg dies worthless. How often that happens on SPY, and the fix by 4 p.m.
A spread that expires between the strikes is the one outcome a risk defined position does not protect you from. The short leg finishes in the money and is exercised. The long leg finishes out of the money and expires worthless, and a trade capped at a few hundred dollars of risk turns into an unhedged share position held over the weekend.
What happens when a spread expires between the strikes
Both legs of a vertical share an expiration and an underlying, separated by the width between the strikes. At 4:00 p.m. ET each leg is judged on its own. The Options Clearing Corporation exercises any long contract that finishes at least $0.01 in the money unless the holder files contrary instructions, a process called exercise by exception. A close inside the width means exactly one of your two contracts clears that bar.
Four shapes, four outcomes at the bell:
- Short call vertical: a close inside the width assigns you short 100 shares per contract at the short strike, with the market above it.
- Short put vertical: a close inside the width assigns you long 100 shares per contract, with cash debited at the short strike.
- Long call vertical: your long call is exercised into 100 long shares per contract and the call you sold lapses, leaving a share position and a cash debit that can exceed the account's buying power.
- Long put vertical: your long put is exercised into a short share position at the strike you bought.
In every case the overnight exposure is the share position, not the spread. What happens when an option expires in the money walks the assignment plumbing leg by leg, and credit spread versus debit spread covers which side of the width you paid to own.
Cash settled index options end at the settlement price
Settlement style decides whether between the strikes means shares or cash. Broad index options are cash settled: the in the money leg pays its intrinsic value against a single settlement value, the other leg lapses, and the position is gone that night. ETF and single stock options are physically settled, which is where the share position appears. Cash settled versus physical delivery sets the two mechanics side by side, and SPX versus SPY options is close to the same trade written in both styles.
What a between the strikes close actually costs
Take a hypothetical stock trading near $498 on expiration morning. You sell the $500 call and buy the $505 call for a net credit of $1.00, or $100 per contract on a $5 wide spread. The most the spread can lose is the width minus the credit, $400. The stock closes at $502.30. The $500 call is assigned, the $505 call expires worthless, and Monday opens with you short 100 shares at $500. The paper loss is $230 against the $100 credit, and Monday's price settles it, not Friday's. A $20 gap higher prices those short shares roughly $2,000 against you, several times the spread's stated maximum. That gap is the part a maximum loss figure does not describe.
How often does the close land between two levels?
Strikes sit on a fixed grid. Closing prices do not. SPY lists strikes in one dollar increments near the money, and the whole dollar grid is a fair stand in for the strikes a narrow vertical is written against. The panel below scores every Friday session, reading the last regular session minute bar as the close and the 3:00 p.m. ET bar as the reference.
| year | expiration_count | between_strikes_pct | crossed_strike_pct | within_10_cents_pct |
|---|---|---|---|---|
| 2022 | 50 | 100 | 86 | 20 |
| 2023 | 50 | 100 | 66 | 18 |
| 2024 | 50 | 100 | 52 | 24 |
| 2025 | 49 | 98 | 57.1 | 24.5 |
| 2026 | 32 | 100 | 68.8 | 18.8 |
The exact SQL behind every number
WITH bars AS (
SELECT
toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York')) AS et_minute,
toFloat64(close) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= '2022-01-01 00:00:00'
AND window_start < '2026-09-01 00:00:00'
),
day_marks AS (
SELECT
session_date,
anyIf(px, et_minute = 900) AS px_3pm,
argMax(px, et_minute) AS px_close
FROM bars
WHERE et_minute >= 570
AND et_minute <= 959
GROUP BY session_date
HAVING px_3pm > 0
AND px_close > 0
AND max(et_minute) >= 955
)
SELECT
toString(toYear(session_date)) AS year,
count() AS expiration_count,
round(100 * countIf(px_close != floor(px_close)) / count(), 1) AS between_strikes_pct,
round(100 * countIf(floor(px_close) != floor(px_3pm)) / count(), 1) AS crossed_strike_pct,
round(100 * countIf(least(px_close - floor(px_close), floor(px_close) + 1 - px_close) <= 0.10) / count(), 1) AS within_10_cents_pct
FROM day_marks
WHERE toDayOfWeek(session_date) = 5
GROUP BY year
ORDER BY yearAcross SPY Fridays from 2022 through 2026, the close landed strictly between two whole dollar levels on 100% of the 32 sessions scored in the 2026 row. Finishing exactly on a level is the rare case. The second measure is the one a spread cares about: on 68.8% of those sessions the close sat in a different one dollar bracket than the 3:00 p.m. print, meaning a strike passed under or over the price during the final hour. On 18.8% the close finished within ten cents of a whole dollar level, which is pin risk at options expiration in its most literal form.
Where the strikes sit matters as much as the grid. The next panel builds one standard narrow vertical per Friday: the short strike is the first whole dollar level at or above 0.5% over the 3:00 p.m. price, the long strike is the first level at or above 3% over that same price, and the outcome is scored against the closing bar.
| symbol | expiration_count | both_legs_worthless_pct | between_strikes_pct | both_legs_itm_pct |
|---|---|---|---|---|
| TSLA | 181 | 85.6 | 14.4 | 0 |
| AMD | 181 | 90.6 | 9.4 | 0 |
| NVDA | 181 | 93.9 | 6.1 | 0 |
| MSFT | 181 | 96.1 | 3.9 | 0 |
| AAPL | 181 | 97.2 | 2.8 | 0 |
| SPY | 181 | 98.9 | 1.1 | 0 |
The exact SQL behind every number
WITH bars AS (
SELECT
ticker AS symbol,
toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York')) AS et_minute,
toFloat64(close) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'AAPL', 'MSFT', 'NVDA', 'AMD', 'TSLA')
AND window_start >= '2023-01-01 00:00:00'
AND window_start < '2026-09-01 00:00:00'
),
day_marks AS (
SELECT
symbol,
session_date,
anyIf(px, et_minute = 900) AS px_3pm,
argMax(px, et_minute) AS px_close
FROM bars
WHERE et_minute >= 570
AND et_minute <= 959
GROUP BY symbol, session_date
HAVING px_3pm > 0
AND px_close > 0
AND max(et_minute) >= 955
),
verticals AS (
SELECT
symbol,
px_close,
ceil(px_3pm * 1.005) AS short_strike,
ceil(px_3pm * 1.030) AS long_strike
FROM day_marks
WHERE toDayOfWeek(session_date) = 5
)
SELECT
symbol,
count() AS expiration_count,
round(100 * countIf(px_close <= short_strike) / count(), 1) AS both_legs_worthless_pct,
round(100 * countIf(px_close > short_strike AND px_close < long_strike) / count(), 1) AS between_strikes_pct,
round(100 * countIf(px_close >= long_strike) / count(), 1) AS both_legs_itm_pct
FROM verticals
WHERE long_strike > short_strike
GROUP BY symbol
ORDER BY between_strikes_pct DESCThe panel is sorted by how often the close landed inside the width. TSLA sits at the top, with 14.4% of its 181 scored Fridays finishing between the two strikes, against 1.1% for SPY at the bottom. For TSLA, both legs finished in the money on 0% of those sessions, the clean maximum loss case a spread is built to accept, and the whole structure expired untouched on 85.6%. The middle bar is the slice that turns a defined trade into a share position.
The last hour is where the zone gets crossed
Distance travelled after 3:00 p.m. ET is what converts a cushion into an assignment. This panel measures the absolute move from the 3:00 p.m. bar to the closing bar on every SPY Friday, as a percentage of the 3:00 p.m. price, at the median and at the ninth decile.
| year | expiration_count | median_final_hour_move_pct | p90_final_hour_move_pct |
|---|---|---|---|
| 2022 | 50 | 0.353 | 0.779 |
| 2023 | 50 | 0.141 | 0.388 |
| 2024 | 50 | 0.115 | 0.294 |
| 2025 | 49 | 0.103 | 0.399 |
| 2026 | 32 | 0.124 | 0.306 |
The exact SQL behind every number
WITH bars AS (
SELECT
toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York')) AS et_minute,
toFloat64(close) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= '2022-01-01 00:00:00'
AND window_start < '2026-09-01 00:00:00'
),
day_marks AS (
SELECT
session_date,
anyIf(px, et_minute = 900) AS px_3pm,
argMax(px, et_minute) AS px_close
FROM bars
WHERE et_minute >= 570
AND et_minute <= 959
GROUP BY session_date
HAVING px_3pm > 0
AND px_close > 0
AND max(et_minute) >= 955
)
SELECT
toString(toYear(session_date)) AS year,
count() AS expiration_count,
round(quantileDeterministic(0.5)(100 * abs(px_close - px_3pm) / px_3pm, toUInt32(toUnixTimestamp(session_date))), 3) AS median_final_hour_move_pct,
round(quantileDeterministic(0.9)(100 * abs(px_close - px_3pm) / px_3pm, toUInt32(toUnixTimestamp(session_date))), 3) AS p90_final_hour_move_pct
FROM day_marks
WHERE toDayOfWeek(session_date) = 5
GROUP BY year
ORDER BY yearIn 2026 the median SPY Friday travelled 0.124% in that hour, and one Friday in ten travelled at least 0.306%. In 2022 the same two figures were 0.353% and 0.779%. On a fund priced in the hundreds of dollars, the ninth decile is several dollars of strike grid, wider than most of the spreads written on it.
Here is one of those hours, pinned to a fixed past date: SPY's final sixty minutes on August 21, 2026, in five minute buckets, with the whole dollar level immediately below the 3:00 p.m. price drawn alongside as a reference line.
| et_time | spy_price | strike_line |
|---|---|---|
| 15:00 | 766.03 | 766 |
| 15:05 | 766.1 | 766 |
| 15:10 | 766.04 | 766 |
| 15:15 | 765.97 | 766 |
| 15:20 | 766.2 | 766 |
| 15:25 | 766.05 | 766 |
| 15:30 | 766.08 | 766 |
| 15:35 | 766.28 | 766 |
| 15:40 | 766.47 | 766 |
| 15:45 | 766.67 | 766 |
| 15:50 | 765.9 | 766 |
| 15:55 | 765.69 | 766 |
The exact SQL behind every number
WITH bars AS (
SELECT
toStartOfFiveMinute(toTimeZone(window_start, 'America/New_York')) AS et_bucket,
argMax(toFloat64(close), window_start) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= '2026-08-21 19:00:00'
AND window_start < '2026-08-21 20:00:00'
GROUP BY et_bucket
),
anchor AS (
SELECT floor(argMin(toFloat64(close), window_start)) AS strike_line
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= '2026-08-21 19:00:00'
AND window_start < '2026-08-21 19:05:00'
)
SELECT
formatDateTime(b.et_bucket, '%H:%i') AS et_time,
round(b.px, 2) AS spy_price,
a.strike_line AS strike_line
FROM bars AS b
CROSS JOIN anchor AS a
ORDER BY et_timeSPY entered that hour at $766.03 in the 15:00 ET bucket, with the reference level at $766. The final bucket, beginning 15:55, closed at $765.69. Whether any particular spread finished between its strikes that Friday is a question of where its short strike sat against this path, and zero days to expiry positions meet that path on the same afternoon they are opened.
Method notes and caveats
- Prices come from the minute bar record. The close is the last regular session minute bar rather than the official closing print, and the 3:00 p.m. reference is the 15:00 ET bar. Sessions missing either bar, including early closes, drop out.
- Scoring covers Friday sessions, the expiration all six names carry every week. The 2026 rows cover Fridays through August 2026.
- Whole dollar levels stand in for listed strikes. That matches SPY's one dollar grid near the money and approximates it on the single names, where increments widen at higher prices.
- The narrow vertical in the second panel is a scoring convention, not a recommendation, and it holds the same placement rule across all six names.
What to check before the bell
Four operational levers exist on expiration afternoon, and each has a different clock:
- Close the spread for a debit. Buying back the short leg and selling the long leg ends both obligations at a price on screen.
- Read the broker's own auto liquidation policy. Many firms reduce positions that would create an assignment the account cannot cover, on their own late session timetable, which is house policy rather than an exchange rule.
- Exercise the long leg. Instructions on the contract you own turn a between the strikes outcome back into a hedged pair, capping the loss near the width.
- Do nothing, with exposure sized for it. The overnight risk is the share position, and the account's cash and margin absorb a Monday gap.
The deadline for the third one belongs to your broker, and it lands earlier than the clearing deadline. Pin risk at options expiration works through the decision itself and hands off to broker exercise cutoff times for the clock that actually binds.
FAQ
What happens if a stock closes between my spread's strikes?
Your short leg finishes in the money and is exercised against you, and your long leg expires worthless. On a physically settled option that leaves 100 shares per contract, long or short depending on the leg, carried at the short strike until you trade out of them.
Can a defined risk spread lose more than its maximum loss?
Yes, once the legs separate at expiration. The stated maximum assumes both legs settle together. A between the strikes close leaves a share position whose Monday price is unknown on Friday, and a gap can carry the outcome past the width.
Do cash settled index spreads have the same problem?
Not the overnight part. A cash settled spread pays the intrinsic value of the in the money leg against the settlement value and closes itself, so the loss is fixed at settlement and no shares change hands.
How late can I close a spread on expiration day?
Regular trading in most equity and ETF options runs to 4:00 p.m. ET, while exercise and contrary instructions reach your broker earlier than the clearing deadline. Both cutoffs vary by broker and by product.
Every panel here ships with the SQL that produced it, and the counts can be rebuilt bar by bar. To score the same test on the names you trade, ask it in plain English on the Strasmore terminal.