Backtesting
How TradePilot simulates a backtest — rebalancing, daily valuation, transaction costs, and the buy-and-hold benchmark. Reference for what the run loop actually does.
A backtest replays a strategy over historical prices to estimate how it would have performed. TradePilot’s engine runs the whole simulation in your browser. For the why of backtesting (and its pitfalls like overfitting), see Learn; this page documents what the engine does.
The run loop
Given a BacktestConfig, the simulator:
- Determines rebalance dates — the trading days in
[startDate, endDate], everyrebalanceFreqdays. - At each rebalance date:
- Values the portfolio every trading day between rebalances, producing a daily equity curve — not just point-to-point at rebalance dates.
- Applies transaction costs on each trade if a cost model is configured.
- Tracks a benchmark buy-and-hold curve for comparison.
- Computes metrics from the daily series.
Daily valuation
The engine values holdings on every trading date in the window (annualizing
with periodsPerYear = 252). This gives an honest equity curve and realistic
drawdowns, rather than sampling only on rebalance days.
There is a legacy rebalance-date-only mode (
periodsPerYear = 52) kept purely so the Python parity test can pin the original behavior. The app always uses daily valuation.
Transaction costs
Costs are optional and expressed in basis points per trade side:
costBps— commission / feesslippageBps— slippage
Total friction per trade = (costBps + slippageBps) / 10000 × trade notional.
Both default to 0 (frictionless), so leave them off for an idealized run and
turn them on to stress a high-turnover strategy.
The benchmark
Every run tracks a buy-and-hold benchmark (default SPY, set via
benchmarkSymbol). It’s overlaid on the equity curve and drives the alpha
metric. If the benchmark symbol has no price data, the benchmark series is
simply null and omitted.
What a run returns
The result (BacktestResultV2) is fully JSON-serializable — daily dates and
portfolioValues, per-rebalance weights, the trades list, the metrics
object, monthlyReturns, topDrawdowns, and the benchmarkValues. That exact
shape is what gets stored when you save a run; see
the data model.
Related
- Strategies · Optimizers · Metrics
- Engine internals — types, Worker execution, parity