Backtesting
Prove any strategy you generate
A decade of bars in seconds, with commission, slippage, spread and partial fills applied to every order. Compare against buy-and-hold, inspect each trade, and see the drawdown you would actually have had to live through.
Six strategies, one engine, no cherry-picking
Switch between saved runs to see the equity curve, the underwater chart and the full statistics table update together. One of these six loses to buy-and-hold, and we left it in.
Saved runs
Six runs from our internal regression suite, all on the same engine with 5 bps commission and 2 bps slippage. None of them is a recommendation.
Momentum Breakout
NVDA · 4H · 2,180 bars · Jan 2024 → Aug 2026
- Net profit
- +58.4%
- Max drawdown
- -15.2%
- Win rate
- 44.6%
- Profit factor
- 1.74
- Sharpe
- 1.62
- Trades
- 186
Buy & hold +31.2%
Peak to trough on closed equity
83 winners / 103 losers
Gross win ÷ gross loss
Annualised, zero risk-free rate
Round turns
How to read this run
Fewer than half of these trades win. The curve is carried by a handful of long holds while the rest bleed a little — the shape every breakout rule produces, and the shape that is hardest to sit through by hand.
The costs that decide whether an edge is real
Most backtests fail in production for one boring reason: the simulation traded for free. Every assumption below is on by default, visible in the report header, and adjustable per run.
Commission, per venue
Charge per share, per contract or in basis points, and split exchange fees from clearing so a rebate-heavy schedule does not quietly subsidise the result.
Slippage that scales
A flat tick of slippage flatters fast systems. Ours defaults to a fraction of the bar’s true range, so the cost rises exactly when your signals cluster — in volatile tape.
The spread you actually cross
Entries lift the offer, exits hit the bid. The modelled spread widens at the open, into the close and across scheduled economic releases rather than staying constant all session.
Partial fills and queue position
Order size is capped as a share of the bar’s volume. Anything beyond that cap is re-queued to the next bar or cancelled, so a strategy cannot pretend it absorbed the whole print.
Look-ahead prevention
Signals are evaluated on the close of a bar and filled at the next open. Indicators may never read a value they could not have known, and restated fundamentals are stored as-of their first publication.
Financing and corporate actions
Overnight borrow on shorts, perpetual funding on crypto, and dividends, splits and spin-offs applied on the ex-date — the carry that decides whether a slow strategy is viable at all.
Cost sensitivity, on every report
Before you read the headline number, read this one: how much of it survives when the cost assumption doubles. A strategy that keeps most of its profit at twice the modelled friction is worth studying. One that does not is a spread-capture fantasy.
What a backtest cannot tell you
A simulation is evidence about a rule, not a forecast of your account. These four failure modes are structural — no amount of engineering removes them, and knowing them is most of the skill.
Overfitting is invisible from inside
Test two hundred variations of an idea against the same decade and the best one is a report on that decade’s noise, not on the idea. The tell is not the peak result but its neighbourhood: a profit factor of 1.8 at a 20-bar lookback with 1.7 either side is a plateau you can stand on. A 2.4 flanked by 0.9s is a spike, and spikes do not survive new data.
What we do about it — AlgoBeam counts every run you make against a data set and deflates the reported Sharpe by the number of trials.
Survivorship quietly removes the losers
Backtesting on today’s index membership tells you how a rule performed among companies that did not go bankrupt, get acquired or get relegated. Add the delisted tickers back and most long-biased systems give up a fifth to a third of their edge, and the left tail gets considerably fatter.
What we do about it — Delisted and acquired names are included by default. You can switch them off; the report will say so in red.
Your sample contains only the regimes that happened
The last decade of equity history is two long trends and a few violent dislocations. A rule fitted to that mix looks robust in aggregate and then meets a flat, choppy year alone. Splitting out-of-sample data by volatility regime rather than only by date exposes this fast, and usually uncomfortably.
What we do about it — Every report breaks results into low, normal and high-volatility regimes so you can see which one paid you.
Liquidity is assumed until it is not
A simulated order never moves the book. In reality, size is the first thing that breaks a strategy: the small-cap that filled 5,000 shares at the touch in the test will take three minutes and forty basis points of impact in the market. Capacity, not signal quality, is what ends most profitable systems.
What we do about it — Set a participation cap and the engine reports the account size at which the modelled edge goes to zero.
And one more with no software fix: you will not trade the backtest. It never skipped a signal after three losers, never doubled size to make back a bad week, and never took a holiday during the month that carried the year.
Walk it forward, or don’t believe it
A single in-sample fit tells you what a decade already did. Walk-forward analysis asks the only question that matters: would parameters chosen with the information available at the time have worked on the months that came next?
- Fit, then step. Parameters are optimised on each training window and applied unchanged to the block that follows. The window then rolls forward and the whole thing repeats.
- Only out-of-sample trades are reported. The published curve is stitched from the untouched blocks alone — the in-sample fits never contribute a single trade to the headline number.
- Efficiency is the score. Divide out-of-sample return by in-sample return. Above roughly 0.5 the rule is travelling; near zero you have optimised a curve, not discovered a behaviour.
- Then resample. A thousand Monte Carlo shuffles of the trade order give you the distribution of drawdowns the same edge could have produced — usually far worse than the one path you happened to see.
Rolling walk-forward, five folds
SchematicThe same engine, from your terminal
Everything the interface does is available as an API. Point AlgoBeamTS at a provider, hand it an AlgoBeamScript strategy, and get back statistics, a trade list and an equity curve you can diff in CI.
- Identical fill model on the platform and in the open-source runtime
- Reports export to CSV and JSON for your own analysis
- Deterministic seeds, so a run is reproducible bar for bar
import { AlgoBeamTS, Provider, readScript } from 'algobeam-ts'
const algobeam = new AlgoBeamTS(Provider.Binance, 'ETHUSDT', '4h', 5_000)
const source = await readScript('./strategies/ribbon-breakout.algo')
const report = await algobeam.backtest(source, {
capital: 25_000,
positionSize: { type: 'percent', value: 15 },
commissionBps: 5,
slippageBps: 2,
fillModel: 'next-open',
from: '2024-01-01',
to: '2026-08-27',
})
const { stats, trades } = report
console.table({
netProfitPct: stats.netProfitPct.toFixed(2),
maxDrawdownPct: stats.maxDrawdownPct.toFixed(2),
winRatePct: stats.winRatePct.toFixed(1),
profitFactor: stats.profitFactor.toFixed(2),
sharpe: stats.sharpe.toFixed(2),
trades: trades.length,
})
// These numbers assume the fill model above and do not account for
// funding, borrow cost or partial fills in thin books.
await report.writeCsv('./out/ribbon-breakout-equity.csv')Ready when you are
Test the idea before you fund it.
Open the backtester, fork one of the six runs above, and change a single assumption to see what your edge is really made of.
- No card required
- Cancel anytime
- 14-day Ultimate trial