Honest re-run: −69.5%; the apparent wins were bugs.
Notebook 01 · April – August 2026
Four months of market research on 252 million rows of Indian equity and index-option history. It set out to find a signal and ended up building an instrument that can prove, cheaply and repeatedly, that a signal is not there.

It started as a Flask dashboard scanning NSE equities for CPR, Camarilla, relative strength, reversals and fractal coils. The organising idea was a timeframe ladder — weekly reads yearly levels, daily reads monthly, four-hour reads weekly, and everything intraday reads the day.
The first data came from Yahoo Finance, and nine of those first 512 files were not Indian equities at all: crude, gold, copper, natural gas, palladium, platinum, silver, corn, wheat. There was a multi-asset scope, and it got dropped. Narrowing to NSE equity and index options was a deliberate early call, and the abandoned commodity leg is the evidence of it.
The timeframe ladder survived the entire project as a way of looking. It died as an edge.
Upstox OAuth, the Nifty 500 matched against the instrument master, and a hive-partitioned parquet store — daily candles back to 2000, minute candles from 2022.
The detail that mattered was in the cleaner. Session detection became coverage-based and era-relative: a date counts as a real trading day only if at least a fifth of that year’s active symbols traded. Before that fix it had been silently discarding pre-2010 days, because it was judging 2004 by how many symbols trade in 2025. Rows are removed; values are never touched.
Clean by a rule that assumes today’s market and you will quietly delete the past.
Camarilla long and short, CPR long and short, confluence long and short, across six timeframes, through three generations of engine.
The acceptance checklist was written down before anything ran: expectancy-per-risk at or above 0.10, at least 300 trades, profit factor 1.25, at least 40% of symbols profitable, drawdown no worse than 20R. Settled design decisions were logged as “do not revert” with the reason attached to each.
This is the point where it stopped being scripts and became a discipline.
Walk-forward logistic scoring ranked trades by win probability, and it worked: out-of-sample, the top quartile hit 75–92% win rate against 42–44% for the bottom. Futures were modelled with real lot sizes and margin. Options were priced off actual bhavcopy premium rather than a formula. A live scanner ran on the Upstox REST API.
The headline was a Sharpe of 3.88, a maximum drawdown of −5.7%, and a book that survived 2008 down only 4%.
Every number in that paragraph is wrong. The next entry is why.
Entry was booked at the level. But the signal only confirms once a bar closes beyond that level — on daily data, about 1.95% beyond it. You cannot fill at a price the bar has already left. The entire modelled edge was living inside that gap.
| Sleeve | Modelled @ level | Enter at close | Retrace limit | Verdict |
|---|---|---|---|---|
| cam_daily_long | +1.64% | −0.30% | −0.29% | DEAD |
| cpr_daily_long | +1.72% | −0.23% | −0.14% | DEAD |
| cam_1H_short | +0.50% | −0.13% | −0.04% | DEAD |
| cpr_1H_short | +0.51% | −0.14% | −0.06% | DEAD |
Flip between the two and watch every sleeve cross the line:
The signal is a lagging report that the move already happened.
Then we tried to rescue it. A stop order resting at the level fills on the touch, in real time — but it drags in exactly the fakeouts the closing confirmation had been screening out, roughly half of all touches, each losing between 0.6% and 2.7%. Three leading filters were pre-committed before testing — volume on approach, ADX primed, higher-timeframe trend. None of them clears cost. ADX made the daily book actively worse.
Four more biases fell out of the same audit. Survivorship inverted the trust ordering: the universe is the 2024 F&O list projected backwards, so the long history is the most contaminated, and that famous −4% in 2008 is the book largely sitting the year out — thirteen trades against a normal fifty-four to sixty-nine. Capacity was fiction, arithmetic over tens of thousands of signals. Slippage was uncalibrated and charged nothing on entry. And the structure itself — which family, how many sleeves, which exits — had been chosen in-sample.
Out of this came an audit lens: eight failure classes, ordered not by theory but by how often each one has actually killed an edge in this repository. Every later idea was run through it before it was believed.
One thing did survive the teardown, and not as a strategy. If the breakout side is dead because half of all touches fail, then the failures themselves are a population worth watching. That became a tab — and the tab argues with whoever opens it:

