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 = falseIf you do not declare any [[objective]] block, a default objective based on net profit is used.
[[objective]]
id = "netprofit"
formula = "netprofit"
ascending = falseWhen 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 = falseCalmar ratio
The Calmar ratio compares compounded annual growth to maximum drawdown over the effective backtest window.
[[objective]]
id = "calmar"
formula = "calmar_ratio"
ascending = falseRecovery 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 = falseTotal 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 = falseExpectancy 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 = falseAdapted 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 = falseMultiple 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 = falseAvailable 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.
| Variable | Description | Availability |
|---|---|---|
initial_capital | Starting capital of the backtest. | Strategy and objectives |
equity | Current portfolio value. | Strategy and objectives |
netprofit | Final net profit. | Strategy and objectives |
grossprofit | Sum of profits from winning trades. | Strategy and objectives |
grossloss | Sum of losses from losing trades (positive value). | Strategy and objectives |
grossprofit_percent | Gross profit as a percentage of initial capital. | Strategy and objectives |
grossloss_percent | Gross loss as a percentage of initial capital. | Strategy and objectives |
avg_winning_trade | Average profit of winning trades. | Strategy and objectives |
avg_losing_trade | Average loss of losing trades. | Strategy and objectives |
avg_winning_trade_percent | Average profit of winning trades, in percentage terms. | Strategy and objectives |
avg_losing_trade_percent | Average loss of losing trades, in percentage terms. | Strategy and objectives |
avg_trade | Average profit or loss per trade. | Strategy and objectives |
avg_trade_percent | Average profit or loss per trade, in percentage terms. | Strategy and objectives |
closedtrades | Total number of closed trades. | Strategy and objectives |
max_drawdown | Maximum drawdown. | Strategy and objectives |
max_drawdown_percent | Maximum drawdown, in percentage terms. | Strategy and objectives |
max_runup | Maximum run-up. | Strategy and objectives |
max_runup_percent | Maximum run-up, in percentage terms. | Strategy and objectives |
sharpe_ratio | Annualized Sharpe ratio computed from portfolio-equity returns on the backtest’s native timeframe. | Objectives only |
sortino_ratio | Annualized Sortino ratio computed from portfolio-equity returns on the backtest’s native timeframe. | Objectives only |
calmar_ratio | Calmar ratio computed as CAGR / MDD on the effective backtest period, using max_drawdown_percent / 100 as the drawdown fraction. | Objectives only |
profit_factor | Profit factor, computed as grossprofit / abs(grossloss) (NaN if there is no loss). | Objectives only |
percent_profitable | Percentage of winning trades. | Objectives only |
profit_multiplier | Capital multiplier (final capital / initial capital). | Objectives only |
exposure_pct | Market exposure, as a percentage. | Objectives only |
commission_paid | Total 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.