Type/to search
Getting Started
Platform Basics
Writing Strategies
Development Tools
Backtesting System
Overview and Starting a Backtest
Backtest Modes and Order Matching
Backtest Configuration and Saving
Supported Languages and Exchanges
Reading Backtest Results
Parameter Optimization
Custom Data Source
Local Backtesting Engine
Backtest Page Shortcuts
Advanced Topics
Data and Research
Extended API Interface

The platform publishes local backtest engines for JavaScript and Python. They use the same engine core and the same history data (downloaded from the platform's data server) as cloud backtests, and backtest JavaScript and Python strategies quickly on your own computer. Source code:

Python

Install (requires Python 3 and pip):

bash
pip install https://github.com/fmzquant/backtest_python/archive/master.zip pip install pandas matplotlib # only needed for Join(True) and Show()

On first use the package downloads the engine file for your system from the data server; afterwards only history data is downloaded. A strategy file is an ordinary FMZ strategy plus the backtest configuration comment at the top (format: see Backtest Configuration and Saving; the local engines read only some of its keys, see "Differences from cloud backtests" below) and a few lines that drive the engine:

python
'''backtest start: 2026-09-01 00:00:00 end: 2026-09-15 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Binance","currency":"BTC_USDT","balance":10000,"stocks":0}] ''' import json from fmz import * # initialize the engine from the configuration above; exchange, Log, TA etc. become globals task = VCtx(__doc__) # The strategy under test, copied from the platform as is def main(): Log(exchange.GetAccount()) while True: r = exchange.GetRecords() if r: LogStatus(_D(), r[-1]["Close"]) Sleep(60 * 60 * 1000) try: main() except EOFError: # The engine raises EOFError when the virtual clock reaches the end time pass result = json.loads(task.Join(False)) # Raw backtest result (JSON) print(result["LogsCount"], result["Elapsed"] / 1e6) # task.Show() # Or show the profit chart (requires matplotlib)

Run it with python strategy.py. task.Join(False) returns the raw result as JSON, task.Join(True) returns a pandas DataFrame of the first exchange account's profit and loss (PnL) and utilization at each snapshot, and task.Show() plots equity, profit and loss and utilization from the account snapshots; neither depends on LogProfit().

JavaScript

bash
npm install git+https://github.com/fmzquant/backtest_javascript.git
javascript
var fmz = require("fmz") var task = fmz.VCtx({ start: "2026-09-01 00:00:00", end: "2026-09-15 00:00:00", period: "1h", basePeriod: "15m", exchanges: [{eid: "Binance", currency: "BTC_USDT", balance: 10000, stocks: 0}] }) // From here on exchange, Log, TA etc. are globals; paste the strategy code and call main() function main() { Log(exchange.GetAccount()) while (true) { var r = exchange.GetRecords() if (r) { LogStatus(_D(), r[r.length - 1].Close) } Sleep(60 * 60 * 1000) } } try { main() } catch (e) { // The engine throws "EOF" when the virtual clock reaches the end time } var result = JSON.parse(task.Join()) // Same result as Join(False) of the Python engine console.log(result.LogsCount)

Differences from cloud backtests

  • Only JavaScript and Python strategies are supported and templates are not loaded automatically: paste the code of referenced templates into the file. PINE and MyLanguage strategies depend on trading libraries and therefore cannot be backtested locally.
  • Strategy parameters are not injected; define them as global variables in the code.
  • start and end in the comment are parsed in the machine's time zone; network delay is fixed at 200 ms; slippage and real-tick mode are not supported.
  • Only start, end, period, basePeriod and exchanges (with its eid, currency, balance, stocks, fee, feeMin) are read from the comment; mode, args, depthDeep, tradesMode, feeder and the like are ignored. Without basePeriod it is derived from period (1d→1h, 1h→30m, 30m→15m, 15m→5m, 5m→1m); without stocks the default is 3; without fee the engine's built-in fee table is used. It is best to write them all out.

Backtesting with an AI assistant

An AI assistant can run backtests for you: it starts a cloud backtest with the MCP tool run_backtest and reads profit, drawdown, error logs and other results with get_backtest, see AI Integration. It can also install the local engine on your machine for a fast edit-and-run loop, then confirm once with a cloud backtest.