Skip to content

Backtesting

Running a backtest

The full walkthrough lives in Run your first backtest. This page covers what you do once that's familiar.

Reading the result panels

A completed backtest is shown on the Dashboard. The top row is a set of summary KPI cards; the fuller risk metrics live in the Detailed Stats panel (see below).

Summary stats

The KPI cards across the top of the Dashboard:

Stat What it means
Total Return Final equity ÷ initial capital − 1, expressed as a %. The sub-line shows the ₹ P&L.
Ann. Return Total return scaled to a full year (CAGR-style). Useful for comparing runs of different lengths.
Win Rate % of trades that closed profitable. Pair it with average win / loss size; a 30%-win strategy with big wins beats a 70%-win strategy with tiny wins. The sub-line shows the trade count.
Max Drawdown Largest peak-to-trough fall during the run, as a % of peak equity. The deeper this is, the more drawdown you'd have to stomach in live trading.
Capital Starting capital → ending capital.
Avg Deployment How much of your capital was actually working — see below.

Average deployment

Avg Deployment is the time-weighted % of your starting capital that was invested in positions across the backtest period. A value of 60% means that, on average, 40% of your capital sat idle as cash.

It's the number that reconciles the common "my position went up 68% but the backtest only shows 44% total return" gap: if capital is only deployed ~65% of the time, the portfolio return is roughly the trade return scaled by the deployment fraction. A low value isn't necessarily bad — it can mean the strategy is selective — but it does cap the portfolio return relative to how well individual trades did.

Detailed stats

Open the bar-chart icon in the right-hand side panel (it appears once a backtest is loaded) for the Detailed Stats panel. It adds the risk and trade-quality metrics that aren't in the summary row:

Stat What it means
Sharpe Risk-adjusted return. Above 1 is solid for retail, above 2 is unusually good — be sceptical and check for overfitting.
Sortino Like Sharpe but penalises only downside volatility. Shown as a trade-level approximation.
Profit factor Gross profit ÷ gross loss. Above 1 is profitable; below 1 loses money.
Expectancy Average P&L per trade (₹).
Avg win / Avg loss Mean size of winning vs losing trades (₹).
Loss streak Longest run of consecutive losing trades — a feel for the worst stretch.
Win rate / Max drawdown / Ann. return / Total trades Same as the summary, repeated for convenience.

Where the right-hand panel is

Detailed Stats (and the Compare and Notes widgets) live in the right-side panel, which is hidden on narrow/mobile screens. Use a laptop-width window to see it.

Equity curve

The chart card has three tabs — Equity, Compare, and Drawdown. The Equity line is your portfolio value over time, overlaid with the symbol price and buy ▲ / sell ▼ markers. Hover for the exact value on any date. The Drawdown tab plots the same run as a drawdown curve.

Trade list

Each row is one round-trip trade:

  • Entry / exit — dates and prices
  • Side — BUY (long) or SELL (short)
  • Quantity — number of shares/contracts
  • P&L — net of brokerage and slippage
  • Hold days — calendar days between entry and exit

Click a trade row to highlight it on the chart panel.

Compare

The Compare page (sidebar) puts two completed backtests side by side. Useful for:

  • Comparing two strategies on the same symbol/range
  • Comparing the same strategy with different parameters
  • Comparing the same setup across two symbols

The equity curves are normalized to a common starting point so you can read the shape, not the absolute capital.

Speed and the cache

The first backtest on a new symbol fetches historical data from Kite. We persist this in a local cache, so every subsequent backtest on that symbol — at any date range — uses the cache, not the network.

Expected timings:

  • First run on a new symbol: 1-2 seconds (one Kite call, ~300ms; rest is local computation)
  • Subsequent runs on the same symbol: 100-500ms

If a backtest is much slower than that, two common causes:

  1. Multiple concurrent backtests on different symbols — the rate limiter serializes Kite calls to stay within Zerodha's per-second cap. Wait a few seconds.
  2. Cold cache + many symbols — running a comparison on 8 fresh symbols means 8 sequential Kite calls + their data persisted. Re-running the same comparison will be near-instant.

Saving and exporting

Every backtest is saved automatically — see the Backtests sidebar for the full list. From the Dashboard's Trades table you can export the trade list as CSV or JSON.