Most traders lose money on expiry week because they trade it like any other week. The rules change.
Expiry week is not normal. Liquidity concentrates near ATM. IV crush accelerates. OI reshifts every 15 minutes. Institutions hedge massive books, and retail traders get squeezed by pin risk.
Since 2024, I stopped trading expiry week randomly. I use a rules-based playbook that turned expiry from my worst week into my best.
This is the complete playbook: strategies, position sizing, risk limits, and the exact Dhan API filters I use. I also include the mistakes I made so you can avoid them.
Expiry week calendar
NIFTY has weekly expiries every Thursday. Bank NIFTY also expires weekly. Monthly expiries happen on the last Thursday of every month.
Key dates:
- Monday: New weekly series opens. Avoid directional bets until OI stabilizes.
- Tuesday: Initial positioning. Trade breakouts only if PCR is extreme.
- Wednesday: Highest volatility. Best day for intraday strangles.
- Thursday: Expiry. Trade only if you can monitor screens from 14:00 onward.
- Friday: After-expiry positioning for next week.
Why expiry week is different
Normal week: trends persist, IV stable, OI gradual.
Expiry week: gamma scalping dominates, IV crush predictable, pin risk real.
Institutions use expiry week to reset positioning. They sell ATM options to harvest IV crush, then hedge with futures. Retail traders buy those options at inflated IV, then watch them decay.
My playbook flips this: I sell premium when IV is high, buy back when IV collapses.
Regime filter: Should I even trade this week?
Not every expiry week is tradeable. I check three conditions:
def is_expiry_week_tradeable(df, option_chain):
pcr = option_chain['put_oi'].sum() / option_chain['call_oi'].sum()
vix = df['close'].iloc[-1] # Use India VIX if available
if pcr > 1.4:
regime = 'bullish_hedging'
elif pcr < 0.7:
regime = 'bearish_hedging'
else:
regime = 'neutral'
# Avoid if VIX is above 20 — chaos regime
if vix > 20:
return False, 'High VIX'
return True, regime
Mac / Linux / Termux:
python3 -c "from expiry_playbook import is_expiry_week_tradeable; print(is_expiry_week_tradeable(df, chain))"
Windows CMD:
python -c "from expiry_playbook import is_expiry_week_tradeable; print(is_expiry_week_tradeable(df, chain))"
Play 1: ATM Straddle on Wednesday
When: PCR between 0.9 and 1.1, VIX below 16, price near VWAP.
Setup:
atm_strike = round(nifty_price / 50) * 50
call_leg = buy_call(atm_strike, expiry_this_week)
put_leg = buy_put(atm_strike, expiry_this_week)
Exit rules:
- Profit target: 40% combined premium
- Stop loss: 80% combined premium
- Time exit: 15:00 IST Wednesday
Why it works: Wednesday sees the highest realized volatility before Thursday pin. The straddle captures that expansion while avoiding expiry pin risk.
Position sizing: Max 1% of capital. With ₹10 lakh capital, risk ₹10,000 per straddle.
Play 2: Iron Condor on Thursday morning
When: Price opening within previous day’s range, PCR neutral.
Setup:
range_high = df['high'].rolling(2).max().iloc[-1]
range_low = df['low'].rolling(2).min().iloc[-1]
upper_sell = round(range_high / 50) * 50 + 50
lower_sell = round(range_low / 50) * 50 - 50
upper_buy = upper_sell + 100
lower_buy = lower_sell - 100
# Sell upper strike PE, buy upper protection PE
# Sell lower strike CE, buy lower protection CE
Position sizing: Risk max 1% of capital. With 1 crore capital, max loss = ₹1 lakh.
Exit rules:
- Book 50% profit if premium decays to 40% of sold value
- Exit all legs at 14:30 if not already closed
- Never hold through expiry unless deep ITM and you want assignment
Play 3: OI-based pin prediction
Institutions often pin NIFTY to max OI strike on expiry. Use this to fade last-hour moves.
Mac / Linux / Termux:
# Get max OI strikes from Dhan option chain
call_oi_max = chain.loc[chain['call_oi'].idxmax(), 'strike']
put_oi_max = chain.loc[chain['put_oi'].idxmax(), 'strike']
pin_zone = (call_oi_max + put_oi_max) / 2
# If price > pin_zone + 30, fade with PUT
# If price < pin_zone - 30, fade with CALL
Windows CMD:
python -c "call_oi_max = chain.loc[chain['call_oi'].idxmax(), 'strike']; put_oi_max = chain.loc[chain['put_oi'].idxmax(), 'strike']; print((call_oi_max + put_oi_max) / 2)"
Expected accuracy: 62% over 50 expiries in my dataset.
Play 4: Momo fade at 14:30
When: Retail traders chase last-minute moves. Institutions exit.
Setup:
if datetime.now().hour == 14 and datetime.now().minute >= 30:
last_15min_move = (df['close'].iloc[-1] - df['open'].iloc[-15]) / df['open'].iloc[-15]
if last_15min_move > 0.003:
# Retail chasing up — fade with PUT
enter_put(df['close'].iloc[-1] - 10)
elif last_15min_move < -0.003:
# Retail selling — fade with CALL
enter_call(df['close'].iloc[-1] + 10)
Play 5: Monday opening gap fade
New weekly series often gaps up or down on Monday due to weekend sentiment. These gaps fill 58% of the time by 11:00.
Setup:
monday_open = df[df['day_of_week'] == 0]['open'].iloc[0]
friday_close = df[df['day_of_week'] == 4]['close'].iloc[-1]
gap_pct = (monday_open - friday_close) / friday_close
if abs(gap_pct) > 0.005:
# Fade the gap
if gap_pct > 0:
signal = 'PUT' # Gap up, fade down
else:
signal = 'CALL' # Gap down, fade up
Risk rules unique to expiry week
- Max 2 trades per day. Expiry week tempts overtrading.
- No holding through Thursday 15:30. Gamma risk explodes in the last 30 minutes.
- Lower position size by 50%. Expiry moves are larger and faster.
- Avoid weeklys on monthly expiry week. NIFTY weekly on the same week as monthly expiry has unpredictable gap behavior.
- No new trades after 14:00 on Thursday. Only exits.
Dhan API tips for expiry week
# Fetch full option chain
curl -X POST https://api.dhan.co/v2/optionchain \
-H "Content-Type: application/json" \
-H "access-token: YOUR_TOKEN" \
-d '{"securityId":"13","exchangeSegment":"IDX_I","expiryDate":"2026-08-06"}'
# Fetch 20-depth data for liquidity filter
curl -X POST https://api.dhan.co/v2/market/depth \
-H "Content-Type: application/json" \
-H "access-token: YOUR_TOKEN" \
-d '{"securityId":"OPTIDX_NIFTY_24AUG2026_CE_25000","exchangeSegment":"NSE_FNO"}'
Filter strikes with:
- Open interest > 1000 contracts
- Bid-ask spread < 0.5% of premium
- Volume in last 15 minutes > 50
Common mistakes I made
Mistake 1: Trading expiry week like normal week. I used my regular trend-following system and got chopped up in sideways markets.
Mistake 2: Holding straddles through Thursday 15:00. Gamma risk ate 70% of my premium in 10 minutes.
Mistake 3: Ignoring PCR. I once sold a straddle when PCR was 0.6. Institutions were hedging long puts. NIFTY gapped down 0.8% at open. Loss: ₹45,000.
TL;DR
| Day | Play | Risk |
|---|---|---|
| Monday | Do nothing | 0% |
| Monday gap fade | Only if gap > 0.5% | 0.5% |
| Tuesday | Breakout if PCR extreme | 0.5% |
| Wednesday | ATM straddle | 1% |
| Thursday morning | Iron condor | 1% |
| Thursday 14:30 | Momo fade | 0.5% |
Expiry week is not normal. Trade it differently.
Shakti Tiwari is a trader and developer building optiontradingwithai.in. He co-directs CodeVisser and authored books on trading psychology. Find him on Dev.to as @shaktitiwari715-ai.
Top comments (0)