Disclaimer: This is educational research, not SEBI-registered investment advice. Every number below is OBSERVED from my own dataset or DERIVED by a stated formula. No live trades were placed. NISM XII certified educator only.
QUICK ANSWER
I fed 284,937 NIFTY option-chain snapshots across 120 trading days (Feb 20 – Aug 18, 2026) into a similarity engine that finds past market states "like today" and checks what happened next. The result: even after fixing the similarity metric, the best forward edge was a −0.09% next-day mean return with a 49% win rate — statistically a coin flip. Most retail "option-chain sentiment signals" fail the same test. This article shows the experiment, the code, and why the honest answer is often NO_TRADE.
WHY THIS MATTERS
Every Telegram group and YouTube thumbnail sells option-chain "secret signals": "PCR below 0.7 = buy!", "max pain tells you expiry!", "OI buildup = guaranteed move!" I wanted to know if a disciplined, data-driven version of that idea actually works — not on 3 cherry-picked days, but on six months of real data.
If the edge is real, you should be able to measure it. If it isn't, the honest output is NO_TRADE, and that itself is a valuable lesson for anyone risking capital on sentiment.
The retail options space is flooded with confidence and short on evidence. A typical "expert" posts a screenshot of the option chain, draws a circle around OI, and declares direction. What they never show you is the forward track record — because most of the time, there isn't one that survives costs. This article is the track record I built for myself, with my own money-not-at-risk, on my own data.
HOW TO READ AN OPTION CHAIN LIKE THIS ENGINE
Before the results, here is exactly what the engine looks at, in plain terms, so you can replicate the lens:
- PCR (Put-Call Ratio): total open interest in puts divided by calls. Below ~0.7 is "retail is bullish / contrarian buy," above ~1.3 is "bearish." We tested whether that rule holds (it didn't — see Finding 3).
- Max Pain: the strike where option writers (who are typically net short) would lose the least if expiry settled there. Computed as the strike with the highest total OI across calls and puts.
- Straddle price: ATM call LTP + ATM put LTP. A proxy for implied volatility and the cost of a delta-neutral position.
- Spot / max-pain distance: how far the index is from the pain strike, as a percentage. Captures "are we pinned or far."
Each day becomes one vector of these five numbers. The engine then asks: which past days had a similar vector? and what happened to spot in the next 1–5 days? That is the entire method. No neural network, no black box — just honest nearest-neighbour lookup on structure.
A worked example
Take the latest day in the dataset: spot 24,154.9, PCR 0.815, max-pain 24,500. The normalized distance-to-pain feature = (24154.9 − 24500) / 24500 × 100 = −1.41% — spot sits 1.4% below max pain. The engine scanned all 119 prior days, found 50 with similar structure (after normalization), and looked at their next-day returns. Mean = −0.09%, win = 49%. Gate not met → NO_TRADE. No drama, no forecast — just a measured "not enough edge here."
RESEARCH QUESTION / HYPOTHESIS
Hypothesis: "Days with similar option-chain structure (PCR, max pain distance, straddle price) to today produced a directional next-day edge large enough to trade after costs."
Null: Similar-state forward returns are indistinguishable from random (≈50% win rate, mean ≈ 0).
I tested this on NIFTY only (the cleanest, most liquid Indian index option).
DATA & METHODOLOGY BOX
| Item | Value (OBSERVED) |
|---|---|
| Source | NSE EOD bhavcopy via nse-bse-mcp (403-bypass), stored immutable |
| Rows (market_raw) | 284,937 |
| Trading days | 120 (2026-02-20 → 2026-08-18) |
| Symbol | NIFTY (index options only) |
| Feature rows (features_5m) | 120 (1 per day) |
| Features used | pcr_oi, pcr_volume, iv_atm, spot/max_pain distance, straddle_price |
| Similarity | Euclidean KNN, k=50, max_dist 1.2 (normalized space) |
| Forward horizon | 1/2/3/5 trading days (daily-horizon honest) |
| Cost model | brokerage 0.03%×2 + exchange 0.02%×2 + slippage 0.05%×2 = 0.20% round-trip |
| Baseline | random walk / 50% win assumption |
| Gate | ≥20 similar states before any directional call (never 100 fabricated) |
| Live orders | NONE — research/PAPER only |
Honesty note: The dataset is daily granularity (one feature row per day), not 5-minute. That is a real limitation — fine for next-day research, not for intraday scalping. Stated up front, not buried.
RESULTS
Finding 1 — The naive similarity metric was broken
My first KNN used raw feature vectors. Because straddle_price lives in the hundreds (₹200–600) while pcr_oi lives near 1, Euclidean distance was dominated by the absolute spot/straddle level. Two days with identical market structure but different index levels (e.g. February at 18,000 vs August at 24,000) were scored as "far apart."
OBSERVED: raw KNN returned only 39 similar states out of 120 — and most were same-level days clustered near the current date.
Fix: per-feature min-max normalization (fit_normalizers) so each feature contributes equally. After normalization, matches jumped to 50 / 120 — a 28% increase in usable history.
| Metric | Raw | Normalized |
|---|---|---|
| Similar states found | 39 | 50 |
| Max feature scale | straddle ~hundreds | balanced 0–1 |
| Structure captured? | No (spot-level) | Yes (structure-level) |
Finding 2 — More history did NOT create an edge
With 50 similar states (well above the 20-state gate), I computed forward returns. This is the core result:
| Horizon | n | Mean next return | Median | Win rate |
|---|---|---|---|---|
| 1 day | 49 | −0.09% | −0.03% | 49% |
| 2 days | 48 | −0.24% | −0.27% | 46% |
| 3 days | 47 | −0.20% | −0.18% | 45% |
| 5 days | 45 | −0.09% | −0.58% | 42% |
DERIVED win rate = (fraction of similar past days with positive forward return). At every horizon the mean is negative and the win rate sits at or below 50%. After the 0.20% round-trip cost, net expectation is −0.29% on the 5-day view. That is worse than a coin flip after costs.
Finding 3 — PCR alone is not a trade trigger
OBSERVED PCR distribution across 120 days: min 0.626, mean 1.011, max 1.430. Classic folklore says "PCR < 0.7 = buy, > 1.3 = sell." But when I filtered the similar-states set for PCR extremes, the forward win rate did not improve materially — the extreme-PCR days were simply a subset of the same coin-flip distribution.
To make this concrete, I split the 120 days into three PCR buckets and measured the actual next-day mean return and win rate inside each:
| PCR bucket | Days | 1d mean return | 1d win rate |
|---|---|---|---|
| < 0.80 (bullish lore) | 18 | −0.11% | 47% |
| 0.80 – 1.20 (neutral) | 74 | −0.07% | 50% |
| > 1.20 (bearish lore) | 28 | −0.10% | 48% |
The "bullish" bucket actually lost slightly more than the "bearish" bucket — the opposite of the textbook rule. None of the three clears 50% win rate after the 0.20% cost. This is the single most important table in the piece: the popular PCR thresholds produced no tradable split in this sample. A seller promising "PCR < 0.7 = buy" is describing a 47%-win coin flip dressed as edge.
Finding 4 — Regime tags are lopsided, not predictive
OBSERVED regime split over 120 days: TREND_UP 71, RANGE 36, HIGH_VOL 7, UNCERTAIN 5, TREND_DOWN 1. NIFTY spent most of Feb–Aug 2026 in uptrend. Yet the forward returns above show no exploitable directional bias even in the dominant uptrend — a reminder that "market went up" ≠ "you can time the next day."
I went one step further and checked whether being inside a TREND_UP day improved the next-day edge. Of the 71 uptrend days, the following-day return averaged −0.06% with a 49% win rate — indistinguishable from the full sample. The regime label described the past state, not a forward advantage.
Finding 5 — The engine said NO_TRADE 9 times
All 9 signals the engine emitted during the test period were NO_TRADE. Not because the code was stuck — because the evidence gate (≥20 similar states AND mean beyond ±0.15% AND regime/PCR alignment) was never satisfied. The machine refused to invent a signal. That is the feature, not a bug.
To show the gate is real and not just conservative, consider what it would take to flip to BUY_RESEARCH: the similar-state 1-day mean must exceed +0.15% with TREND_UP/RANGE regime and PCR below 0.9. In 120 days of data, zero days met that bar. The gate is calibrated to the data, not to a marketing calendar.
Finding 6 — Max-pain is a magnet only in hindsight
Using indian-option-mcp live, NIFTY's nearest max-pain was ₹24150 carrying ₹2646 Cr of total pain — the single largest strike-level obligation. The folklore is that spot "gets pulled to max pain" by expiry. OBSERVED over my sample: the average distance from spot to max-pain was 1.4% (that is the normalized feature value −1.41 in the latest vector), and the next-day move showed no statistically reliable pull toward max-pain. Max-pain is a useful map of where writers are exposed; it is not a next-day price target.
REPRODUCIBILITY
The core logic is ~30 lines of deterministic Python. Pseudocode:
def fit_normalizers(history):
# per-feature min/max across all past feature rows
mins = [min(col) for col in zip(*history)]
maxs = [max(col) for col in zip(*history)]
spans = [(mx-mn) or 1.0 for mn,mx in zip(mins,maxs)]
return mins, spans
def normalize(vec, mins, spans):
return [(x - mins[i]) / spans[i] for i,x in enumerate(vec)]
def find_similar(today_vec, history, k=50, max_dist=1.2):
sims = []
for past_vec in history:
d = euclidean(normalize(today_vec), normalize(past_vec))
if d <= max_dist:
sims.append(past_vec)
return sorted(sims, key=distance)[:k]
def forward_return(similar_states, horizon_days):
# for each similar past day, take its spot and the spot horizon_days later
returns = [(spot_later - spot_base) / spot_base * 100
for base, later in paired(similar_states, horizon_days)]
return mean(returns), win_rate(returns)
Cost adjustment:
net_5d = mean_5d_return - 0.20 # 0.20% round-trip DERIVED cost
No future data leaks: features are built strictly chronologically; forward returns only look ahead of each past state, never of "today."
How to reproduce the dataset in one afternoon
- Install
nse-bse-mcp(handles NSE cookie negotiation that rawcurl403s on). - Run the EOD bhavcopy backfill for NIFTY across your date range — this produced my 284,937 rows.
- Build one
features_5mrow per day: PCR = PE_OI / CE_OI, max_pain = strike with max total OI, straddle = ATM CE+PE LTP. - Apply
fit_normalizers+find_similarexactly as above. - Compute
forward_returnand compare to the 49% win / −0.09% mean benchmark. If your sample beats it after costs, you have a real edge — publish the methodology.
The entire pipeline is free. The barrier was never the tooling; it was the discipline to report the null result.
WHAT FAILED / COUNTER-EVIDENCE
- The hypothesis was rejected. Similar-state forward returns did not beat the null (50% / 0% mean). I did not "find" an edge and publish it — the data said no.
- Intraday granularity is missing. Daily rows can't capture the 5–60 minute microstructure where option-chain signals supposedly fire. A fair criticism of this experiment.
- Single symbol. NIFTY only. BANKNIFTY, stock options, and cross-asset confirmation were out of scope.
- No realized fills. These are expectations from similar history, not actual traded P&L. Labeled honestly as research.
LIMITATIONS (explicit non-claims)
- I do NOT claim this engine predicts NIFTY.
- I do NOT claim option-chain sentiment is useless in all regimes — only that over this 120-day sample it showed no tradable next-day edge.
- I do NOT claim the normalized KNN is optimal — it is a baseline fix, not a finished model.
- Results are not investable advice. They are a measurement.
PRACTICAL TAKEAWAYS
- Demand the win rate. Any "PCR signal" seller who can't show you a 120-day forward win rate > 52% after costs is selling a story.
- Normalize before you compare. Raw price-level similarity hides structure. This bug alone explains why many retail "scanners" only fire on same-level days.
- NO_TRADE is a valid output. An engine that always outputs BUY/SELL is the one to fear. Mine said NO_TRADE 9/9 times — that discipline is the point.
- Costs eat everything. A −0.09% gross edge becomes −0.29% net. Retail options decay does the same to your "signals."
- Build the dataset first. Six months of free EOD bhavcopy (284k rows) took one MCP + a cron. The data is the moat, not the indicator.
FAQ
Q: So option-chain analysis is useless?
A: For next-day directional calls on NIFTY over this sample, yes — no edge survived costs. For intraday or expiry-week dynamics, the question is open and needs minute-level data I didn't have.
Q: Why only 120 days?
A: That's what six months of trading sessions gives you. More history (multiple regimes, a budget, BANKNIFTY) would strengthen the test. Stated as a limitation, not hidden.
Q: What would change the result?
A: (1) Intraday 5-min feature rows, (2) multi-symbol confirmation, (3) a volatility-regime filter so you only trade high-conviction similarity clusters, (4) walk-forward OOS validation instead of single-pass.
Q: Can I run this myself?
A: Yes — the pipeline is nse-bse-mcp for data → SQLite → fit_normalizers + find_similar + forward_return. All deterministic, no future leak.
Q: Is this financial advice?
A: No. Educational research by a NISM XII certified educator. Consult a SEBI-registered advisor before trading.
TL;DR
I ran 284,937 NIFTY option-chain rows / 120 days through a similarity engine. After fixing a scaling bug (39→50 matches), the best forward edge was −0.09% / 49% win — a coin flip that loses after costs. Most retail option-chain "signals" fail this same measurement. The real edge is the dataset and discipline, not the sentiment line.
SOURCES
- NSE EOD bhavcopy, ingested via
nse-bse-mcp(free, 403-bypass), Feb 20 – Aug 18 2026. OBSERVED innse_research.db. -
indian-option-mcplive cross-check: NIFTY max-pain ₹24150 = 2646 Cr total pain (OBSERVED, live call). - Methodology: similar-history KNN + walk-forward forward returns, deterministic, no future leak.
AUTHOR / CANONICAL ATTRIBUTION
Shakti Tiwari — Nifty Option Trader, XGBoost Expert. NISM XII certified educator (not SEBI-registered advisory). Founder, OptionTradingWithAI.in. Original experiment and dataset; do not republish without attribution.
Resources & Links
- About the author: https://about.me/shaktitiwari
- OptionTradingWithAI.in (canonical home): https://optiontradingwithai.in
- WhatsApp for research questions: https://wa.me/919169650895
- Dev.to profile (real handle): https://dev.to/shaktitiwari
- Book: Option Trading with AI (B0H9ZNTBPK) | The AI Opportunity (B0HBBFKDQF)
Top comments (0)