free expiry day ↓

blog /

How fast an at-the-money straddle bleeds on expiry day: a minute-by-minute look

On the 14 Oct 2025 NIFTY expiry the 25,150 straddle fell from 171.65 at the open to 4.45 at the close, and lost half its remaining value between 14:30 and 15:00. Here is how to measure it.

Short-straddle sellers talk about expiry-day "theta" as if it were a smooth line. Minute data shows something lumpier: long flat stretches, and then most of the remaining premium vanishing in a short window late in the day.

The day

We used the free sample, NIFTY on Tuesday 14 October 2025. The index opened at 25,277.55, touched 25,310.35 at 09:24, fell to 25,060.55 at 12:44 and closed the regular session at 25,123.35. By the close, the 25,150 strike held the most call and the most put open interest of the expiring series, so it is a natural straddle to follow.

Time (IST)NIFTY25,150 CE25,150 PEStraddle
09:1525,291.65159.7511.90171.65
11:0025,195.7082.2525.05107.30
13:0025,094.3515.7580.0595.80
14:0025,126.0518.6036.5555.15
14:3025,154.4025.2514.6039.85
15:0025,170.9020.551.8522.40
15:1025,140.601.654.506.15
15:2925,123.350.054.404.45

One-minute closes from the sample files. Straddle = call close + put close at the same minute.

What the table says

Repeat it on any expiry

import pandas as pd

opt = pd.read_parquet("NIFTY_OPT_1min_2025-10-14_exp2025-10-14.parquet")
opt = opt.rename(columns={"datetime": "ts", "strike_price": "strike"})
opt["cp"] = opt["right"].str[0].str.upper().map({"C": "CE", "P": "PE"})

px = opt.pivot_table(index="ts", columns=["strike", "cp"], values="close")
k = 25150
straddle = (px[(k, "CE")] + px[(k, "PE")]).rename("straddle")
print(straddle.resample("30min").last())

Older files name the columns timestamp, strike, option_type; rename those the same way and the rest of the code is unchanged. To follow the straddle nearest the index instead of a fixed strike, merge in the index file and round its close to the strike step (50 for NIFTY) every minute.

Turning one day into a study

One day is an anecdote. Run the loop over every expiry session in a pack and record the share of the opening straddle left at 13:00, 14:00, 14:30 and 15:00. The distribution of those shares, split by how far the index travelled, tells you far more about entry timing than any rule of thumb.

more guides

Building an expiry-day dataset in Python: pandas and DuckDB recipesOne-second or one-minute bars for the last hour of expiry?Does NIFTY pin to max pain on expiry day? Testing it with open interest by strike