Every performance stat the run reports, its exact formula, and its edge cases. The stats are computed by the kScript (legacy) engine's own statistics module, vendored unchanged, and delivered under strategy.output.stats in the backtest report and under the run's strategy key on a chart. Percent-scaled fields end in Pct and are already multiplied by 100.
{
"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
| Stat | Definition |
|---|---|
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 backtest card's benchmark is this number. |
Trades
| Stat | Definition |
|---|---|
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. |
Risk
| Stat | Definition |
|---|---|
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. |
Costs
| Stat | Definition |
|---|---|
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 in this release, which attaches no funding data. |
fundingEventsApplied | Settlements applied to an open position. |
fundingUnavailableCount | Bars an open perps position had no covering funding data under funding: "data": in this release every such bar. The disclosure counter; no rate is ever invented. |
Slippage is not a separate stat line: it is priced into every fill.
Perps
| Stat | Definition |
|---|---|
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.
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:
| Stat | Definition |
|---|---|
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: 0, null and {} in this release, which attaches no finer-interval data. |
bookSlippageFillCount, bookSlippageUnavailableCount, bookSlippageAvgBps | The book-estimate slippage model's counters: 0, 0 and null, because that model is refused by name in this release. |
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 full run (a backtest, a chart's first render) every bar is confirmed, the newest included: an order placed on the last bar rests pending. On a live chart the newest bar is the forming bar: it is marked, never filled, and its orders are rejected and counted, so pending-order and stat values can shift once between the first render and the first tick, and settle when the bar confirms.