Objectives

A strategy explores a set of parameter combinations. An objective turns the outcome of a backtest into a score. That score is then used to rank the tested combinations according to the selected criterion.

A strategy can define more than one objective. The engine then produces one ranking per objective from the same backtests.

An objective does not change the strategy logic; it only changes how results are ranked.

The [filters] block removes results that do not meet your criteria. Objectives then rank the remaining ones.

The sharpe_ratio and sortino_ratio variables are computed from portfolio-equity returns sampled at each close of the backtest’s native timeframe, then annualized so test runs on different timeframes can be compared on a consistent basis. The calmar_ratio variable is computed once at the end of the backtest from CAGR / MDD, using the effective backtest period and the engine’s finalized maximum drawdown.

Declaring objectives in TOML

An objective is declared with an [[objective]] block that defines an id and a formula. The id lets you identify the objective in the outputs and must be unique within the strategy. The ascending field defines whether the best score is the smallest one (true) or the largest one (false).

[[objective]]
id        = "profit"
formula   = "netprofit"
ascending = false

If you do not declare any [[objective]] block, a default objective based on net profit is used.

[[objective]]
id        = "netprofit"
formula   = "netprofit"
ascending = false

When a formula becomes long, you can write it across multiple lines with triple quotes. The following examples use that form when it improves readability.

Examples

Sortino ratio

The Sortino ratio ranks combinations from portfolio-equity returns while only measuring downside volatility.

[[objective]]
id        = "sortino"
formula   = "sortino_ratio"
ascending = false

Calmar ratio

The Calmar ratio compares compounded annual growth to maximum drawdown over the effective backtest window.

[[objective]]
id        = "calmar"
formula   = "calmar_ratio"
ascending = false

Recovery factor

The recovery factor compares final net profit to the maximum drawdown in absolute terms. A score of 4, for example, means that net profit is four times larger than the worst drawdown observed.

[[objective]]
id        = "recovery_factor"
formula   = "netprofit / max_drawdown"
ascending = false

Total return over drawdown

This formula is a custom return-over-drawdown score based on total portfolio return, expressed as a percentage, divided by maximum drawdown in percentage terms. If a strategy gains 100% with a maximum drawdown of 25%, its score is 4.

[[objective]]
id        = "total_return_over_dd"
formula   = "((profit_multiplier - 1) * 100) / max_drawdown_percent"
ascending = false

Expectancy score

This objective rebuilds trade expectancy from win rate, average winning trade, and average losing trade, then scales it with the number of closed trades. The score measures whether the average edge per trade remains meaningful as the sample grows.

Here, avg_losing_trade is a positive value. That is why the loss component is explicitly subtracted in the formula.

[[objective]]
id        = "expectancy_score"
formula   = """\
((((percent_profitable / 100) * avg_winning_trade) - \
(((100 - percent_profitable) / 100) * avg_losing_trade)) / \
avg_losing_trade) * closedtrades\
"""
ascending = false

Adapted Pessimistic Return on Capital (PROC)

PROC is a deliberately conservative reading of return on capital. The formula slightly reduces the impact of winning trades and slightly increases the impact of losing trades through a square-root penalty. The result gives less weight to backtests that depend on a small number of favorable trades and gives more weight to steadier profiles.

The final score is expressed as a percentage of initial capital, so it corresponds to a conservative return that already includes a sample-size penalty.

[[objective]]
id        = "pessimistic_return_on_capital"
formula   = """\
(((avg_winning_trade * ((closedtrades * percent_profitable / 100) - \
((closedtrades * percent_profitable / 100) ^ 0.5))) - \
(avg_losing_trade * ((closedtrades * (1 - percent_profitable / 100)) + \
((closedtrades * (1 - percent_profitable / 100)) ^ 0.5)))) / \
initial_capital) * 100\
"""
ascending = false

Multiple objectives

You can declare several objectives to get one ranking per objective in the same optimization run. One objective may highlight the most stable combinations, while another may focus on the relationship between net profit and drawdown.

[[objective]]
id        = "sortino"
formula   = "sortino_ratio"
ascending = false

[[objective]]
id        = "recovery_factor"
formula   = "netprofit / max_drawdown"
ascending = false

Available variables

Objective formulas use backtest variables. The Availability column shows whether a variable can be used in the strategy’s trading expressions or is reserved for objectives. Candle series (OHLCV), indicator outputs, and variables tied to market context or the state of an open position are not available in objectives.

The syntax for expressions, operators, and functions is described in Expressions in TOML strategies.

VariableDescriptionAvailability
initial_capitalStarting capital of the backtest.Strategy and objectives
equityCurrent portfolio value.Strategy and objectives
netprofitFinal net profit.Strategy and objectives
grossprofitSum of profits from winning trades.Strategy and objectives
grosslossSum of losses from losing trades (positive value).Strategy and objectives
grossprofit_percentGross profit as a percentage of initial capital.Strategy and objectives
grossloss_percentGross loss as a percentage of initial capital.Strategy and objectives
avg_winning_tradeAverage profit of winning trades.Strategy and objectives
avg_losing_tradeAverage loss of losing trades.Strategy and objectives
avg_winning_trade_percentAverage profit of winning trades, in percentage terms.Strategy and objectives
avg_losing_trade_percentAverage loss of losing trades, in percentage terms.Strategy and objectives
avg_tradeAverage profit or loss per trade.Strategy and objectives
avg_trade_percentAverage profit or loss per trade, in percentage terms.Strategy and objectives
closedtradesTotal number of closed trades.Strategy and objectives
max_drawdownMaximum drawdown.Strategy and objectives
max_drawdown_percentMaximum drawdown, in percentage terms.Strategy and objectives
max_runupMaximum run-up.Strategy and objectives
max_runup_percentMaximum run-up, in percentage terms.Strategy and objectives
sharpe_ratioAnnualized Sharpe ratio computed from portfolio-equity returns on the backtest’s native timeframe.Objectives only
sortino_ratioAnnualized Sortino ratio computed from portfolio-equity returns on the backtest’s native timeframe.Objectives only
calmar_ratioCalmar ratio computed as CAGR / MDD on the effective backtest period, using max_drawdown_percent / 100 as the drawdown fraction.Objectives only
profit_factorProfit factor, computed as grossprofit / abs(grossloss) (NaN if there is no loss).Objectives only
percent_profitablePercentage of winning trades.Objectives only
profit_multiplierCapital multiplier (final capital / initial capital).Objectives only
exposure_pctMarket exposure, as a percentage.Objectives only
commission_paidTotal fees (in quote currency).Objectives only

For a more detailed description of built-in variables, their update cadence, and series indexing, see Built-in variables.