Type/to search
Getting Started
Welcome to FMZ Quant Trading Platform
Quick Start
Key Security
Platform Basics
Account and Billing
Live Robot Billing and Top-up
Sub-accounts
Exchange
General Protocol
Local Credential Files
Exchange-Specific Notes
Securities and Futures
Crypto
Docker
Strategy Library
Live Trading
Writing Strategies
Development Tools
Backtesting System
Advanced Topics
Data and Research
Integrations

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_backtest and read the result with get_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

ItemDescription
Time rangeStart and end time of the backtest.
K-line periodThe K-line period that GetRecords() returns by default.
Base K-line periodThe 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.
ModeSimulated tick or real tick, see Backtesting System → Backtest Modes and Order Matching.
Exchange, trading pairEach 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 fundsInitial 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.
FeesMaker 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.
SlippageNumber of price ticks added outside the simulated best bid and best ask; default 0.
Network delayIn milliseconds; every exchange call advances the virtual clock by this amount; default 200.
Depth levels, amount per levelNumber 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 barsUpper limit of history bars returned by the first GetRecords() call (100-5000, default 300).
Log limitsUpper limits on kept runtime logs, profit logs and chart data points.
Data sourceThe 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() returns true; logic that must not run in a backtest can be skipped based on it, see IsVirtual.
  • Time is virtual: Unix(), _D() and similar functions read the backtest clock, and Sleep() advances it. When the clock passes the end time, the engine throws an EOF exception 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.