Skip to content

Optimise a cBot

The optimize command searches a range of cBot parameter values to find combinations that score well against the criteria you choose. It runs the same genetic or grid sweep as the cTrader desktop application, driven from the terminal plus a JSON file of parameter settings. It is the optimisation counterpart of the backtesting command.

Scope

The optimize command optimises cBot parameters. Indicators and plugins are managed through their own commands (indicator calculate, indicator history, create, build) and are not part of optimisation.

Prerequisites

  • cTrader CLI is installed and you can sign in.
  • The cBot is exported as an .algo file and built for .NET 8.
  • A parameters file that defines which parameters to sweep.

Note

The optimize command is available in the local cTrader CLI edition only. It is not part of the internal or cloud build.

The optimize command

ctrader-cli optimize <path-to-algo-file> --params=<path-to-params-file> [options]

The path to the .algo file is the first argument. --params is required. The base timeframe must come from either --timeframe or the parameters file. If neither provides it, the command stops with an error.

Optimisation options

Only --params is required. Common optional choices shown in the examples below are --timeframe, --method, --criteria, --optres and --passes-dir.

A few options are worth knowing before you run:

  • --methodgenetic (default) or grid. Pick grid when the parameter space is small and you want every combination; pick genetic when the space is large and a guided search is faster.
  • --cores – number of parallel workers that run the backtest leg of each pass in parallel. Each worker uses one CPU thread, so the run uses roughly the same number of threads as the value you pass. Accepted values are integers of 1 or more. Defaults to half the processor count plus one. Lower it on a small VPS to leave room for other workloads, or raise it on a dedicated machine to spread a genetic sweep across more threads.
  • --auto-select-best – automatically select the best pass when the run finishes, so the strongest .cbotset is ready to use without a second step.

Note

The optimize command uses --timeframe, not --period. The run and backtest commands keep --period. Passing --period to optimize is rejected as an unknown option.

The parameters file

The --params file is a JSON object with a parameters array. This is the same shape that the cTrader desktop optimisation interface exports, so a file exported from the desktop application can be passed directly.

{
  "parameters": [
    { "Name": "SlowPeriods",  "Optimize": true, "Min": "5",  "Max": "50", "Step": "5" },
    { "Name": "StopLossPips", "Optimize": true, "Min": "10", "Max": "60", "Step": "5" },
    { "Name": "MAType",       "Optimize": true, "Values": ["0", "1", "2"] },
    { "Name": "MySymbol",     "Optimize": true, "Values": ["EURUSD", "GBPUSD"] }
  ]
}

Field rules

  • Name is required and should match a cBot property name. Run ctrader-cli metadata <path-to-algo> to see the available property names. A name that is not found in the cBot metadata is logged and skipped, and the run continues with the remaining parameters.
  • Optimize set to true includes the parameter in the sweep. Set to false holds it fixed.
  • Range parameters, such as integers and doubles, that are being swept need Min, Max and Step.
  • Value parameters, such as enumerations and symbols, that are being swept need a non-empty Values array.
  • ParameterType is optional. When omitted, the type is resolved from the cBot metadata by matching Name.

Fix a parameter to a single value

To hold a parameter at a fixed value, include it with Optimize: false and its Value:

{ "Name": "MAType",      "Value": "1", "Optimize": false },
{ "Name": "FastPeriods", "Value": "5", "Optimize": false }

Warning

The parameters file is authoritative. Before applying it, cTrader CLI resets every parameter so that only the parameters you list with Optimize: true are swept. A parameter left out of the file entirely is held at its default value, even if it would default to optimised in the cBot. List a parameter with Optimize: true to include it.

Optimise the main timeframe

The optimize command can sweep the main timeframe as well as the cBot parameters. The main timeframe comes from two sources, with --timeframe taking precedence.

  • --timeframe <tf> – one value pins the main timeframe; several comma-separated values sweep it.
  • Parameters file – a desktop-exported file already includes a synthetic timeframe parameter for this purpose.

The base data timeframe is the single value, the pinned value or the smallest of the swept values.

Timeframe and data-mode compatibility

The swept or pinned main-timeframe values must be loadable under the chosen --data-mode.

Data mode Valid main-timeframe values
open Timeframes that are the same frame type and an exact multiple of the smallest selected timeframe.
m1 or m1-csv Any time-based timeframe; non-time frames such as Renko and range are rejected.
ticks Any non-custom timeframe.

Note

An invalid combination stops the command before any data is loaded and lists the values that caused the failure.

Criteria

Each entry in --criteria pairs a performance index with a direction of max or min, such as NetProfit:max. The table below lists every supported index name and what it measures.

Index What it measures
NetProfit Final profit or loss in account currency
ProfitFactor Gross profit divided by gross loss
MaxEquityDrawdownPercentages Largest percentage peak-to-trough drop in equity
MaxBalanceDrawdownPercentages Largest percentage peak-to-trough drop in balance
MaxEquityDrawdown Largest absolute drop in equity, in account currency
MaxBalanceDrawdown Largest absolute drop in balance, in account currency
WinningTrades Number of trades that closed in profit
LosingTrades Number of trades that closed in loss
TotalTrades Total number of closed trades
AverageTrade Net profit divided by the number of closed trades

