Skip to main content

Fees & charges in a backtest

Who it’s for
Anyone comparing a backtest result to what they would actually have made
Assumes
You have run a backtest
Applies to
Every backtest, every market
Correcting earlier documentation

Earlier versions of these docs said a backtest assumes "perfect order execution and no slippage." That was wrong, and it understated the platform.

Every backtest applies modelled slippage, commission and, where the market has them, statutory transaction charges. Your results are already net of costs. If you were mentally discounting them further, you were double-counting.


What the simulation charges

Costs apply on both legs of every trade, expressed as a percentage of the trade price.

Entry price paid = price × (1 + (slippage_bps + commission_bps)/10,000 + statutory_buy_pct/100)
Exit price received = price × (1 - (slippage_bps + commission_bps)/10,000 - statutory_sell_pct/100)

Three components:

ComponentWhat it represents
SlippageMarket impact, bid-ask spread and execution imperfection
CommissionBroker or exchange fee, in basis points
Statutory chargesTransaction taxes and regulatory fees, where the market has them

Wire defaults

Applied unless the market profile or asset family overrides them:

KnobDefault
Slippage5 bps (0.05%)
Commission2 bps (0.02%)

By market

Indian equity cash: NSE, BSE

ChargeRate
Slippage5 bps
Commission2 bps
STT, intraday0% buy, 0.025% sell
STT, delivery0.1% on both legs
Session375 minutes
Annualisation252 trading days
Quantity stepWhole shares

The intraday/delivery split is derived from the holding period. An intraday round trip is charged STT on the sell only; a position held overnight is charged on both legs at four times the rate, a material difference that a flat assumption would hide.

Crypto spot

ChargeRate
Slippage5 bps
Commission10 bps (0.10%, Binance spot standard tier)
StatutoryNone. No STT on a crypto venue
SessionContinuous, 1,440 minutes
AnnualisationCalendar days
Quantity step0.00001

The 10 bps commission on both legs is 20 bps round-trip, five times the equity default. On a 1-minute strategy taking hundreds of trades that is the dominant term in the result.

US equity

ChargeRate
Slippage5 bps
Commission2 bps
STTZero, US regulatory fees are not an STT and are deliberately not modelled
SessionUS equity session length
Annualisation252 trading days
Why the zero is explicit

US equity once had no profile of its own and fell through to the Indian one. So every US backtest was charged 0.025% STT on intraday sells and 0.1% on both delivery legs, a tax that does not exist in that market, on a session 15 minutes too short. The zeros are stated rather than inherited so that cannot recur.

Indian F&O: options

Options attract a different family of charges, not a variation of the equity ones. Rates as of 1 October 2024:

ChargeRateSide
STT0.1% of premiumSell only
Stamp duty0.003% of premiumBuy only
Exchange transaction0.03503% of premium (₹3,503 per crore)Both
IPFT0.0005%Both
SEBI turnover fee0.0001% (₹10 per crore)Both
GST18% on the exchange, SEBI and IPFT feesBoth
Brokerage₹20 per order, flat, modelled as an approximationBoth

Percentages are of turnover, which for an option means the premium.

F&O STT is sell-side only, however long you hold

It is not an intraday/delivery split. Deriving the sides from holding period is not a smaller version of the truth. It is a different tax, so the F&O charge set replaces the equity derivation outright rather than adjusting it.

Indian F&O: futures

ChargeRateSide
STT0.02% of contract valueSell only
Stamp duty0.002%Buy only
Exchange transaction0.00173% (₹173 per crore)Both
IPFT0.0001%Both
SEBI turnover fee0.0001%Both
GST18% on the fee componentsBoth
Brokerage₹20 per order, flatBoth

For futures, turnover means the contract value.

FX (currency derivatives and OTC)

STT-exempt: currency derivatives attract no Securities Transaction Tax. Cost is commission plus slippage only. FX is not reachable by users today; documented for completeness. See Regulatory position.


How the flat ₹20 is modelled

A flat per-order brokerage has no representation in price space, so it is folded into commission as a basis-point equivalent against the allocated capital.

The consequence to understand: a flat fee's bps equivalent depends on your position size. ₹20 on a ₹2 lakh position is 1 bp; on a ₹20,000 position it is 10 bps. A small-position F&O strategy is charged proportionally far more, exactly as it would be in reality.

Families that charge no flat fee leave commission untouched.


Resolution order

Four levels, highest priority first:

  1. A run override you supplied, a value in the request that differs from the wire default
  2. The asset family's charges, F&O and FX. Absent for equity and crypto, which therefore keep their market defaults untouched
  3. The market profile's defaults, the venue's own rates
  4. The Indian equity default, the fallback for an unrecognised market
Why level 1 compares against the wire default rather than checking presence

Every request carries all four cost keys, so presence proves nothing about intent. Comparing against the wire default is what separates "the caller chose 0.025" from "the caller sent the schema's untouched 0.025."

The trade-off: passing a value equal to the Indian wire default on a crypto run gets the crypto default instead. Acceptable, since that number is meaningless for crypto. And any genuinely different value, including 0.0, is honoured exactly.


Overriding costs on a run

Both are settable per backtest, from the chat:

backtest with 10 bps slippage
backtest with zero commission

An explicit 0.0 is a deliberate override and is honoured. Use it to isolate the cost drag, run once with costs and once without, and the difference is what execution is costing your strategy.

A zero-cost run is a diagnostic, not a result

It tells you how much of your return the costs consume. It is not what you would have made.

You can also set starting capital: backtest with 5 lakh. See Choosing a test period.


Cost model version

Every stored backtest result carries a cost_model_version. It is currently 4.

It exists so results produced under different cost assumptions can be told apart instead of being silently compared. Version 4 added the asset-family dimension and the Indian F&O families; every equity, crypto and FX result is numerically unchanged from version 3, because those families impose no override. But the version moved because the resolution order changed, and a version-3 F&O result was charged the equity model.

Rates are statutory and change by notification

The F&O rates above are as of 1 October 2024. Statutory charges change by government and exchange notification. Re-check them against the current NSE circular and your broker's schedule before trusting absolute cost figures. And note that a stored result was computed under the rates in force at the time, which is exactly what the version counter exists to make visible.


What is still not modelled

Costs are modelled honestly. Execution mechanics are not, and these remain genuine caveats:

Not modelledConsequence
Partial fillsAn order fills entirely or not at all
Queue positionNo modelling of where you sit in the book
LatencyZero delay between signal and fill
Intra-candle pathFills use candle boundaries. When both a stop and a target are inside one candle, the stop is assumed to fill first, deliberately pessimistic
Spread widening in stressSlippage is a constant, not a function of conditions
Market impact of sizeThe 5 bps allowance does not scale with your order
Circuit limits and haltsA locked instrument is untradeable in reality, not in the simulation

These are the right things to be sceptical about, and they matter more on short timeframes. Full list: Backtest limitations.


Next