52#include <pineforge/version.h>
61#if defined(_WIN32) || defined(__CYGWIN__)
62 #if defined(PINEFORGE_BUILD_SHARED)
63 #define PF_API __declspec(dllexport)
65 #define PF_API __declspec(dllimport)
67#elif defined(__GNUC__) || defined(__clang__)
68 #define PF_API __attribute__((visibility("default")))
86#define PF_ABI_VERSION 4
90#define PINEFORGE_HAS_AUX_SECURITY_FEED_V1 1
94#define PINEFORGE_HAS_NATIVE_SECURITY_FEED_V1 1
98#define PINEFORGE_HAS_NATIVE_FX_CURVE_V1 1
115typedef enum pf_magnifier_distribution_e {
127typedef struct pf_bar_s {
143typedef struct pf_trade_tick_s {
153typedef struct pf_trade_s {
196typedef struct pf_trade_stats_s {
259typedef struct pf_equity_stats_s {
316typedef struct pf_metrics_s {
325typedef struct pf_equity_point_s {
334typedef struct pf_security_diag_s {
346typedef struct pf_trace_entry_s {
365typedef struct pf_report_s {
507#ifndef PINEFORGE_NO_STRATEGY_DECLS
550 const char* input_tf,
551 const char* script_tf,
553 int magnifier_samples,
668 const char* input_tf,
669 const char* script_tf);
679typedef struct pf_stream_order_action {
1019 double* qty,
int* close_only,
int* partition);
1045 double* limit,
double* trail_activation);
1237 const double* account_per_quote,
int n);
1239#ifdef PINEFORGE_HAS_AUX_SECURITY_FEED_V1
1255 const char* input_tf);
1258#ifdef PINEFORGE_HAS_NATIVE_SECURITY_FEED_V1
1283 const char* timeframe,
1314typedef struct pf_version_s {
void strategy_set_syminfo_timezone(pf_strategy_t s, const char *tz)
Plumb the symbol's exchange timezone (IANA string) into syminfo.
void strategy_set_syminfo_mintick(pf_strategy_t s, double mintick)
Set the instrument tick size (syminfo.mintick, default 0.01).
void strategy_set_override(pf_strategy_t s, const char *key, const char *value)
Override a strategy(...) declaration parameter.
void strategy_set_input(pf_strategy_t s, const char *key, const char *value)
Override a Pine input.
const char * strategy_get_last_error(pf_strategy_t s)
Returns the error message captured by the most recent run_backtest / run_backtest_full call on this s...
int strategy_set_native_security_feed(pf_strategy_t s, const char *timeframe, const pf_bar_t *bars, int n)
Copy the exchange's OWN bars of one higher timeframe for same-symbol request.security calls that requ...
void strategy_set_syminfo_session(pf_strategy_t s, const char *session)
Set the symbol's session string (e.g.
void strategy_set_syminfo_pointvalue(pf_strategy_t s, double pointvalue)
Set the instrument point value (syminfo.pointvalue, default 1.0) — the $-per-point-per-contract multi...
void strategy_set_chart_timezone(pf_strategy_t s, const char *tz)
Set the strategy's chart timezone (IANA / POSIX TZ string).
int strategy_set_aux_security_feed(pf_strategy_t s, const pf_bar_t *bars, int n, const char *input_tf)
Copy a finer feed used exclusively by same-symbol request.security calls.
void strategy_set_magnifier_volume_weighted(pf_strategy_t s, int on)
Toggle volume-weighted bar-magnifier sampling.
void strategy_set_trade_start_time(pf_strategy_t s, int64_t timestamp_ms)
Set the earliest Unix-ms timestamp at which strategy order commands may fire.
void strategy_set_syminfo_metadata(pf_strategy_t s, const char *key, double value)
Inject a fundamental/exchange metadata value by Pine member name (e.g.
void strategy_set_trace_enabled(pf_strategy_t s, int on)
Toggle per-bar trace recording.
int strategy_set_syminfo_string(pf_strategy_t s, const char *key, const char *value)
Set one of the remaining string members of syminfo by Pine member name: "ticker", "tickerid",...
int strategy_set_account_currency_fx_series(pf_strategy_t s, const int64_t *effective_from_ms, const double *account_per_quote, int n)
Install a timestamped quote-to-account currency conversion curve.
void strategy_set_syminfo_type(pf_strategy_t s, const char *type)
Set the instrument class (syminfo.type: "forex", "stock", "crypto", "futures", "index",...
int strategy_execution_contract(pf_strategy_t s)
Native execution contract query.
uint64_t strategy_closed_trade_entry_incarnation(pf_strategy_t s, int trade_index)
Return the physical entry incarnation for one closed-trade row.
int strategy_configure_native_fx_curve_v1(pf_strategy_t s, const pf_native_fx_curve_v1 *curve)
Stage an immutable account-currency FX curve on a Ready native handle.
pf_strategy_t strategy_create(const char *params_json)
Allocate a new strategy instance.
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 strategy_free(pf_strategy_t s)
Release a strategy handle previously returned by strategy_create.
void report_free(pf_report_t *report)
Free heap arrays attached to a filled report.
int strategy_configure_native_v1(pf_strategy_t s, const pf_native_run_spec_v1 *spec)
Apply a native v1 specification.
void run_backtest_full(pf_strategy_t s, pf_bar_t *bars, int n, const char *input_tf, const char *script_tf, int bar_magnifier, int magnifier_samples, pf_magnifier_distribution_t magnifier_dist, pf_report_t *out)
Run a backtest with explicit timeframe and magnifier configuration.
double strategy_current_equity(pf_strategy_t s)
Task 9: initial capital plus realized net profit (strategy.initial_capital + strategy....
void strategy_set_probe_suppress_tail_logic(pf_strategy_t s, int on)
Live probe tail suppression (spec §3.2): the LAST bar of the array fed to every subsequent run() runs...
const char * strategy_closed_trade_exit_id(pf_strategy_t s, int trade_index)
See strategy_closed_trade_entry_id for the row-space/lifetime/NULL contract.
void strategy_set_path_order(pf_strategy_t s, int mode)
Force this run's intrabar path order (ABI v4 live-runtime surface): the leg order every OHLC-path hel...
int64_t strategy_script_bars_processed(pf_strategy_t s)
Task 9: total SCRIPT bars dispatched by the most recent run() (mirrors pf_report_t::script_bars_proce...
void strategy_request_abort(pf_strategy_t s)
Request cooperative abort of the run in progress (see c_abi.cpp).
int strategy_closed_trade_close_cause(pf_strategy_t s, int trade_index)
Task 9: why the trade_index-th REPORT-row closed trade exited.
double strategy_position_avg_price(pf_strategy_t s)
The live position's volume-weighted average entry price (position_entry_price_).
const char * strategy_closed_trade_entry_id(pf_strategy_t s, int trade_index)
Task 9: closed-trade id / exit-comment string accessors, indexing the same REPORT row space as strate...
const char * strategy_closed_trade_exit_comment(pf_strategy_t s, int trade_index)
See strategy_closed_trade_entry_id.
int strategy_pending_orders_len(pf_strategy_t s)
Number of orders resting in the engine's pending-order book after the most recent run() (ABI v4 live-...
int64_t strategy_position_cycle_seq(pf_strategy_t s)
The live position's cycle id (position_cycle_seq_): 0 when flat, a fresh nonzero id per open or rever...
int strategy_pending_order_effective_levels(pf_strategy_t s, int index, double *stop, double *limit, double *trail_activation)
The price levels the index-th resting order would fire at, as the engine's fill path resolves them (A...
int strategy_pending_order_level_resolved(pf_strategy_t s, int index)
1 when the index-th resting order's entry-relative offsets (profit_ticks / loss_ticks / trail_points)...
int strategy_pending_order_fill_qty(pf_strategy_t s, int index, double fill_price, double *qty, int *close_only, int *partition)
Engine-computed fill quantity of the index-th resting order (ABI v4 live-runtime surface,...
int strategy_last_bar_dual_entry_path(pf_strategy_t s)
The dual-entry-stop arbitration decided on the LAST bar the most recent run() dispatched: a flat posi...
double strategy_position_size(pf_strategy_t s)
Task 9: the script-facing signed position size (strategy.position_size; KI-64 freeze-aware – while a ...
int strategy_pending_order_get(pf_strategy_t s, int index, void *out, size_t size_in)
Copy the index-th resting order (0-based, the engine's own book order – insertion order; broker fill ...
const pf_field_desc_t * strategy_pending_order_layout(int *count)
The field table of pf_pending_order_v1_t as THIS runtime compiled it – one pf_field_desc_t {name,...
int strategy_last_run_status(pf_strategy_t s)
0 = completed, 1 = NOT_COMPLETED (aborted), -1 = s is NULL.
double strategy_trail_best_price(pf_strategy_t s)
The trail extreme the exit trail legs ride (trail_best_price_: the running high of a long / low of a ...
void strategy_set_broker_state_hash_recording(pf_strategy_t s, int on)
Toggle per-script-bar broker-state hash recording (spec §3.4, ABI v4).
uint64_t strategy_broker_state_hash(pf_strategy_t s)
Return the broker-state hash of the FINAL state after the most recent run() (see strategy_set_broker_...
void strategy_set_realtime_tail(pf_strategy_t s, int on, int horizon_bars)
Live-runtime tail semantics (spec §3.1): the LAST bar of the array fed to every subsequent run() is a...
int strategy_stream_begin(pf_strategy_t s, const pf_bar_t *warmup_bars, int n_warmup, const char *input_tf, const char *script_tf)
Warm a strategy with confirmed OHLCV, then switch the same instance to a realtime trade stream withou...
int strategy_stream_push_tick(pf_strategy_t s, const pf_trade_tick_t *tick)
Push one normalized realtime trade.
int strategy_stream_order_actions_len(pf_strategy_t s)
Queued physical fills since the last clear, in execution order.
int strategy_stream_push_ticks(pf_strategy_t s, const pf_trade_tick_t *ticks, int n)
Push an ordered batch of realtime trades.
uint64_t strategy_stream_state_hash(pf_strategy_t s)
Versioned deterministic fingerprint of observable broker/stream state.
int strategy_stream_api_version(void)
Native live extension version (1).
int strategy_stream_advance_time(pf_strategy_t s, int64_t timestamp_ms)
Advance the stream clock and close every input bar whose end is <= the supplied time.
int strategy_stream_push_bar(pf_strategy_t s, const pf_bar_t *bar)
Consume one confirmed input-timeframe bar.
int strategy_stream_end(pf_strategy_t s, int finalize_partial_input_bar)
End a realtime stream.
int strategy_stream_fill_report(pf_strategy_t s, pf_report_t *out)
Snapshot the cumulative warmup + realtime report.
int strategy_stream_order_action_get(pf_strategy_t s, int index, pf_stream_order_action_t *out)
Copy one action; return 0 on success, -1 on invalid handle/index/output.
void strategy_stream_order_actions_clear(pf_strategy_t s)
Clear observed events after the caller durably journals them.
pf_magnifier_distribution_t
Bar-magnifier sub-bar sampling distribution.
@ PF_MAGNIFIER_FRONT_LOADED
Sample density biased toward bar open.
@ PF_MAGNIFIER_COSINE
Cosine-tapered density.
@ PF_MAGNIFIER_ENDPOINTS
Default — exact O,H,L,C points plus uniform fill between.
@ PF_MAGNIFIER_BACK_LOADED
Sample density biased toward bar close.
@ PF_MAGNIFIER_TRIANGLE
Triangle-tapered density.
@ PF_MAGNIFIER_UNIFORM
Uniform spacing across the parent bar.
pf_version_t pf_version_get(void)
const char * pf_version_string(void)
Full git-derived version descriptor.
void * pf_strategy_t
Opaque handle to a compiled strategy instance.
Single OHLCV bar pushed into the engine.
int64_t timestamp
Bar open time, Unix milliseconds.
Single per-script-bar equity point.
double open_profit
Mark-to-market open P&L at bar close.
double equity
initial_capital + net_profit + open_profit.
int64_t time_ms
Script-bar OPEN timestamp (Unix ms).
Equity-curve-derived statistics (all-trades only, like TV).
double sharpe_tv
Deprecated spelling of pf_equity_stats_s::sharpe_monthly.
double time_in_market_pct
PERCENT (0-100) of script bars with an open position at bar close.
double max_equity_drawdown_pct
max_equity_drawdown relative to the peak in effect (PERCENT 0-100).
double max_equity_drawdown
Peak-to-trough equity drop, positive currency magnitude.
double max_equity_runup_pct
max_equity_runup relative to that trough (PERCENT 0-100).
double buy_hold_return
initial_capital * (last_close/first_open - 1), currency.
double open_pl
Mark-to-market open profit at the final bar.
double max_equity_runup
Trough-to-peak rise where the trough resets on each new equity peak (mirrors the engine's intra-run e...
double sortino_tv
Deprecated spelling of pf_equity_stats_s::sortino_monthly.
double cagr
PERCENT per year: 100*((final_equity/initial_capital)^(1/years)-1).
double recovery_factor
net_profit / max_equity_drawdown (currency / currency).
double calmar
cagr / max_equity_drawdown_pct — BOTH IN PERCENT, so the ratio is dimensionless.
double buy_hold_return_pct
buy_hold_return as PERCENT.
double sharpe_bar
Per-script-bar returns, annualized by observed bar density (bars per year = (len-1)/calendar span),...
double sortino_bar
Same construction as sharpe_bar over per-bar returns; uses population downside deviation.
Composite metrics container: trade stats (all / long / short) + equity-curve stats.
Immutable timestamped account-currency FX curve for a native run.
const int64_t * effective_from_ms
const double * account_per_quote
Versioned native run specification.
uint32_t allowed_open_directions
const char * basecurrency
double initial_margin_fraction
const char * chart_timezone
Backtest report filled by run_backtest / run_backtest_full.
int input_tf_seconds
Detected/configured input timeframe (seconds).
int security_diag_len
Length of security_diag.
int64_t security_feeds_total
Total higher-TF feed bars across all security sites.
int bar_magnifier_enabled
1 if magnifier was active for this run.
pf_trace_entry_t * trace
Per-bar trace records (empty unless tracing enabled).
int trace_names_len
Length of trace_names.
int64_t input_bars_processed
Source-feed bars consumed.
int script_tf_seconds
Script timeframe (seconds).
double net_profit
Sum of all closed-trade PnL.
int trades_len
Length of trades.
int trace_len
Length of trace.
int64_t script_bars_processed
Script-timeframe bars evaluated.
int64_t magnifier_sample_ticks_total
Sample ticks visited by the magnifier.
int total_trades
Closed-trade count (== trades_len), including the range-end close of a position still open after the ...
int64_t security_partial_total
Total partial-bar evals across all security sites.
pf_security_diag_t * security_diag
One entry per request.security site.
int64_t magnifier_sub_bars_total
Sub-bars synthesized by the magnifier.
int64_t broker_state_hash_len
uint64_t * broker_state_hash
const char ** trace_names
Names indexed by pf_trace_entry_t::name_id.
pf_equity_point_t * equity_curve
int64_t security_complete_total
Total complete-bar evals across all security sites.
int script_tf_ratio
script_tf_seconds / input_tf_seconds.
int needs_aggregation
1 if input → script TF aggregation was performed.
pf_trade_t * trades
Heap array of closed trades; script-driven exits first, then the range-end rows (open_at_end=1).
Per-request.security() site diagnostic counters.
int sec_id
Stable id for the request.security site.
int64_t feed_count
Higher-TF feed bars consumed.
int64_t complete_count
Evaluations on completed parent bars.
int64_t partial_count
Evaluations on still-forming parent bars.
One physical emulator lot action.
uint64_t entry_incarnation
Single per-bar trace entry.
double value
Traced expression value on this bar.
int64_t timestamp
Bar timestamp (Unix ms).
int32_t name_id
Index into pf_report_t::trace_names.
int32_t bar_index
Zero-based bar index.
Trade-level statistics block — computed once each for all / long / short.
double avg_win_pct
Mean of per-trade pnl_pct over winning trades.
double avg_win
gross_profit / num_wins.
double net_profit_pct
net_profit as a percent of initial capital (0-100 scale).
double largest_loss_pct
Maximum of -pnl_pct over losing trades (positive magnitude) — an INDEPENDENT maximum,...
int32_t num_losses
Trades with pnl < 0.
double gross_profit
Sum of winning pnl.
int32_t max_consecutive_losses
Longest losing run; even trades reset both streaks.
double avg_loss_pct
Mean of the NEGATED pnl_pct of the losing trades.
double commission_paid
Sum of pf_trade_t::commission in the block.
double percent_profitable
100 * num_wins / num_trades, in PERCENT (0-100).
double largest_win_pct
Maximum pnl_pct over winning trades — an INDEPENDENT maximum, not the pct of the largest-USD win (TV ...
double gross_loss
Sum of |losing pnl| — POSITIVE magnitude (TV display convention).
double gross_profit_pct
gross_profit as a percent of initial capital (0-100 scale).
double largest_loss
Single largest |pnl| among losing trades (positive magnitude).
double avg_bars_in_wins
Mean bar duration of winning trades, inclusive of the entry bar (TV convention, validated 2026-06-12)...
double avg_bars_in_losses
Mean bar duration of losing trades, inclusive of the entry bar (TV convention, validated 2026-06-12).
double profit_factor
gross_profit / gross_loss.
double avg_loss
gross_loss / num_losses (positive magnitude).
double largest_win
Single largest pnl among winning trades.
double avg_bars_in_trade
Mean of (exit_bar_index - entry_bar_index + 1) in SCRIPT bars, over all trades — inclusive of the ent...
double gross_loss_pct
gross_loss as a percent of initial capital (0-100 scale).
int32_t max_consecutive_wins
Longest winning run; even trades reset both streaks.
double expectancy
(num_wins/num_trades)*avg_win - (num_losses/num_trades)*avg_loss, account currency per trade.
double net_profit
Sum of pnl (account currency, net of commission).
int32_t num_trades
Closed trades in this block (all / long-only / short-only).
double avg_trade_pct
Mean of per-trade pnl_pct over all trades.
double ratio_avg_win_avg_loss
avg_win / avg_loss.
double avg_trade
net_profit / num_trades.
int32_t num_even
Trades with pnl == 0.0 exactly; breaks both win and loss streaks; excluded from win/loss averages.
int32_t num_wins
Trades with pnl > 0.
Closed-trade record returned in pf_report_t::trades.
int32_t exit_bar_index
Script-bar index of the exit fill (0-based).
double pnl_pct
Net return-on-cost in percent: pnl (NET of commission) / entry cost (entry_price * qty * pointvalue) ...
double exit_price
Exit fill price (incl.
int32_t open_at_end
1 when this row is the RANGE-END close of a position that was still open after the final bar; 0 for a...
int32_t entry_bar_index
Script-bar index of the entry fill (0-based).
double commission
Entry+exit commission actually deducted from pnl (account currency).
double pnl
Net realized PnL in account currency (commission-inclusive).
int is_long
1 if long, 0 if short.
double max_drawdown
Peak adverse price travel during the trade ($/unit qty).
double qty
Filled quantity.
double max_runup
Peak favorable price travel during the trade ($/unit qty).
int64_t entry_time
Entry fill time (Unix ms).
double entry_price
Entry fill price (incl.
int64_t exit_time
Exit fill time (Unix ms).
One provider-neutral realtime executed-trade update.
double quantity
Traded quantity in symbol volume units (>= 0).
uint64_t sequence
Normalized per-stream sequence, or 0.
int64_t timestamp
Source event time, Unix milliseconds.
double price
Executed trade price (> 0).
Runtime version descriptor returned by pf_version_get.
const char * commit_sha
Short git commit SHA, or "" if unknown.