Brokerage is close to zero through the API, so the real costs are securities transaction tax and slippage. We rebuilt the round trip per vehicle from its components: 0.238% for cash delivery, 0.035% for cash intraday, 0.026% for futures. Spread was estimated with Corwin–Schultz, market impact with a square-root law.
Relative strength, index regime and breadth are a risk dial, not a return booster. Tested both ways, they work as gates and add approximately nothing as scoring features.
Two gigabytes of one-minute option chains across twelve underlyings, including expired contracts pulled through the expired-instruments API. We built the scalp book and ran it forward on paper.
Buying short-dated premium intraday is negative carry. It loses on average, always. What had looked like a momentum fade was entirely expiry-day theta, and cutting by days-to-expiry proved it.
This programme was retired by decision rather than by statistics — and the repository records which of the two it was. They are not the same thing and should not be filed together.
Instead of hand-coding hypotheses one at a time, we built engines whose purpose is to reject them.
A describer that cannot p-hack — ten low-redundancy gauges per minute, z-scored using only the past, with outcomes measured from an entry you could actually have got — feeding a judge that demands a chronological split, trains at or before 2025, tests on held-out 2026, nets off costs, and uses robust statistics rather than means.
Alongside it: a hundred pre-registered hypotheses, none testable without approval. A factor zoo of 462 factors that collapsed to roughly two independent bets — size, and momentum, which turned out to be relative strength wearing a different name at a correlation of +0.98. A reinforcement learner trained on real level geometry against an identical agent trained on placebo twins, where the profitable placebo was the alarm.
Machine learning, astrology, Gann geometry and a TradingView indicator all went through the same bar and all died. The astrology engine was verified against Solar Fire to within 1.4 arcseconds first.
Refusing to kill something for the wrong reason is part of killing it properly. A wrong result and a broken implementation look identical from the outside.
We took the machine and pointed it at actual trading records. Two thousand two hundred and fifty-eight trades decomposed: skill lands at p = 0.45, and the profit is one name. Another book’s stated rule is dead, while its discretionary selection is real at p ≈ 0.000 — the trader was good at something other than the thing they believed they were doing. A +68.3% run over ten days turned out to have an entry that fails four different ways. A VCP playbook sign-flips on every lever when you move it from the F&O list to a wide universe, which is survivorship.
Traders cannot tell you what they actually do. The stated rule and the executed rule are different objects, and only one of them is in the data.
The integrity checker had gone fifteen days without an update and was covering three of seven stores — because it enumerated what to check. Adding a store broke nothing; it simply went unchecked, forever. Meanwhile it was globbing one filename pattern while 499 symbols carried 55,457 duplicate rows under a different one, and it reported clean. Three orphaned dashboard processes were squatting on ports, one of them twenty-five hours old.
A checker that names what it checks can only find bugs in what it names.
The fix was architectural rather than diligent. A registry file became the declared desired state — every store, every service, every port. The session manager discovers what is actually on disk and running, and fails if anything is not declared. Add a directory and preflight goes red until you declare it.
Drift is a failure, not a silent skip.

A positional momentum book on relative strength went to forward paper trading. Then we tested it against a thousand dart-throwing placebos.
The selection is real — it beats random name-picking. But its Sharpe lands at roughly equal-weight buy-and-hold, which is a much less interesting claim. And the 48% compound headline splits into 85% across 2021–23 against 13.7% across 2024–26.

