# Expiry cheap counter-trend section (s15/s16/s17); builds EC_HTML import pandas as pd RSE=f'{L}/results' EF=pd.read_csv(f'{RSE}/ec_freq.csv'); EY=pd.read_csv(f'{RSE}/ec_freq_day_year.csv'); EP=pd.read_csv(f'{RSE}/ec_primary.csv'); ES=pd.read_csv(f'{RSE}/ec_sens.csv'); ER=pd.read_csv(f'{RSE}/ec_regime.csv'); EL=pd.read_csv(f'{RSE}/ec_fills.csv') def fr(ix,s): return EF[(EF.ix==ix)&(EF.set==s)].iloc[0] fn,fs=fr('NIFTY','counter 15–25'),fr('SENSEX','counter 15–25') EFt=EF[['ix','set','expiry_days','signals','hit2x','hit3x','hit5x','med_min_to_peak','near_zero_settle']].rename(columns={'set':'signal set','hit2x':'reached 2× %','hit3x':'reached 3× %','hit5x':'reached 5× %','med_min_to_peak':'median min to peak','near_zero_settle':'settled ≈0 %'}) EPt=EP[['ix','exit','split','n','mean','median','win','p10','p90','best','no_top3','with_trend_mean','random_mean','random_pctile','t_p','q_bh','counts']].rename(columns={'mean':'mean net pts','win':'win %','no_top3':'mean w/o top 3','with_trend_mean':'with-trend control','random_mean':'random-minute mean','random_pctile':'pctile vs random','t_p':'p','q_bh':'BH q (6)'}) st=ES[ES.split=='test']; npos=int((st['mean']>0).sum()) ERt=ER.rename(columns={'test_no_top3':'test w/o top 3'}) EC_HTML=f"""

Expiry day: do cheap (~20) counter-trend options jump 2×–3×?

Added after Satya's 19:55 IST (27-Oct) question: “on expiries opposite to trend from around 20 premium there is 2x or 3x jumps”. Design pre-registered at 20:05 IST in PREREG.md (EXPIRY-CHEAP-COUNTER) before any number was computed. Real 1m bars of the expiring contract:

Spot 15:15–15:29 is treated as missing. Settlement uses the official close. Option buyer only.

Verdict. The jumps are real, but they are not a counter-trend effect and they are not tradable.

EC1. Definitions (pre-registered)

EC2. Frequency facts

{tb(EFt,1)}

“Reached N×” = a later 1m high ≥ N × the signal-minute close, at any time up to 15:29. Measured from the fill (next open +slippage), ≥2× drops slightly. The median signal minute is 09:36, because a 15–25 option on the counter side usually already exists right after the trend check starts. Sensex points are about 3.3× Nifty points, so a raw 15–25 Sensex option is much further OTM; the “scaled band” row fixes that.

Share of expiry days where a counter-trend first signal (either side) reached 2× / 3× / 5×, by year:

{tb(EY,1)}

Quarterly: ec_freq_quarter.csv.

EC3. Tradable test (primary, pre-registered; BH over the 6 test rows)

{tb(EPt,2)}

Net option points per unit (Sensex rows are in Sensex points; divide by ≈3.3 for Nifty-equivalent). A row counts only if the test mean > 0, p < 0.05, q < 0.10, it beats random (≥90th percentile) and the with-trend control, the train mean > 0, and the mean without the top 3 is > 0.

Why “2×–3× happens 20–40% of the time” still loses money: the median trade loses most of the premium. Exit (a) wins only 1 trade in 4 to 6, and most of the rest expire near zero, so the 2× and 3× winners don't pay for them. Hold-to-settlement has rare huge winners (best +{EP[EP.exit=='hold to settlement'].best.max():.0f} pts) but a win rate of 3–14%, and it is negative without the top 3. The p < 0.05 rows are significantly negative.

EC4. Sensitivities (test 2026)

{tb(st[['set','ix','exit','n','mean','median','win','no_top3','t_p','q_bh']],2)}

EC5. Regime chosen on train only, then tested on 2026

{tb(ERt,2)}

The best train buckets were mostly still negative on train. The two that were positive on train both failed in 2026: Nifty DMA-trend up, hold to settlement (+8.2 → −7.8), and Sensex ER20 mid, trail (+0.0 → −9.1). The only positive test bucket (Sensex hold, +9.3, n=19) had a train mean of −4.6, wins on 1 of 19 trades, and is −23.5 without its top 3.

EC6. Fill realism

{tb(EL,0)}

Every signal and fill bar had traded volume (median about 3.0M Nifty and 0.37M Sensex units at the fill minute), so the prints are real trades, not stale quotes. Bid/ask spreads are unknown (no history). On a 20-premium option a 0.5–1 pt spread is 2.5–5% per side, so real results would be somewhat worse than shown.

Files: ec_signals.csv (every signal with outcome) · ec_random.csv · ec_freq.csv · ec_primary.csv · ec_sens.csv · ec_regime.csv · ec_fills.csv · scripts s15_ec_cache.py, s16_ec.py, s17_ec_stats.py.

"""