Overview and Starting a Backtest
A backtest drives the strategy code with the platform's historical market data: the backtest engine keeps a virtual clock and one simulated account per exchange object, and answers every market, order and account call from history. A backtest only shows how the strategy would have behaved on past data; the past does not represent the future, so read backtest results with caution.
Starting a backtest
- Website: open the strategy editor, switch to the "Backtest" tab, set the backtest configuration and strategy parameters, then click "Start Backtest" (keyboard shortcuts: see Backtesting System → Backtest Page Shortcuts). The configuration can be saved into the strategy source, see Backtesting System → Backtest Configuration and Saving.
- AI assistant: start a backtest with the MCP tool
run_backtestand read the result withget_backtest, see Integrations → AI Integration. Backtests started through MCP always use the simulated-tick mode. - Your own machine: use the open-source local backtest engine, see Backtesting System → Local Backtesting Engine.
Configuration items
| Item | Description |
|---|---|
| Time range | Start and end time of the backtest. |
| K-line period | The K-line period that GetRecords() returns by default. |
| Base K-line period | The K-line period from which ticks are generated in simulated-tick mode. Smaller is closer to real markets and slower. Strategy K-lines are built from base K-lines, so they cannot be shorter than the base period. |
| Mode | Simulated tick or real tick, see Backtesting System → Backtest Modes and Order Matching. |
| Exchange, trading pair | Each exchange object has its own simulated account; pairs are written like BTC_USDT. For futures exchanges the strategy must call exchange.SetContractType() before requesting market data or placing orders. |
| Initial funds | Initial balances of the quote currency (e.g. USDT) and the base currency (e.g. BTC). Coin-margined contracts use the base currency as margin, so set the base-currency balance. |
| Fees | Maker and taker rates in percent; the defaults come from the exchange market's configuration. A limit order that fills immediately when placed pays the taker rate; one that rests in the book and is filled later pays the maker rate. |
| Slippage | Number of price ticks added outside the simulated best bid and best ask; default 0. |
| Network delay | In milliseconds; every exchange call advances the virtual clock by this amount; default 200. |
| Depth levels, amount per level | Number of levels GetDepth() returns (1-20) and the amount on each simulated level; in real-tick mode the depth levels are the real depth requested from the data source. |
| Max K-line bars | Upper limit of history bars returned by the first GetRecords() call (100-5000, default 300). |
| Log limits | Upper limits on kept runtime logs, profit logs and chart data points. |
| Data source | The platform's historical data by default; a custom data source can be used instead, see Backtesting System → Custom Data Source. |
Fault-tolerance test
The backtest page also offers a "fault-tolerance test": exchange calls fail with a given probability (0.5 by default), and the first call of each kind always fails; each failure is logged as the error FaultTolerant Test. Use it to check how the strategy handles failed calls, e.g. whether it retries with _C().
What the strategy sees in a backtest
IsVirtual()returnstrue; logic that must not run in a backtest can be skipped based on it, seeIsVirtual.- Time is virtual:
Unix(),_D()and similar functions read the backtest clock, andSleep()advances it. When the clock passes the end time, the engine throws anEOFexception and the backtest ends;onexit()is not called in that case. - In a backtest
GetCommand()receives no interactive commands,onerror()is not supported, and network request functions are restricted.