PineForge v0.1.2-11-ga87241d
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
Report schema

pf_report_t is the single output of every backtest. This page maps each field to its meaning and units.

See also
pf_report_t for the verbatim struct declaration.

Top-level layout

typedef struct pf_report_s {
/* Trades */
int total_trades;
pf_trade_t* trades;
int trades_len;
double net_profit;
/* Bar processing counts */
int64_t input_bars_processed;
int64_t script_bars_processed;
/* Security diagnostics */
int64_t security_feeds_total;
int64_t security_complete_total;
int64_t security_partial_total;
/* Bar magnifier diagnostics */
int64_t magnifier_sub_bars_total;
int64_t magnifier_sample_ticks_total;
/* Timeframe metadata */
int input_tf_seconds;
int script_tf_seconds;
int script_tf_ratio;
int needs_aggregation;
int bar_magnifier_enabled;
/* Per-security feed/eval counters */
pf_security_diag_t* security_diag;
int security_diag_len;
/* Per-bar trace records */
int trace_len;
const char** trace_names;
int trace_names_len;
Backtest report filled by run_backtest / run_backtest_full.
Definition pineforge.h:153
Per-request.security() site diagnostic counters.
Definition pineforge.h:123
Single per-bar trace entry.
Definition pineforge.h:135
Closed-trade record returned in pf_report_t::trades.
Definition pineforge.h:107

Trade fields

Field Type Meaning
total_trades int Closed-trade count. Always equal to trades_len.
trades pf_trade_t* Heap array, ordered by exit time ascending.
trades_len int Length of trades.
net_profit double Sum of all closed-trade PnL in account currency.

pf_trade_t

typedef struct pf_trade_s {
int64_t entry_time; /* Unix ms */
int64_t exit_time; /* Unix ms */
double entry_price; /* incl. slippage */
double exit_price;
double pnl; /* net of commission, in account ccy */
double pnl_pct; /* relative to entry capital */
int is_long; /* 1 = long, 0 = short */
double max_runup; /* peak favorable price travel ($/unit qty) */
double max_drawdown; /* peak adverse price travel ($/unit qty) */
double qty; /* filled quantity */

max_runup and max_drawdown are the per-unit Maximum Favorable Excursion (MFE) and Maximum Adverse Excursion (MAE) for the trade — multiply by qty to recover the dollar values.

Bar processing

Field Meaning
input_bars_processed Source-feed bars consumed.
script_bars_processed Script-timeframe bars evaluated. Differs from input_bars_processed when needs_aggregation == 1.

Timeframe metadata

Field Meaning
input_tf_seconds Detected (or configured) input timeframe, in seconds.
script_tf_seconds Script timeframe, in seconds.
script_tf_ratio script_tf_seconds / input_tf_seconds.
needs_aggregation 1 if input was aggregated up to script TF; 0 if pass-through.
bar_magnifier_enabled 1 if the magnifier ran on this backtest.

See Timeframes for how the runtime resolves these values from the inputs to run_backtest_full.

Security diagnostics

A Pine strategy can call request.security() from multiple call sites. The runtime tracks each site independently.

Field Meaning
security_feeds_total Higher-TF feed bars consumed across all sites.
security_complete_total Evaluations on completed parent bars.
security_partial_total Evaluations on still-forming parent bars.
security_diag[i] Per-site counters. See pf_security_diag_t.
security_diag_len Number of request.security sites.

Bar magnifier diagnostics

Field Meaning
magnifier_sub_bars_total Sub-bars synthesized by the magnifier.
magnifier_sample_ticks_total Sample ticks visited by the magnifier.

A "sub-bar" is one synthetic intra-bar OHLC slice; a "sample tick" is one fill-resolution probe within that slice. With the default PF_MAGNIFIER_ENDPOINTS distribution and magnifier_samples = 4, expect ~4 * input_bars_processed sample ticks.

See Bar magnifier for the full sampling model.

Trace records

Populated only when:

  1. The source script contains // @pf-trace name=expr pragmas, and
  2. strategy_set_trace_enabled was called with 1 before the run.
Field Meaning
trace[i].timestamp Bar timestamp (Unix ms).
trace[i].bar_index Zero-based bar index within the run.
trace[i].name_id Index into trace_names.
trace[i].value Traced expression value on this bar.
trace_names[k] Name string for name_id == k. Lifetime: until strategy_free.

Trace records are zero-cost when disabled — no allocation, no formatting, no per-bar branch.

Lifetime and ownership

Every heap pointer in pf_report_t is freed by a single call to report_free:

pf_report_t r = {0};
run_backtest(s, bars, n, &r);
/* ... use r ... */
report_free(&r); /* frees trades, security_diag, trace */
void run_backtest(pf_strategy_t s, pf_bar_t *bars, int n, pf_report_t *out)
Run a backtest with auto-detected timeframe and no bar magnifier.
void report_free(pf_report_t *report)
Free heap arrays attached to a filled report.
Warning
trace_names points into a string table owned by the strategy handle, not the report. The pointer is valid until strategy_free is called on the handle that produced it. If you keep trace data past that, copy the strings out first.