Compute standard metrics from backtest results
Details
Standard metrics are derived from the ledger and equity curve:
total_return: last public equity row divided by the first public equity row minus 1.annualized_return: geometric annualized return from the first and last public equity rows using the detected bar frequency, snapped to common frequencies such as daily or weekly.volatility: annualized standard deviation of adjacent public equity-row returns.sharpe_ratio: annualized Sharpe ratio over adjacent public equity-row excess returns, using the scalar annualrisk_free_rateconverted to a per-period return with the detected bar frequency. Flat, constant-return, invalid, or short return series returnNA_real_.max_drawdown: maximum peak-to-trough percentage decline,min(equity / cummax(equity) - 1).n_trades: number of closed trade rows. Open-only fills do not count until a later fill closes quantity.win_rate: share of closed trade rows with strict realized P&L> 0; breakeven is not a win, and open-position gains remain in equity until closed.avg_trade: mean realized P&L across closed trade rows.time_in_market: share of equity timestamps with absolutepositions_value > 1e-6.
Examples
bars <- data.frame(
ts_utc = as.POSIXct("2020-01-01", tz = "UTC") + 86400 * 0:3,
instrument_id = "AAA",
open = c(100, 101, 102, 103),
high = c(101, 102, 103, 104),
low = c(99, 100, 101, 102),
close = c(100, 101, 102, 103),
volume = 1000
)
strategy <- function(ctx, params) {
targets <- ctx$flat()
targets["AAA"] <- 1
targets
}
bt <- ledgr_backtest(data = bars, strategy = strategy, initial_cash = 1000)
ledgr_compute_metrics(bt)
#> $total_return
#> [1] 0.002
#>
#> $annualized_return
#> [1] 0.1827382
#>
#> $volatility
#> [1] 0.009160577
#>
#> $sharpe_ratio
#> [1] 18.3303
#>
#> $max_drawdown
#> [1] 0
#>
#> $n_trades
#> [1] 0
#>
#> $win_rate
#> [1] NA
#>
#> $avg_trade
#> [1] NA
#>
#> $time_in_market
#> [1] 0.75
#>
close(bt)