To maximise net profit while minimising the maximum equity drawdown:

--criteria="NetProfit:max,MaxEquityDrawdownPercentages:min"

For a custom ranking, pass --fitness instead. The cBot's GetFitness method returns the score, and the run keeps the passes with the highest return value. --fitness is mutually exclusive with --criteria; pass exactly one.

Testing-context options

optimize reuses the testing-context options from backtest. The table below lists the options that the live CLI accepts, what each one sets and the difference between the two commands where it matters.

Option Purpose Availability
--account Trading account number. Both
--symbol Symbol to test on. Both
--start Start date and time of the test range. Both
--end End date and time of the test range. Both
--balance Starting balance for the simulation. Both
--data-mode open, m1, m1-csv, tick-csv or ticks. Both
--data-file Path to a CSV file for m1-csv or tick-csv. Both
--commission Commission amount per trade. Both
--spread Spread in pips. Both
--precise-conversion Use precise conversion for cross-currency pairs. Both
--timeframe Base timeframe for the sweep. optimize only
--period Base timeframe for the run. backtest only
--report Path to save an HTML report. backtest only
--report-json Path to save a JSON report. backtest only

Note

The report flags do not apply to optimize, so save results with --optres and --passes-dir instead.

Example

ctrader-cli optimize "C:/test/Sample Trend cBot.algo" \
  --params=C:/test/optimize-params.json \
  --account=1234567 --symbol=EURUSD --timeframe=h1,h2 \
  --start="01/01/2025" --end="01/02/2025" \
  --balance=100000 --data-mode=open --commission=30 --spread=2 \
  --method=grid \
  --criteria="NetProfit:max,MaxEquityDrawdownPercentages:min" \
  --auto-select-best \
  --optres=C:/test/result.optres \
  --passes-dir=C:/test/result-passes \
  --ctid=letstrade --pwd-file=C:/test/password.pwd

Output

While it runs, optimize streams progress to the terminal:

Progress | Loading EURUSD, h1 | 42.00 % |
Progress | Optimization | 37.50 % |
  • Summary – on completion, cTrader CLI prints a summary to the terminal, including the total number of passes, the elapsed time and the best pass with its statistics.
  • Result file – when you pass --optres, cTrader CLI writes the full result as a .optres JSON file that lists every pass. This file uses the same format as the desktop optimisation results, so it can be opened or imported in the desktop optimisation interface.
  • Per-pass reports – when you pass --passes-dir, cTrader CLI writes the per-pass report files into that directory, one subfolder per pass, each containing .html, .txt, .json and .cbotset files. The .cbotset file shows the exact parameter values that pass used.

If you provide neither --optres nor --passes-dir, the run completes and only the summary is printed.

Note

The optimize command does not produce an aggregate HTML report. The per-pass HTML files are still written into --passes-dir when you provide it.

Validate that an optimisation applied correctly

After a run, confirm that the sweep did what you intended.

  1. Open a per-pass .cbotset file under --passes-dir and check that the optimised parameters change between passes, while pinned and omitted parameters stay fixed.
  2. When you swept the timeframe, check the Chart.Period value in each pass .cbotset file. It should match the timeframes you selected.
  3. Open the .optres file, or import it into the desktop optimisation interface, to review the configuration and every pass together.

Validation and common errors

Each row in the table below shows the symptom, the likely cause, the exit code cTrader CLI returns on this failure and the next step to take. cTrader CLI exits with a non-zero status for every validation failure, so a script can stop on the first error without parsing the message.

Exit code in the table refers to the value cTrader CLI returns to the shell. Specific numbers are not published, so an entry of non-zero means the command failed without a distinct code; unknown means the failure is internal and the next step is to switch build or contact support.

Symptom Likely cause Exit Next step
Validation error: missing --params The JSON parameters file was not supplied. non-zero Pass --params=<path>.
Validation error: unknown timeframe A --timeframe value is not a known token. non-zero Run ctrader-cli periods and use one of the listed tokens.
Validation error: invalid main timeframe A timeframe value is not loadable under the chosen --data-mode. non-zero Pick a different timeframe or --data-mode.
Validation error: criteria pairs malformed An index name is wrong, or a direction is not max or min. non-zero Use one of the supported index names with max or min.
Validation error: unknown criteria index A --criteria name is not in the supported list. non-zero Use one of the supported index names listed under Criteria.
Validation error: unknown --method value --method is not genetic or grid. non-zero Use --method=genetic (default) or --method=grid.
--fitness and --criteria both supplied The two are mutually exclusive. non-zero Pass --fitness or --criteria, not both.
optimize not available The CLI build is the internal or cloud edition. unknown Switch to the local user edition.