Stats reference

View as MarkdownOpen the editor

Every performance stat a strategy run computes, its exact formula, its edge cases, and where the Strategy Tester shows it.

The stats come from the engine's own statistics module, and the Tester reads them from the run's result. Percent-scaled fields end in Pct and are already multiplied by 100. One run's stats record:

json
{
  "netProfit": 123.4,
  "netProfitPct": 1.234,
  "grossProfit": 310.2,
  "grossLoss": 186.8,
  "profitFactor": 1.66,
  "totalTrades": 12,
  "winTrades": 7,
  "lossTrades": 5,
  "winRatePct": 58.33,
  "avgTrade": 10.28,
  "avgWin": 44.31,
  "avgLoss": 37.36,
  "payoffRatio": 1.19,
  "largestWin": 96.1,
  "largestLoss": 61.5,
  "avgBarsInTrade": 9.4,
  "maxDrawdown": 402.6,
  "maxDrawdownPct": 3.98,
  "maxRunup": 640.2,
  "sharpe": 0.91,
  "sortino": 1.4,
  "exposurePct": 22.1,
  "buyHoldReturnPct": 4.1,
  "feesPaid": 32.1,
  "makerFeesPaid": 0,
  "takerFeesPaid": 0,
  "fundingPaid": 0,
  "fundingEventsApplied": 0,
  "fundingUnavailableCount": 0,
  "liquidationCount": 0,
  "liquidationHalted": false,
  "bankruptcyDeficit": 0,
  "rejectedOrders": 1,
  "ambiguousFillCount": 0,
  "fineResolvedCount": 0,
  "fineFillCoveragePct": null,
  "fillResolutionByLane": {},
  "bookSlippageFillCount": 0,
  "bookSlippageUnavailableCount": 0,
  "bookSlippageAvgBps": null,
  "long": { "netProfit": 123.4, "totalTrades": 12, "winRatePct": 58.33 },
  "short": { "netProfit": 0, "totalTrades": 0, "winRatePct": 0 }
}

Returns

netProfit

Sum over closed trades of pnl - fees (a trade record's pnl is the price move, its fees the trade's total). netProfitPct is relative to initialCapital.

grossProfit / grossLoss

Sum of winning trades' net results and the absolute sum of losing trades'.

profitFactor

grossProfit / grossLoss; null when there are no losses.

buyHoldReturnPct

(lastConfirmedClose / firstTradableClose - 1) * 100 over the run's confirmed bars: what doing nothing would have returned. The Performance tab's Buy & hold return is this number.

In the Tester: Net profit (with netProfitPct) and Profit factor sit in the Overview's stats column, and the Performance tab's Returns group shows Net profit, Gross profit / loss and Buy & hold return.

Trades

totalTrades, winTrades, lossTrades

Closed trades and the split; winRatePct is winTrades / totalTrades * 100.

avgTrade, avgWin, avgLoss

Mean net result per closed trade, per winner, per loser (avgLoss is a magnitude).

payoffRatio

avgWin / avgLoss; null when there are no losers. Read it with the win rate: 40% winners at a 3.0 payoff is profitable, 70% at 0.3 is not.

largestWin, largestLoss

The single best and worst closed trades. If largestWin dominates netProfit, one trade made the backtest.

avgBarsInTrade

Mean holding time in bars (exitBar - entryBar).

rejectedOrders

