Bot A — TradingView backtest, 2016-10 → 2026-10
196 NSE stock futures · 4H SuperTrend · LONG only · validated 2026-10-06 ·
RESEARCH — NOT DEPLOYED
Why this page is separate from BT · 5yr Python.
That run stores every trade in SQLite and can be drilled into. This one cannot: TradingView
reports aggregates on the chart, so the figures below are
chart-read totals, not trade-level
data. Nothing here is reconstructed or interpolated — where a number does not exist, it is
marked
not measured rather than estimated.
Headline — risk cap ₹25,000 vs ₹35,000
2,124 / 3,107
trades 25k / 35k
1.539 / 1.385
profit factor
₹2,984 / ₹2,759
net per trade
₹0.181 / ₹0.133
net per ₹1 risked
₹10.3L / ₹20.4L
max drawdown
₹35,000 was adopted — and not because it earns more.
On the pooled 11 years ₹25,000 wins every quality measure. The reason to override that is a
structural break at 2024: NSE raised the minimum F&O contract value to ₹15 lakh in Nov 2024,
lifting lot sizes universe-wide. Since risk_per_lot = stop% × price × lot, a lot
became 2–3× more expensive in risk terms, and a cap sized for ₹5–10 lakh contracts can no longer
reach the current universe.
The deciding split
Both halves of the case for ₹25,000 reverse.
The cap used to drop 21% of signals and keep the better ones. It now drops 64% and keeps
the worse ones.
Year by year
The 11 year rows sum to the batch
totals within ₹2 of display rounding — the year table and the summary are internally consistent.
Per batch (5 × Pine scripts — the engine caps request.*() at 40 calls)
Defect found and fixed during this study — B5 phantom trades.
B5 held 36 real symbols but made 40 runSym() calls; slots 37–40 were left as
input.symbol(""), and Pine resolves an empty symbol string to the chart symbol
(ignore_invalid_symbol does not help — empty is valid). B5 was trading four
phantom copies of whatever chart it sat on.
How it was caught: the same engine was run twice at ₹25,000 on two different chart
symbols. B1–B4 reproduced to the rupee; B5 did not (600 trades / PF 1.48 → 636 / PF 1.75).
Only B5 had empty slots. Guard applied: str.length(s37) > 0 ? c_37 : na.
The published 196-symbol headline was depressed, not inflated, by its phantoms —
that run sat on BAJFINANCE, whose four copies lost ₹124,636. Corrected: 2,124 trades /
PF 1.539 / ₹6,338,944 (previously 2,292 / 1.48 / ₹6,214,309).
Live config parity — what live was changed to match
Three risks accepted on the record.
- The ₹35,000 cap breaks a deliberate safety invariant. Sizing is
contracts = max(1, floor(risk / risk_per_lot)), so the 1-lot floor means a passing
signal is taken even when one lot risks more than the target. Measured in this backtest:
average risk/trade ₹20,696 — 38% above the ₹15,000 nominal, worst case ₹35,000 = 2.33×.
Plan capital on ₹20,696, not ₹15,000.
- Unlimited concurrency makes broker margin the only limit. Entries do reject cleanly
when capital runs out — but if an entry fills and the bracket's SL leg is then rejected for
margin, the position is naked. That is the most repeated failure in this codebase
(BUG-011/018/020/032/034). Harmless while draft mode is on; must be re-evaluated before
going live.
- The stop-distance filter was switched off although it was validated. The 5.5-year sweep
found it helped in every RR/ADX combination — but at mult 0.5, where bands sit close to price.
At mult 2.5 the median stop is 4.74% against a 0.6% floor, so it should rarely bind.
This was not measured.
What this backtest does not model
- No concurrency cap. 2,124 trades assume unlimited simultaneous positions. Live now runs
unlimited too, so margin is the binding constraint instead — a constraint the backtest never saw.
- No margin gate. Real NRML margin is 17.7%–50.2% per symbol and is not applied here.
- Max drawdown — MEASURED 2026-10-06. ₹1,033,528 at the ₹25,000 cap vs
₹2,036,908 at ₹35,000: +97% drawdown for +35% net, net/maxDD 6.13 → 4.21, and ₹25,000
wins 4 of 5 batches on risk-adjusted return. 🚨 Against ~₹13.3L of capital the ₹35,000 figure is
~153% of the account. Caveat: batch drawdowns cannot be summed exactly — the sum is an
upper bound, the worst single batch (₹602,003 / ₹278,574) a lower bound, and for a LONG-only
book the truth sits nearer the sum. The book is also uncapped, so live margin will cut both net
and drawdown by an unknown amount.
- One static lot size per symbol for all 10 years. NSE revises lots as prices rise, so
early-year rupee figures are approximate. Trade counts and win rates are unaffected, and the cap
decision rests on 2024–26 where current lots are roughly right.
- Bar-level exit timing. Prices are exact; the moment inside the bar is not.
- 2026 loses under both caps (−₹347,528 / −₹858,026) and 2023 alone is 34% of all
profit. Neither is addressed by the cap choice.
Evidence & source documents
.claude/evidence/bot_a_tv_backtest_evidence_2026_10_06.md — full audit trail:
method and platform limits, three-way engine verification, every sweep table behind the config
choice, the risk-cap study, the B5 defect with its proof, and the Pine bugs found and fixed.
.claude/guides/bot_a_tv_validated_config_2026_10_06.md — the validated config,
IS/OOS, by-year results, the deployment change set and the three accepted risks.
.claude/guides/bot_a_real_futures_bt_2026_10_02.md — the independent Python study
on real futures prices with lot sizing, historical lots, a real NRML margin gate and a measured
drawdown. It reproduces live's loss at live's old dials (−₹258,164 / WR 31.3% vs live's
−₹213,745 / WR 31.0%), which is what makes its other outputs worth reading.
pine/cap_B1..B5.pine — the five batch scripts behind every number on this page.
Method, in one line: both risk caps
run side by side inside one script, so they see identical signals, bars and lot sizes —
the only difference is the cap test.