|
PineForge v0.13.1-379-g9b50973
Deterministic PineScript v6 backtest runtime — C ABI reference
|
Deterministic backtest and forward-execution runtime, validated trade-for-trade against TradingView.
PineForge is a C++17 engine in two layers. The kernel matches triggers, prices fills, sizes orders, books lots, settles margin and computes indicators, time and session math — and knows nothing about PineScript or TradingView. The Pine adapter reproduces TradingView's execution semantics on top of it, and is what a PineForge-compiled strategy attaches.
That gives three front doors, all documented here:
.pine to a .so and drive it over the C ABI in <pineforge/pineforge.h>. This is the path the TradingView parity results measure.NativeStrategyHost and describe the run in one NativeRunSpec. No PineScript, no codegen, no adapter.<pineforge/native_c_api.h> and drive it from any language with a C FFI.<pineforge/source/…>, <pineforge/compat/pine/…>) are internal to the parity layer and carry no stability guarantee. The kernel and native API headers — native_host.hpp, native_run_spec.hpp, native_order.hpp, native_toolkit.hpp, native_c_api.h and pineforge.h — are the surface this site documents and the one a host programs against.NativeStrategyHost, configure_native, execution terms and the C ABI contract. Coming from PineScript, start with PineScript to native C++ — every strategy.* builtin mapped to its C++ and C spelling, the runnable host that exercises each, and a six-feature strategy migrated end to end.pineforge.h — or jump to the Pure C or Rust worked examples.tutorial/run_stream.py against the bundled MACD strategy. The optional native C++ runner is documented in runner/README.md. For the separate Python pineforge-live recompute project, read ABI v4 live surface.pf_metrics_t field with units, NaN rules, and TV / quant-library validation status — alongside the Report schema for the surrounding pf_report_t layout and the equity curve.CONTRIBUTING.md in the repository root for the workflow, the gates and the parity contract, or Contributing as an LLM if you are an agent working from a brief.End-to-end, runnable examples that go beyond the MACD tutorial.
Driving a compiled strategy over the C ABI:
| Example | Use case |
|---|---|
| Tutorial: MACD on BTCUSDT | The 60-second backtest. Start here. |
| Pure C harness | One file, no Python, dlopen + run. |
| Parameter sweep in Python | Re-run one .so over a 2-D grid; sticky configuration; walk-forward variant. |
| Multi-strategy harness | Load N .so files; rank by net PnL; thread-pool execution. |
| Magnifier on vs off | A/B comparison with all six distribution modes. |
| Multi-timeframe (MTF) | script_tf switching, request.security, and lower-TF sub-bar synthesis. |
| Historical to realtime streaming | Warm on confirmed OHLCV and continue the same strategy on ordered trades. |
| Calling from Rust | Idiomatic libloading wrapper with safe Rust types. |
Driving the kernel yourself. Every host under examples/native/ is a complete, self-contained program that checks its own results and is run as a CTest row (ctest --test-dir build -R example_). They link PineForge::kernel directly, so a Pine-layer symbol reaching one is a link error.
| Host | What it demonstrates |
|---|---|
hello_kernel.cpp | The smallest complete host: subclass, describe the run, submit, read the trades. |
hello_kernel_c.c | The same host written against the C API — a callback table, no C++. |
native_market_strategy.cpp | One entry, one flatten, as both a standalone program and a loadable module; batch then stream. |
native_selected_strategy.cpp | Host-sized openings, a child bound to one opening's cycle, a selected close, an exact reversal. |
native_bracket_strategy.cpp | Anchored bracket legs placed before the entry has a price, on a tick ladder. |
native_sized_report_strategy.cpp | Kernel sizing by cash and by equity fraction, and a kernel-recorded report. |
native_margin_strategy.cpp | A per-side margin model, a solved liquidation price and a kernel-issued liquidation. |
native_calc_on_fills_strategy.cpp | Calculation timing: recalculating on each fill, and the open-only bar view. |
native_htf_strategy.cpp | Higher-timeframe series for a bare host, with and without gaps. |
native_auxiliary_feed_strategy.cpp | A series finer than the run's input, built from an auxiliary feed. |
native_trail_risk_strategy.cpp | A trail spelled in ticks, the working book, and a fill-count risk limit. |
native_risk_limits_strategy.cpp | Account money limits, the kernel's own flatten, and the risk day. |
native_price_grid_strategy.cpp | One strategy under all four instrument price-grid answers. |
native_price_grid_c.c | The same four answers from C, read back off the event history. |
native_open_lots_strategy.cpp | The open book lot by lot, and who folds the equity extremes. |
The public C surface is 97 PF_API declarations across two headers:
<pineforge/pineforge.h> — 65: 57 runtime implementations plus eight per-strategy generated exports. This is what a compiled strategy .so exports and what a harness calls.<pineforge/native_c_api.h> (included by pineforge.h) — 32: the other direction, where the host drives the kernel itself. Submit, replace, cancel, execute, read the book, read the lots. Additive: no symbol, struct or behaviour of the first set changes.scripts/check_c_abi_runtime.py pins the first inventory and scripts/check_native_c_api_surface.py the second, so neither can drift.
| Group | Symbols | Reference |
|---|---|---|
| Lifecycle | strategy_create, strategy_free, run_backtest, run_backtest_full, report_free, strategy_closed_trade_entry_incarnation | Strategy lifecycle |
| Streaming | strategy_stream_begin, strategy_stream_push_tick, strategy_stream_push_ticks, strategy_stream_advance_time, strategy_stream_end, strategy_stream_fill_report | Historical to realtime streaming |
| Live runtime (ABI v4) | strategy_request_abort, strategy_set_realtime_tail, strategy_set_probe_suppress_tail_logic, strategy_set_path_order, the broker-state hash, the pending-order mirror, closed-trade id/comment/close-cause, position and equity accessors — 24 default-off exports | Live-runtime surface (ABI v4) |
| Configuration | Inputs, strategy overrides, tracing, trade start, chart / symbol timezone, session, tick size, point value, numeric metadata, and timestamped account-currency FX | Per-strategy configuration |
| Diagnostics | strategy_get_last_error | strategy_get_last_error |
| Version | pf_version_get, pf_abi_version, pf_version_string | Version query |
| Types | pf_bar_t, pf_trade_tick_t, pf_trade_t, pf_report_t, metrics, diagnostics, trace, equity, version, and pf_magnifier_distribution_t | Types |
| Native kernel host (C) | strategy_native_host_create_v1, strategy_native_run_v1, the submit / replace / cancel family, the position, working-book, open-lot, event and state reads, the cohort and subscription calls, and strategy_configure_native_ext_v1 | native_c_api.h |
Every PineForge-generated strategy .so exports the 65 public symbols of pineforge.h and zero internal C++ symbols — see ABI stability for the full guarantee.
Build: cc demo.c -lpineforge -lstdc++ -lm. That's it.
Getting going
| Page | What it covers |
|---|---|
| Getting Started | Build, test, install and link in under a minute. |
| Install | What cmake --install puts where, and the package layout. |
| CMake integration | find_package(PineForge) in a downstream project. |
| Tutorial: MACD on BTCUSDT | One strategy from .pine to a graded trade list. |
Driving a compiled strategy
| Page | What it covers |
|---|---|
| Strategy lifecycle | Handle ownership, run reuse and report freeing. |
| Configuration | Inputs, strategy() overrides, symbol metadata, timezones and sessions. |
| Report schema | pf_report_t field by field, including the equity curve. |
| Trading metrics reference | Every pf_metrics_t field: units, NaN rules, validation status. |
| ABI stability | The append-only guarantee, and the internal C++ epochs behind it. |
| ABI v4 live surface | The default-off live accessors: abort, realtime tail, broker-state hash, pending-order mirror. |
| FFI from Python | A ctypes mirror of every POD in pineforge.h. |
Writing a native host
| Page | What it covers |
|---|---|
| Native engine | The reference: lifecycle, run spec, request vocabulary, the C ABI contract. |
| PineScript to native C++ | Every Pine builtin mapped to its C++ and C spelling, with a worked migration. |
| Contributing as an LLM | The repo map, the boundary invariants and the lane recipe, for an agent. |
How execution works
| Page | What it covers |
|---|---|
| Order execution model | Ownership, reservation and ordering contracts for fills. |
| Market admission | What is checked before an opening reaches the book. |
| Exit-leg lifecycle | How a bracket leg is born, armed, matched and retired. |
| Exit lifecycle reflection | Reading that lifecycle back, and what completion means. |
| Bar magnifier | Intrabar path synthesis and the six distribution modes. |
| Timeframes | Parsing, aggregation and session-aware bucketing. |
| Multi-timeframe (MTF) | request.security, script_tf switching and lower-TF synthesis. |
| Historical to realtime streaming | Warm on OHLCV, continue on ordered trades, keep one state. |
pages/exit-leg-activation.md | The activation bounds an exit leg's matching consumes. |
pages/quantity-intent.md | Requested amount versus native working reservation, in the placement snapshot. |
Coverage and worked examples
| Page | What it covers |
|---|---|
| PineScript v6 coverage | What this runtime owns, what codegen emits inline, what is out of scope. |
| Pure C harness | dlopen a strategy, feed it a CSV, print the trades. |
| Parameter sweep in Python | Re-running one .so over a grid. |
| Multi-strategy harness | N strategies, ranked, in a thread pool. |
| Magnifier on vs off | The A/B that shows what the magnifier changes. |
| Calling from Rust | A safe libloading wrapper. |
libpineforge.a). The PineScript-to-C++ transpiler is a separate, source-available product (PolyForm Noncommercial); this runtime is what every compiled strategy .so links against, and it also runs hosts written directly against the kernel with no transpiler in sight.