Orders the broker refused and counted: the pyramiding cap, conflicting or missing legs, a size the equity could not fund, a non-finite or unconfirmed bar (a live chart's forming bar included); on perps also insufficient margin and post-halt entries.

In the Tester: the Overview's Win rate is winRatePct and the Performance tab's Avg trade / payoff is avgTrade and payoffRatio. The trade counts in both tabs are counted from the trade list (the Overview's Trades includes a trade still open), and the Long vs short and P&L distribution cards (largest win and loss, best and worst streaks) are worked out from the closed trades.

Risk

maxDrawdown

Largest peak-to-trough equity decline over the run, in money; maxDrawdownPct is relative to the peak it fell from. The per-bar drawdown series is the money distance from the running peak.

maxRunup

Mirror of drawdown: the largest trough-to-peak climb.

sharpe

mean(r) / sampleStd(r) * sqrt(barsPerYear) over per-bar equity returns on confirmed bars, barsPerYear = 31,536,000,000 / intervalMs; zero with no variance. Annualized from the run's interval, so compare across runs at the same interval.

sortino

Sharpe with the downside deviation (returns below zero) in the denominator.

exposurePct

Bars with a nonzero position over all confirmed bars, times 100.

In the Tester: Max drawdown (maxDrawdownPct and maxDrawdown) and Sharpe sit in the Overview, where the equity curve's DD lane is the drawdown bar by bar and Trades carries the exposure; the Performance tab's Risk group shows Max drawdown, Max runup and Exposure, and Sharpe / Sortino sits under Returns.

Costs

feesPaid

Total fees across all fills, already subtracted from equity and netProfit (funding excluded). Spot: commissionPercent of each fill's notional. Perps: exactly makerFeesPaid + takerFeesPaid.

makerFeesPaid / takerFeesPaid

Perps fees by fill class; both 0 on spot even with rates declared.

fundingPaid

Net funding settled against open perps positions, signed from the strategy's side; 0 under funding: "off", on spot, and on the chart, which attaches no funding data to a strategy run.

fundingEventsApplied

Settlements applied to an open position.

fundingUnavailableCount

Bars an open perps position had no covering funding data under funding: "data": on the chart every such bar. The disclosure counter; no rate is ever invented.

Slippage is not a separate stat line: it is priced into every fill.

In the Tester: the Performance tab's Trades group carries Fees paid, and on perps Maker fees paid, Taker fees paid, and Funding paid (or Funding received when the strategy was paid); Run details show fundingUnavailableCount as "Funding data did not cover N bars".

Perps

liquidationCount

Trades force-closed by the broker's liquidation stop; those trades carry exitReason: "liquidation". One liquidation can close several open trade records in the same net position.

liquidationHalted

true when onLiquidation: "halt" stopped the run at the first liquidation; every subsequent entry counts as rejected.

bankruptcyDeficit

The shortfall a liquidation fill left beyond the position's committed margin: how far equity would have gone below zero before the floor.

Perps runs also add committedMarginSeries and fundingPaidSeries beside the stats; both are omitted on spot.

In the Tester: a liquidated trade reads Liquidated under Exit via, and the Overview says when and at what price the first liquidation happened, how many there were, and whether the strategy continued or halted. Its Margin chart draws committedMarginSeries, and its Funding chart draws fundingPaidSeries with the sign flipped, so paying walks down.

Long and short splits

long and short carry netProfit, totalTrades and winRatePct per direction. A "market-neutral" idea whose entire profit sits in long during a bull window is a long-only idea with extra steps.

Simulation-quality stats

These describe how the result was produced, not how the strategy performed:

ambiguousFillCount

Intrabar ordering decisions settled by the declared fillModel rather than data; see fill simulation.

fineResolvedCount, fineFillCoveragePct, fillResolutionByLane

Ordering questions settled by walking finer bars. The chart attaches no finer-interval data to a strategy run, so fineResolvedCount is 0 and fillResolutionByLane is {}; fineFillCoveragePct is null while no fill was contested and 0 once one was.

bookSlippageFillCount, bookSlippageUnavailableCount, bookSlippageAvgBps

The book-estimate slippage model's counters: 0, 0 and null, because the chart refuses that model by name.

In the Tester: ambiguousFillCount is Model-settled fills in the Performance tab, with a ± fill badge on each such trade, and the fine-fill fields become the Run details precision line: "Fill precision: exact" while fineFillCoveragePct is null, "Fill precision: bar resolution" once a contested fill was settled by the model.

Equity accounting, precisely

Equity on every bar i is cash plus the open position marked at close[i], fees already paid, recorded on flat bars too. Per-bar returns for Sharpe and Sortino are r_i = equity_i / equity_{i-1} - 1 over confirmed bars with positive prior equity. On a live chart the forming bar is marked, never filled, so pending-order and stat values can shift once between the first render and the first live update, and settle when the bar confirms; fill simulation says which bars count as confirmed.