Data engineering · Quantitative
Acumen
A trader asked whether his strategy made money. Ten years of data said no — and the whole repository exists to make that answer hard to disbelieve.
Built
2026
Stack
- Python
- pandas
- pyarrow / Parquet
- SmartAPI
- pytest
No live demo — it is a local command-line tool that reads a 4.1 GB Parquet lake.
01 — The problem
Anyone can build a backtest that agrees with them.
A discretionary trader had a written intraday strategy he believed had an edge. The hard part was never running it. The hard part was running it in a way that could survive him not liking the result.
So the rules were frozen first, in a specification the code is never allowed to alter, and then replayed with no human judgement anywhere in the loop — every signal, every stock, no discretion, no skipped days. The strategy owns the rules; the engine only executes them.
It lost money in all eleven calendar years walked.
- Trades taken
- 1,88,345
- across 204 stocks and 2,428 trading days
- Net result
- −₹1.68 cr
- against ₹1,00,000 of starting capital
- Years negative
- 11 of 11
- every calendar year in the span
- Test cases
- 2,621
- verified by running the suite, not by reading the badge
The whole result is one 3.07-point gap.
The strategy has a small positive edge before costs and a decisively negative one after. Every round trip costs ₹100 against ₹1,000 of risk — ten per cent of the money at stake before the market has moved at all — and the strategy takes 188,345 of them.
The cost is the entire story
What the trades made before commission, what commission took, and what was left.
Source docs/validation/trader_pack.md
Table
| Step | Amount |
|---|---|
| Before costs | ₹19,98,482 |
| Commission | −₹1,88,34,500 |
| Net result | −₹1,68,36,018 |
Reduced further, the ten-year loss is a single number missing its target. With this strategy’s own average winner and its own average loser, both after costs, it needed to win 34.60% of its trades to end level. It won 31.53%.
It won 31.53%. It needed 34.60%.
Break-even is computed from the strategy’s own average winner and loser, not from a rule of thumb.
Two populations appear in the report: 31.53% over all 188,345 trades, and 31.54% over the 188,305 that were not flat. The figure used here is the one over every trade taken.
Source docs/validation/trader_pack.md
Table
| Measure | Value |
|---|---|
| Win rate | 31.53% |
| Break-even win rate | 34.6% |
| Shortfall | 3.07 points |
| Winners | 59,385 |
| Losers | 1,28,920 |
| Flat | 40 |
| Profit factor | 0.8708 |
| Expected payoff per trade | −₹89 |
Not one good year to point at.
A losing strategy usually has a year that flatters it — a bull run, a volatile quarter, something to argue from. This one has none. Every bar is below the line, and the account never recovers the high it set on its fourth trading day.
Net profit and loss by calendar year
Eleven years walked, all negative. Hover any bar for its trade count and win rate.
2016 covers October to December only — minute data begins 2016-10-03 — and 2026 is clamped at 2026-07-30. Neither is annualised. The best full year is 2018, still at −₹11.79 lakh.
Source docs/reports/chunk9b_backtest_report.md
Table
| Year | Trades | Win rate | Net P&L |
|---|---|---|---|
| 2016 | 3,530 | 30.74% | −₹2,25,599 |
| 2017 | 14,868 | 29.77% | −₹16,81,334 |
| 2018 | 16,060 | 30.86% | −₹11,78,850 |
| 2019 | 17,016 | 30.12% | −₹19,89,896 |
| 2020 | 18,160 | 30.78% | −₹18,90,255 |
| 2021 | 19,195 | 31.36% | −₹17,18,597 |
| 2022 | 21,067 | 31.88% | −₹16,60,157 |
| 2023 | 20,796 | 31.38% | −₹20,98,184 |
| 2024 | 21,732 | 32.9% | −₹13,00,023 |
| 2025 | 22,416 | 32.8% | −₹19,43,791 |
| 2026 | 13,505 | 32.88% | −₹11,49,333 |
Account equity, year by year
Starting capital ₹1,00,000. The line crosses zero during the first year and never returns.
Closing equity is −₹1,67,36,018.20, which is the ₹1,00,000 of capital plus the −₹1,68,36,018.20 of net P&L. The two figures differ by exactly the starting capital.
Source docs/reports/chunk9b_backtest_report.md
Table
| Year end | Equity |
|---|---|
| start | ₹1,00,000 |
| 2016 | −₹1,25,599 |
| 2017 | −₹18,06,933 |
| 2018 | −₹29,85,783 |
| 2019 | −₹49,75,679 |
| 2020 | −₹68,65,934 |
| 2021 | −₹85,84,530 |
| 2022 | −₹1,02,44,687 |
| 2023 | −₹1,23,42,871 |
| 2024 | −₹1,36,42,894 |
| 2025 | −₹1,55,86,685 |
| 2026 | −₹1,67,36,018 |
The engineering is all in the audit trail.
Money is held in integer paise, never floating point, so the ledger reconciles exactly rather than approximately: gross 199,848,180 paise minus costs 1,883,450,000 equals net −1,683,601,820, and the report recounts it row by row before it prints. The volume-profile point of control is computed with exact fractions for the same reason.
Four pure deterministic functions carry the strategy. The same four drive a live Telegram screener that places no orders and never can — a structural guarantee, not a configuration flag. The screener was checked against the backtester over a fifteen-day sample and agreed candle for candle.
- Source
- 49 modules
- 42,822 lines across the engine
- Test cases
- 2,621
- 102 test files, 0 failures
- Review reports
- 28
- committed adversarial reviews under docs/reviews
- Data lake
- 4.1 GB
- 4,95,312 symbol-days of minute candles
What it deliberately does not do
-
It never places an order. The screener watches and sends a Telegram alert. A human always trades. That is enforced in the code path, not left to a setting.
-
It does not correct for survivorship bias. The universe is today’s F&O list walked backwards, so a stock that left the index is absent and one that joined in 2024 is walked from 2016 anyway. That flatters any strategy trading liquid large caps. The report discloses it rather than quietly fixing it.
-
It does not size positions realistically. The trader asked for the honest numbers with no limits, so every signal is taken. With no capital constraint the book peaked at 90 concurrent positions against ₹1 lakh of capital — which no real account could carry. Section 11 of the report measures the size of that assumption instead of hiding it.
What it gets wrong
One calibration is still open: which volume-spreading method matches TradingView’s own profile. It needs a paid TradingView plan to settle, so it was handed to the strategy owner and the repo runs on the provisional method until his numbers come back.