quantwala

Methodology

How the Bhav engine turns a strategy into a backtest: the data it uses, how orders fill, what every charge and tax is, and what it does not model. Every figure Quantwala shows about charges comes from the tables on this page, which mirror the engine's cost models in source/bhav/src/bhav/costs/.

Nothing here is legal, tax or investment advice. Rates change by circular; confirm them against your broker's charge sheet and a chartered accountant before relying on them.

Charge rules

Equity and F&O (NSE, BSE)

Source: costs/india_equity.py. Rates effective 1 April 2026 (FY2026-27), after the STT revision that took futures from 0.02% to 0.05% and options from 0.10% to 0.15% of premium (Finance Act 2026; NSE circular NSE/FATAX/73524, 31 March 2026).

A trade is charged at the exchange it is on. NSE and BSE differ only in their own transaction charge (and where NSE's investor protection levy appears); STT, stamp duty, the SEBI fee, GST and DP charges are the same on both. Statutory charges, as a share of each leg's turnover (for options, turnover is the premium, never the notional):

SegmentSTT on buySTT on sellExchange txn (NSE)Exchange txn (BSE)Stamp duty (buy only)IPFT (NSE)
Equity delivery0.1%0.1%0.0030699%0.00375% (groups A, B; others below)0.015%0.0000001%
Equity intradaynone0.025%0.0030699%0.00375% (groups A, B; others below)0.003%0.0000001%
Futuresnone0.05%0.0018299%none0.002%0.0000001%
Optionsnone0.15%0.0355299%0.0325%0.003%0.0000001%

ETFs (a fund's units, which carry an INF ISIN) pay STT as fund units, not shares (Finance (No.2) Act 2004, s.98): an equity-oriented fund's units pay none on the buy, 0.001% on a delivery sell and 0.025% on an intraday sell; gold, silver, debt, liquid and overseas-index ETFs pay no STT at all. The engine tells the two apart from the fund's symbol and name, and takes a fund it can't place as equity-oriented. Every other charge is a share's.

NSE, per crore each side (of premium, for options), a transaction charge plus a contribution to NSE's Investor Protection Fund Trust (IPFT), from 1 March 2026 (circular NSE/FA/73061, 27 February 2026):

NSE segmentTransaction chargeIPFTTotal
Cash market₹306.99₹0.01₹307
Equity futures₹182.99₹0.01₹183
Equity options (premium)₹3,552.99₹0.01₹3,553

From 1 October 2024 to 28 February 2026 the same totals were split ₹297 + ₹10, ₹173 + ₹10 and ₹3,503 + ₹50 (NSE/FA/64232, 27 September 2024; the IPFT from NSE/FA/56129, 24 March 2023). GST is on both parts, so the charge is the same either way. Each line is rounded to the paisa, so the IPFT line reads ₹0.00 on a leg under ₹50 lakh.

BSE, cash market, by scrip group, each side, with BSE's ₹1 per crore Investor Protection Fund contribution already inside the charge (BSE, "Equity Segment Transaction Fees", bseindia.com, read 29 September 2026; notice 20221109-7, from 1 December 2022):

BSE groupPer crore of turnoverShare of turnover
A, B, T, and E, F, FC, G, GC, I, W when also listed elsewhere₹3750.00375%
SME (M, MT, MS, TS), InvITs and REITs (IF, IT), rights (R), and E, F, FC, G, GC, I, W listed only on BSE₹2750.00275%
X, XT, Z₹10,0000.1%
P, ZP₹1,00,0001%

The workspace lists BSE's groups A, B, X and E (below); a group-X stock (listed only on BSE) costs 0.1% a side in exchange charges plus GST on it, which the engine charges. An exclusively listed E-group ETF is charged ₹375 rather than ₹275, a slight overstatement.

BSE, derivatives, at the table's rates. The engine also charges BSE futures and options an IPFT line of ₹5 and ₹50 per crore (of premium, for options), a rate it has always carried that no BSE notice has yet confirmed.

Statutory, both exchanges: STT as above (Finance Act 2026). Stamp duty under the Indian Stamp Act as amended by the Finance Act 2019, collected by the clearing corporations from 1 July 2020: 0.015% on a delivery buy, 0.003% on an intraday buy (NSE, "Stamp Duty"). SEBI turnover fee ₹10 per crore.

On every leg of every segment:

  • SEBI turnover fee: ₹10 per crore (0.0001%).
  • GST: 18% of brokerage + SEBI fee + exchange transaction charge + IPFT. Never on STT or stamp duty.
  • DP charge: a flat amount per scrip when delivery shares are sold (below).

Brokerage, per order (the backtest lets you pick the schedule):

BrokerDeliveryIntradayFuturesOptionsDP charge per scrip sold
Zerodha (default)₹00.03%, max ₹200.03%, max ₹20₹20 flat₹15.34
Groww0.1%, max ₹200.1%, max ₹200.1%, max ₹20₹20 flat₹18.50
None (statutory only)₹0₹0₹0₹0₹0

Each component is rounded to the paisa, half up. Breakeven is the round-trip charge on a trade bought and sold at the same price, as a percentage of its value: the move a trade needs just to cover costs.

Crypto

Source: costs/crypto_vda.py. Rules effective 1 April 2026 (FY2026-27).

Exchange fees, as a share of turnover:

VenueTakerMakerGST on the fee1% TDS withheld on sellsSettles in
CoinDCX0.5%0.5%18%YesINR
WazirX0.2%0.2%18%YesINR
ZebPay0.45%0.45%18%YesINR
Binance0.1%0.1%noneNo (self-reported)USDT
Bybit0.055%0.02%noneNo (self-reported)USDT
OKX0.1%0.08%noneNo (self-reported)USDT
Kraken0.26%0.16%noneNo (self-reported)USD

Each pair is charged at its own venue. A venue with no fee schedule is an error, never priced as another venue. The engine's command line (--venue, or CostConfig(crypto_venue=...) in code) prices every pair at one venue instead, as a what-if.

  • TDS, Section 194S: 1% of the sell consideration. Indian exchanges withhold it at source; on offshore venues the liability still exists but is self-reported, so the engine only withholds it there when a run asks it to. In a backtest it applies to every sell; the annual thresholds (₹50,000 for specified persons, ₹10,000 for others) are not applied. TDS is credited against the year's tax, and any excess is refundable.
  • Tax, Section 115BBH: 30% plus 4% cess (31.2%) on the sum of winning trades. Losses cannot be set off against any gain, including gains on another crypto asset, and cannot be carried forward. The only deduction allowed is the cost of acquisition. By default the engine taxes each trade's P&L after exchange fees; the strict reading, which does not deduct fees, is an option. The TDS inside a trade's charges is added back before gains are summed: it is a prepayment credited against the tax (any excess refundable), not a cost. Book P&L is after exchange fees and GST but before TDS; after-tax P&L is book P&L minus the tax.

Because losses do not offset gains, a strategy with a positive book P&L can lose money after tax. The engine reports gains, losses, taxable income, tax, TDS credit and after-tax P&L on every crypto run.

Paper trading

Paper orders are charged as equity delivery on the stock's own exchange, NSE or BSE (at its scrip group's rate), on the Zerodha schedule, including the DP charge when shares are sold.

Data

NSE and BSE prices for backtests and the workspace

  • Two exchanges, as equals. An NSE stock is keyed by its symbol (RELIANCE), a BSE stock by BSE- and its symbol (BSE-RELIANCE; strategies write NSE:RELIANCE and BSE:RELIANCE). A company listed on both has both listings, linked by ISIN, each with its own prices, volume and charges. NSE and BSE run one equity session (09:15 to 15:30 IST) and close on the same holidays, so their bars share dates and a strategy may hold stocks from both.
  • Daily bars (open, high, low, close, volume). The source is set by the operator:
  • Groww (groww): from Groww's public instrument list, refreshed each morning, every NSE EQ-series stock (about 2,700) and every BSE stock in groups A, B and X (normal settlement; X lists only on BSE) and E (ETFs), about 3,700. Trade-for-trade, non-compliant, SME, debt, InvIT/REIT and rights groups are left out on both exchanges. Five years of daily bars come from the Groww Trade API, each stock on its own exchange. Groww's plan may serve only recent months: the operator's history probe measures the depth for each exchange, and older sessions come from the exchange's own public daily bhavcopy files instead: NSE's (series EQ, BE and BZ) and BSE's (the UDiFF file since July 2024, the older EQ_ISINCODE file before, which names a stock only by scrip code and ISIN; groups A, B, X and E plus T, XT, Z and ZP), so a stock moved to trade-for-trade keeps its history. For the sessions Groww serves, the files only fill gaps.
  • a licensed vendor feed (licensed_http);
  • Yahoo Finance delayed daily bars for the featured stocks (49 NSE large caps and BSE's SENSEX 30) from 1 January 2020, for development and private use only (split-adjusted by Yahoo);
  • synthetic prices for offline testing, labelled as synthetic everywhere they appear.

Any real prices in a beta or public deployment need the source's written permission on record, covering NSE and BSE.

  • With Groww, each session's bar is added after the close; during the session the last traded price comes from Groww's live quotes where the operator turns them on, for NSE and BSE stocks alike. Other sources refresh every 15 minutes during market hours and once after the close. Every price shows its session date and freshness; missing or stale data is shown as such and never replaced with generated prices, another vendor's data or the other exchange's price.
  • Bar timestamps are normalised to 09:15 IST on their trading day, on both exchanges. Backtests use completed sessions only; a partial current-day bar is excluded.
  • A stock is available for backtests once it has more than 30 stored sessions, so a new listing waits.
  • Price returns exclude dividends. Splits and bonuses are adjusted as described below.
  • The universe is stocks listed today, not historical index membership; delisted stocks are absent, so results carry survivorship bias.
  • A backtest uses the most recent 200 to 2,500 sessions (750 by default). You can also import your own CSV price history.

Splits and bonuses

Groww's candles and both exchanges' files are stored as traded, and NSE's previous-close column is not adjusted either: on Reliance's 1:1 bonus (28 October 2024) the previous close reads ₹2,655.70 against an open of ₹1,337. The app adjusts when it reads the bars. When a session opens at least 40% away from the previous session's close, the two sessions are at most 7 days apart, and the ratio matches a usual split or bonus within 3% (1.5 for a 1:2 bonus, 2 for a 1:1 bonus or 2-for-1 split, then 2.5, 3, 4, 5, 6, 8, 10, 20, 25, 50 and 100), every earlier price is multiplied by the inverse of that ratio and every earlier volume divided by it. Consolidations are found the same way. So the Reliance bar before the bonus reads ₹1,327.85. The same rule runs on BSE listings, each on its own prices.

Limits:

  • Bonuses smaller than 1:2 (1:3 or 1:4 open only 20-25% lower) are not detected.
  • Rights issues, demergers and special dividends are not adjusted.
  • A genuine overnight move of 40% or more that happens to match a ratio would be read as a split. Price bands make this rare.
  • BHAV_SPLIT_ADJUST=0 turns detection off. Yahoo's bars arrive split-adjusted; a licensed feed must use one adjustment policy across its whole history.

Crypto

  • Pairs the operator enables (BHAV_CRYPTO_DATA): CoinDCX INR pairs and Binance USDT pairs, keyed COINDCX-BTCINR and BINANCE-BTCUSDT (strategies write COINDCX:BTCINR).
  • Daily candles cut at 00:00 UTC, every day of the year: no exchange calendar and no holidays. The running day's candle is excluded from backtests, as on NSE and BSE.
  • CoinDCX INR pairs can be backtested and paper traded in fractional quantities, in the pair's quantity step and price tick and above its minimum order value, with CoinDCX's fee, GST and 1% TDS, and the 115BBH report on every run.
  • Binance USDT pairs are charts only: backtests and the paper portfolio are in rupees, and there is no stored USD/INR series to convert them yet.
  • One strategy trades up to 50 instruments from one market: stocks (NSE and BSE together are fine: one session, one calendar) or crypto pairs, never both, because sessions, charges and taxes differ. The engine refuses a backtest that mixes them.

Beyond the workspace (charts and numbers only, no backtests or paper orders)

  • The assistant's price lookup for any coin, beyond the enabled pairs: rupee prices and daily candles from CoinDCX, with CoinGecko as the price fallback.
  • Indian mutual fund NAV history from AMFI data via mfapi.in.
  • Rupee exchange rates from ECB reference rates (Frankfurter).
  • Web research through Firecrawl, where the server has it switched on. Web pages are treated as data, never as instructions, and answers cite them.

Fill model

Each bar, in this order:

  1. The clock advances; the strategy may see bars up to and including this one, never later.
  2. Orders the strategy placed on the previous bar fill at this bar's open. A decision made on a bar's close can never fill on that bar.
  3. Stops, targets and trailing stops are checked against this bar's range. If the open gaps through a stop, the exit fills at the open, not at the stop level. If one bar touches both the stop and the target, the engine assumes the stop was hit first.
  4. Intraday positions are squared off at the end of the session.
  5. The portfolio is marked to the close and equity is recorded.
  6. The strategy runs and may queue orders for the next bar.

Order handling:

  • Slippage: market orders fill 2 basis points worse than the open by default (adjustable from 0 to 100), then the price snaps to the tick grid in the adverse direction (each stock's tick from the exchange's instrument list, ₹0.01 for most stocks under ₹250 and larger for high-priced ones, and the pair's tick for crypto), so slippage smaller than a tick is never rounded away. The tick is today's, applied to the whole history.
  • Limit orders fill only if the bar traded through the limit.
  • Sizing: quantities round toward zero to whole shares or lots; fractional amounts are allowed only for crypto, in the venue's step.
  • Rejections are counted, not hidden: orders below one lot, orders the cash cannot pay for (charges included), orders above the exchange freeze quantity, short sales (off by default), orders for a symbol with no bar, and orders below a venue's minimum.
  • Product: a strategy on daily bars that does not choose a product holds positions as delivery.
  • Every run records its assumptions (fill rule, protection rule, intrabar rule, slippage, shorting, engine version) and the date of the rate schedule, so a result stays interpretable later.

What the results mean

  • Net return is after every charge; gross return adds the charges back. The gap is the cost of the strategy. Slippage is inside the fill prices, so it shows in both.
  • Sharpe is measured against a 6.8% risk-free rate (the 10-year G-Sec proxy), not zero, annualised over 250 sessions a year for NSE and BSE and 365 days for crypto. A strategy that sits almost entirely in cash (under 1% annual volatility) gets no Sharpe rather than a meaningless one.
  • Charges as a share of gross P&L, win rate, profit factor, expectancy, drawdown and its duration, exit reasons and rejected orders are reported with every run.
  • No index benchmark. Results are measured against the G-Sec rate, not against NIFTY 50 or SENSEX: neither index's history is stored yet. Groww's candles serve both (NSE-NIFTY, BSE-SENSEX), so either could be added as a benchmark, each for its own exchange's stocks.

What the engine does not do

  • Place real orders. Quantwala is research and paper trading only.
  • Reconstruct historical charges. Today's rate schedule is applied to every past trade.
  • Include dividends, or adjust corporate actions other than the splits and bonuses above.
  • Model market impact, queue position or partial fills. Orders fill in full at the modelled price.
  • Use intraday data in the hosted app. Workspace backtests run on daily bars.
  • Model options depth: Greeks, SPAN margin and multi-leg positions are not part of sizing.
  • Model margin, leverage costs, interest on cash, or taxes other than crypto VDA tax. Capital-gains tax on equity is not computed.
  • Correct for survivorship bias: the universe is today's listed stocks.
  • Predict anything. A backtest describes what a rule would have done on past prices, with the costs above. It is not a forecast.

Quantwala is a research and paper-trading tool, not an investment adviser, research analyst or stockbroker, and it is not registered with SEBI as any of them. Nothing here is investment, tax or legal advice.