Skip to main content
Backtesting simulates a controller config against historical candles. Use it to understand parameter sensitivity and to check that your strategy behaves as expected, not to predict exact live results.

Philosophy

Backtesting market making strategies can’t perfectly simulate reality:
  1. Queue position: order books are first in, first out, and exchanges don’t tell you where your order sits in the queue.
  2. Path dependency: if one fill differs between backtest and live, everything after it diverges.
  3. Order book depth: on a thick book your order may never fill, even when the price touches your level.
Don’t trust absolute PnL numbers from backtests. Use backtesting as a parameter research tool, not a prediction engine.

What backtesting is good for

Supported executors

The Hummingbot backtesting engine simulates the executors a controller creates. It has simulators for these executor types: A controller that creates unsupported executors produces no trades for them in a backtest.

Running a backtest in Condor

Condor runs backtests with the backtest_chart routine. It sends a saved controller config to the Hummingbot API’s backtesting engine, waits for the result, and draws an interactive chart. The routine is part of Condor’s shared routine library, so you can run it from the Workspace, from Telegram, or through an agent.
  1. Open the Routines page and select backtest_chart.
  2. Pick a config in config_name and fill in the other fields (see the table below).
  3. Run it. The summary and metrics appear in the run’s result, and the interactive chart is saved as a report.

Fields

Each run gets a Task ID, shown in the summary. Results are stored in Condor for 30 days by default (CONDOR_BACKTEST_RETENTION_DAYS). If a run has fewer than 20 executors, the summary warns that the metrics are noise. Widen the date range or loosen the config and run it again.

Candle resolution and look-ahead

For controllers that trade on indicator signals, use a resolution no finer than the controller’s own candle interval.
The engine joins each controller’s indicator candles to the simulation candles by the candle’s open time. When the simulation resolution is finer than the controller’s interval (for example, a 15m bollinger_v1 run at 1m), each 1m row inside a 15m candle already sees that 15m candle’s final close and signal. The backtest trades on information it wouldn’t have had live, so PnL and Sharpe come out better than they should. Backtest such controllers at their own interval (here, 15m).
supertrend_v1 can’t be backtested at the moment: the engine drops every row of its indicator data, and the run fails.
Hummingbot’s standalone script scripts/backtest_pmm_mister.py (run from a Hummingbot source checkout) defaults to --resolution 1s for market making. Condor’s routine lists only 1m, 5m, 15m and 1h.

Comparing backtests

The backtest_compare routine overlays the PnL curves of saved backtests and ranks them in a metrics table.

Reading the chart

The backtest_chart figure stacks up to four panes that share the time axis. Panes only appear when the backtest has data for them. The chart title shows net PnL, Sharpe ratio, profit factor, executor count and volume.

PnL lines

Executor markers

Each executor is drawn as an entry marker and an exit marker joined by a line. Markers are grouped by how the executor closed: For TP, SL and Other markers the connecting line is green when the executor made money and red when it lost.

Example analysis: 2% vs 10% allocation

With pmm_mister, portfolio_allocation sets how much of the capital is quoted around the price. 2% allocation:
  • Inventory builds gradually
  • Trading continues through drawdowns
  • More consistent activity
10% allocation:
  • Inventory builds quickly
  • May reach max_base_pct during a drawdown
  • With position_profit_protection on, the controller won’t sell below its break-even price, and above max_base_pct it won’t buy either, so it stops trading until the position is profitable again

PMM Mister parameters

These pmm_mister fields have the most effect on backtest behaviour. Field names come from the controller’s config class.

Trading bots vs Condor agents

Agents can backtest, deploy and retune controllers, but they act every few minutes, not every tick. The bot does the fast work; the agent supervises it.