**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:
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
1. Install `nse-bse-mcp` (handles NSE cookie negotiation that raw `curl` 403s on).
2. Run the EOD bhavcopy backfill for NIFTY across your date range — this produced my 284,937 rows.
3. Build one `features_5m` row per day: PCR = PE_OI / CE_OI, max_pain = strike with max total OI, straddle = ATM CE+PE LTP.
4. Apply `fit_normalizers` + `find_similar` exactly as above.
5. Compute `forward_return` and 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
LIMITATIONS (explicit non-claims)
PRACTICAL TAKEAWAYS
1. **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.
2. **Normalize before you compare.** Raw price-level similarity hides structure. This bug alone explains why many retail "scanners" only fire on same-level days.
3. **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.
4. **Costs eat everything.** A −0.09% gross edge becomes −0.29% net. Retail options decay does the same to your "signals."
5. **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
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.
---