Quote the regime numbers, never the headline. A single figure spanning two regimes is an average of two different businesses.
We swept the public internet across six lanes looking for mechanical systems and found the same thing everywhere: there is no undiscovered entry signal out there. What the literature genuinely offers is the risk layer.
Ding’s generalisation of Grinold gives the frame — information ratio is capped at IC divided by the volatility of IC, regardless of how much breadth you add. More bets cannot rescue an unstable signal.
| Pre-test | Result | Consequence |
|---|---|---|
| AR(1) on monthly realised variance | +0.114 (US momentum: +0.578) | Volatility scaling discounted |
| Effective number of bets | 10 names = 1.3 bets | No sizing scheme can fix it |
| Autocorrelation of own returns | +0.126 (universe: +0.004) | Drawdown stops back on the table |
The last thread pointed the instrument at its own operator. Four rounds of interviews — one spoken, twenty-two minutes, transcribed rather than translated so the Hinglish trading vocabulary survived intact; three typed, verbatim. The goal was to write down the discretionary system that actually gets traded, as a specification.
The specification surfaced a reframe that invalidates every mechanical test that came before it. The target is 0.7–0.8% in the underlying, which becomes roughly 10% on the premium, and then the position is closed. The daily level everyone was testing against sits 5–6% away, and is deliberately not the target.
The system never needed the entry to predict direction. It needed the position to visit a small favourable excursion.
That is a question about the path a trade takes, not about where it ends. Every test in the repository up to this point had measured endpoints.
So we pre-registered 104 cells, split train at or before 2023, test across 2024–25, holdout 2026. Cells clearing the null at p95, after cost, after a red-team pass: zero. Best net expectancy: −12.95 basis points per trade. Random entry on the same stock-days beat the best signal by about ten points of compound annual return. Two candidates survived the first pass, were independently re-derived from raw data by separately written code, reproduced exactly — and were then destroyed by attacks that reversed their sign. A clean null, not an inconclusive one.
The durable output is not a signal. It is this, measured on a real account’s actual behaviour:
| Leverage | With de-sizing | Without de-sizing |
|---|---|---|
| 1× | +4.7% CAGR · −15.7% DD | +6.9% · −19.3% |
| 3× | +7.8% · −28.4% | +16.8% · −49.9% |
| 10× (ATM-call proxy) | +9.2% · −53.6% | −0.6% · −94.9% (p5: −99.7) |
Positive expectancy and survival are different properties. A book can have the first and still reliably destroy the account that trades it.
Every hypothesis we ran to a conclusion, with the finding that ended it. Forty-one are dead. We are naming all of them, because a list of what did not work is the only honest way to read a list of what did.
Hover any dot. Each one is a hypothesis, placed on the month it was concluded and coloured by its verdict.
Honest re-run: −69.5%; the apparent wins were bugs.
Rupee edge ≈ ₹0 — always judge option strategies in RUPEES, not percent.
21+ hypotheses dead. Fully closed.
Selection skill dead (clustered p=0.45); the profit was BHARATFORG concentration in a bull tape.
All timeframes dead. Do not re-test.
0/16 configs net-positive held out.
Worse than the simple Nifty-SMA gate on the same book.
Can't distinguish winner-pausing from loser-topping.
Can't predict break-vs-fake; its confidence gate was a volatility proxy.
No replicating signal; BankNifty monthly-only kills the vehicle anyway.
The 1-min lead was an index-staleness artifact; the ~11pt fade bounce was the only real structure.
Loses to the live pb=18/28 config OOS; its apparent wins were mislabels.
No filter cuts the big losses — they're irreducible; manage via SIZING.
Both worse than baseline; the blowup was variance, not a fixable rule.
Entry booked at the level but confirmed at the close ~1.95% past it — the whole modeled edge lives in that un-gettable gap. No entry (lagging, leading, filtered, LTF-confirm) recovers it.
Momentum continuation, reversal, compression-straddle: all dead to THETA. Buying short-dated premium intraday is negative-carry, always. Only SELL-theta or swing-underlying can survive.
Kickoff → pullback → breakout: all 8 cells dead.
The apparent edge was plain 21-EMA trend; the CPR component flips sign train→test.
Every mechanical setup dead or beta; the best book loses to a 200-SMA filter. The untested residue = discretion → journal.
All four sign-flip train→test.
Index/equity ORB + candlestick confluence dead across the chapter. Don't re-test.
7/7 dead; only futures-basis remains scoped (not built).
Exits are a solved, dead lever for the RS book — every rework tested worse.
v1 AND faithful v2: 0/436 combos held out; the '90% WR' was false; re-test on real futures volume also dead.
2nd-best RS name vs the leader = coin flip.
Dead 6 ways — coil subtracts value as a mechanical entry or long-vol proxy. Only compression↔expansion MAGNITUDE survived (not direction).
Trigger, fade, gate, exit, sizing all closed (fade real but illiquid + decayed). Root: it can't pick the trade — the losing bar arrives unannounced.
Both dead on the real futures volume/OI store (spot index volume is 0 forever — futures is the only real index orderflow source).
~29M events vs 3 null models: Gann never beats equidistant/random-phase nulls; the √-geometry adds nothing.
75k events: the long-side profit was pure drift; level-breaks dead BOTH directions.
H2 drift dead; H3 open-reversion real on the un-gettable auction print, −0.4 bps at a real NIFTY_FUT fill; H5 flat.
Every lever sign-flips FNO→wide universe = survivorship, not edge. Lesson: report the wide universe first.
The WINDOW is real (3.9x more travel after minute 1, ~1.5% to close) but nothing calls direction: blind test n=25, model 52% vs always-DOWN 56%; biggest beat FELL.
Spread sign-flips train→test (−10.2% @20d held out). The ratio was a size-factor proxy measuring smallcap-vs-largecap rotation.
0/6 families survive: real gross +2..+6 bps/leg everywhere, all under the ~6 bps zero-slip cost floor. X4 lead-lag was the cleanest signal (futures data could revive it).
His +68.3%/10-day book decomposed: entry dead 4 ways (114k events, all cells premium-negative). The engine was 68% base-rate × 10.7x payoff × hold-through; UNOMINDA rule-break = 44% of net.
Fade-retail, follow-FII, lottery-peak primaries all dead on participant_oi 2022-26.
CPR's 7th death. Models match placebo-level twins; RL with ₹-reward learned all-skip (discovered cash). A yday_ret lookahead survived every kill-test EXCEPT permutation importance — a profitable placebo IS the alarm.
462 factors collapse to ~2 independent bets (SIZE + MOMENTUM≡RS corr +0.98); the 12m-RS upgrade died inside the real GATI book — decile results don't transfer to a filtered book.
1.85 bps gross per leg vs the ~7 bps cost floor — independently replicates the xsec wall.
Progressed-Moon 15° grid on 435 NSE names / 75.5k flips: timing, direction, and a 12-config sweep ALL chance; placebo group identical. Engine verified vs Solar Fire ±1.4".
Validated OOS as CONTEXT (fade backdrop), not direction; max-pain dead; as a scalp filter it HURTS.
The drawdown-cut replicates; built into minervini_signals.py. A risk dial, not a return booster.
States are real; every tradeable use tested is dead. Open lead: weekly-context.
Works but weaker than headline; gap-fill variant DEAD.
Sector rotation discount; TS trend + 52wk-breadth DEAD; FII/DII history too short.
The stated mechanical rule is DEAD, but discretionary selection is REAL (p≈0.000). The leak was holding past entry day → journal + risk rules.
User decision: no edge worth the execution risk. Honest numbers were execution-gated (first-candle fills); daemon + tape KEPT for research.
Descriptive intraday expansion/contraction gauge with validated persistence — context lens on the Today tab, not an entry signal.
Both DO exist (/v2/news, /v2/fundamentals/{isin}/income-statement) — structured quarterly rev/PAT replaces PDF parsing. Gotchas documented.
v1 built + dry-run validated (whole-market resolver, Haiku gate + Opus map, immutable journal). Blocked on an Anthropic API key in .env.
Reproduces the YouTube macro-funnel + micro-tightness scores with a subjectivity meter. Shape-not-direction guardrail; Nifty500 only.
3s-tape episode detector at levels for USER discretion; replay-and-correct pending. Pine can't ingest external data → TV overlay via MCP.
The ONE held-out-positive lead from the barrier scan: delta-neutral short premium. Needs cost + tail validation before any capital.
Real next-day risk signal, incremental over lagged vol, holds on both halves — awaiting a book to gate.
IC +0.10 on both splits but 2026 flat — DISCOUNT lead, forward-track only.
The momentum edge lives overnight/positional; intraday expression dead. Foundation of the GATI book.
Long-only leg: CAGR 50.1% / Sharpe 1.28 after the lookahead patch. Short leg dead. Became the GATI book's ancestor.
RARE survivor: spread real at +35/+57 bps/mo held-out, cost-robust. Absolute CAGR is survivorship fiction; transplant into the Minervini book DEAD.
The compounding book. Headline '48% CAGR' splits into 85% (2021-23) vs 13.7% (2024-26) — quote regime numbers. N=5 concentration, leverage, faster-rebalance all tested and REJECTED. ₹5L forward paper test running.