The Backtest That Changed the Strategy
How point-in-time validation on a Nifty 500 momentum scanner killed a tight-stop swing design, and what replaced it, verified two independent ways.
I built a rules-based scanner that ranks the Nifty 500 every evening on ~15 technical/volume signals, partitioned across large, mid and small cap. The first version used tight stops and fixed profit targets. It looked reasonable, and it was wrong: a proper backtest showed the stop mechanism was bleeding away the exact edge it was supposed to protect. I rebuilt the exit logic around holding longer with a wide disaster-stop instead, and the redesigned system now beats the Nifty 500 by an estimated +3.32% per pick before costs (+2.82% net of an assumed 0.5% round-trip cost), verified two independent ways. It's still early: one market regime, survivorship-biased sample, and I say so below, not after.
Retail trading advice is untestable noise
Every finance Telegram channel has a "buy this, target that" call. None of them show you the losing calls, the drawdown, or what happens if you'd mechanically followed every pick for a year. I wanted the opposite: a system I could actually grade, rules-based, interpretable, and backtested against the index it's trying to beat, not trusted on faith.
A nightly scanner, not a tip sheet
After market close it pulls NSE bhavcopy and delivery data into SQLite, computes ~15 technical and volume indicators per stock, and scores every name in the Nifty 500 on a single positional trend horizon, held roughly 60 trading days. Names are partitioned by market-cap tier (large, mid and small cap) so a handful of volatile small-caps can't swamp the list. A same-day Gemini pass tags news sentiment and broker calls. The composite ranks a cap-tier-partitioned, sector-capped Top-9, emailed daily with position levels attached.
↓
~15 indicators → composite trend score (60d hold)
↓
Gemini news gate ◆ delivery floor 45% ◆ cap-tier partition ◆ sector cap
↓
Top-9 daily email → self-grading pick ledger
None of that is the interesting part of this story. The interesting part is what happened when I stopped trusting the scoring and started backtesting the exits.
The first design looked disciplined. It wasn't.
Version one was a classic swing-trading setup: a fixed profit target, a tight stop, and a minimum 2:1 reward-to-risk filter before a name even qualified for the daily Top-N. On paper that's textbook risk management. Hold for a week or two, cut losers fast, let a favorable R:R do the work.
A point-in-time backtest, no lookahead, spot-checked against the actual production scoring code, said otherwise. Two findings stood out:
- The stop was the problem, not the protection. A simple buy-and-hold version of the same picks beat the benchmark index on 51% of trades. The tight-stop version, on the identical picks, only beat it on 42%, because 70% of trades were getting stopped out before the underlying trend had a chance to play out.
- Alpha rose with hold length. Across matched windows, the longer a pick was allowed to run, the better it did relative to the index. The tight exit wasn't reducing risk. It was capping the exact upside the scoring was correctly identifying.
The ranking signal was fine. The trade structure wrapped around it was actively destroying value. Good stock-picking, bad risk management, and the backtest is what made that visible instead of assumed.
The redesign
I rebuilt the exit logic from scratch, in stages, each one tested against the same live objective before it shipped:
- Hold length moved from 5 to 10 trading days, first out to 30 to 45, and after later rounds of testing, to the current 60 trading days, long enough for the trend signal to actually resolve.
- The tight stop and fixed target were replaced with a wide disaster-stop (roughly 4x ATR, clamped to 10 to 25% of price), a blow-up guard, not a noise filter. No fixed target: let the winners run, exit on time or on the disaster stop.
- The 2:1 reward-to-risk gate was retired. It had been quietly selecting for exactly the tight-stop geometry that was losing.
- The universe itself later widened from the Nifty 200 to the full Nifty 500, partitioned by cap tier so mid and small-cap names, where a real part of the edge lives, get their own dedicated slots instead of being crowded out by large-caps.
Verified two ways, not asserted once
I don't trust a single backtest number, so the current alpha is computed two independent ways: a direct mean-return comparison against the benchmark, and a separate trade-by-trade ledger simulation. Both land on the same net figure, +2.82% per pick, to the basis point. If they hadn't matched, I'd have assumed a bug before a discovery.
| Metric | Value |
|---|---|
| Mean pick return, 60-day hold, net of cost | +1.89% |
| Nifty 500 buy-and-hold, same windows | -0.93% |
| Alpha per pick, net of cost | +2.82% |
| Alpha per pick, before cost | +3.32% |
| Picks that beat the index | 46.7% |
| Statistical significance (t-stat) | +7.1 |
The headline number is the pre-cost alpha: +3.32% per pick against the Nifty 500, which is what most public discussion of a strategy's edge actually means by alpha. Net of an assumed 0.5% round-trip trading cost, a deliberately conservative estimate, it holds up at +2.82%, with a t-stat of +7.1, a strong result for a sample this size. Absolute returns look small in places because parts of the backtest window were flat to down for the index. The edge is index-relative, which is the only version of "working" that means anything for a stock-picking system.
Rigor mostly means saying no to yourself
The pivot was the headline finding, but the same discipline applied everywhere else turned up smaller, equally important results, including a few ideas that looked promising and did not survive scrutiny.
What I got backwards the first time
Same-day delivery percentage, a proxy for real accumulation versus speculative intraday churn, looked like an obvious quality filter. Requiring a high floor to qualify seemed to help, at first: an early test using a swing-trading risk-multiple metric showed it roughly doubling per-trade outcomes. That metric turned out to be the wrong one to trust. Tested against the real objective, index-relative alpha net of cost, the result reversed: raising the delivery floor further actually hurt returns, because it tilted the book toward low-beta large-caps and away from the mid-cap names that carry most of the momentum edge. The floor came down, not up, currently 45%, versus an earlier 55%. It isn't zero either: some of what a delivery floor protects against, a thinly-traded name that later gets delisted or manipulated, is invisible to a backtest built on today's surviving universe. So the floor stays in place as insurance against a risk the backtest structurally can't see, even though the backtest itself argues for going lower.
What didn't survive scrutiny
- Tightening the sector concentration cap and excluding freshly-extended breakout names were both tested. Neither cleared the bar for a real, out-of-sample improvement, so both stayed at their defaults.
- A regime filter that only trades when the index is above its own 50-day average looked good in-sample and worse out-of-sample, the textbook signature of overfitting. Left out.
The news layer stays a gate, not a vote
I ran a market-neutral event study on the Gemini-tagged news sentiment and broker calls, de-meaning each day against the overall market move so a bad day for the whole index doesn't masquerade as a bad signal for one stock. Once de-meaned, neither news tone nor broker calls showed a reliable edge. Rather than force a weight onto a signal that hadn't earned one, it's used only as a downside veto: bad news can keep a stock out of the Top-9, but no news doesn't put it in.
Every one of these decisions came from the same rule: a backtest and a self-grading ledger beat conviction. If I can't measure it, it doesn't ship as signal, it stays a gate, an idea, or a rejected experiment.
Backtest design
The backtest reuses the exact production scoring and indicator code, no separate reimplementation to drift out of sync with what's actually emailed. It's point-in-time and spot-checked for lookahead: on any given day, only data that would have actually been available that evening feeds the score. Every live pick is also graded automatically against the Nifty 500 as it matures, so the backtest isn't the only proof. There's a running, real-time track record behind it too.
Show backtest internals
Sample: 280 trading days (2025-06-19 to 2026-08-06), current Nifty 500 constituents partitioned into large, mid and small cap, 1,610 completed Top-9 trades on the single Trend sleeve.
Reconciliation: alpha computed by a direct mean pick-return-vs-benchmark comparison, and independently by a trade-by-trade ledger simulation. Both return the same net alpha, +2.82% per pick, t = +7.1.
Drift check: rolling quarterly alpha strengthened through the sample, from -0.9% in the earliest quarter to +6.0% in the most recent one; the most recent 536 trades still show +6.23%. Standing verdict: edge stable, rechecked weekly rather than trusted as a one-time result.
What's deliberately excluded: the news/broker layer stays a downside-only gate, not a weighted input, because it hasn't earned one in testing. A separate monthly fundamentals overlay exists and is validated independently, not blended into these numbers.
Where I'd push back on my own numbers
- Survivorship bias. The backtest universe is today's Nifty 500 constituents. Names that got delisted, demoted, or blew up along the way aren't in the sample, which biases the results optimistic.
- One market regime. The window covers roughly 14 months that were mostly flat to down for the index. It hasn't been tested through a strong sustained bull run or a sharp crash, and I wouldn't claim it has.
- Costs are estimated, not measured. The 0.5% round-trip figure is an assumption, not a broker statement. The live ledger will eventually replace it with real fills.
- It's a ranking tool, not an oracle. Scores are technicals-and-volume-dominated by design. The fundamentals overlay exists as a separate gate on a separate book, and I'd rather under-claim what each signal contributes than round up.
Still building
- A true index-level Nifty price series, to unlock rolling beta and a cleaner relative-strength read. Today it leans on a tradeable proxy instead of the real index.
- Forward-collecting more history on a promoter shareholding-change signal that's now live in the separate monthly quality book, since the current read is still statistically underpowered.
- Wiring an institutional bulk and block deal footprint signal, now that the Nifty 500 universe actually reaches the mid and small-cap names where those disclosures cluster.
- Extending the monthly quality book to the full Nifty 500 universe. It's still scored against Nifty 200 today.