|
PineForge v0.12.2-8-g8df08f2
Deterministic PineScript v6 backtest runtime — C ABI reference
|
End-to-end backtest you can reproduce from a fresh clone in under a minute. Source: tutorial/.
| Step | What you learn |
|---|---|
| 1 | Build the runtime + transpile a Pine MACD into strategy.so. |
| 2 | Load strategy.so from Python via ctypes. |
| 3 | Push an OHLCV feed and call run_backtest_full. |
| 4 | Read every interesting field of pf_report_t. |
| 5 | Re-run the same compiled strategy with different parameters — no recompile. |
| 6 | Sweep a 2-D parameter grid in parallel using one .so per worker. |
By the end you'll have the canonical patterns for ad-hoc backtests, parameter sweeps, walk-forward windows, and live diagnostic capture.
Requires cmake, g++, and python3.
Configures CMake (first time only), builds tutorial/macd/strategy.so, then runs the harness. Expected output:
Numbers depend on the OHLCV snapshot — refresh with python3 tutorial/data/fetch_btcusdt.py to get current Binance bars.
Mount the strategy + OHLCV into the published runtime image; get a JSON report on stdout.
Same engine, identical numbers. Build the image locally instead with docker build -t pineforge -f docker/Dockerfile . if you don't want to pull from GHCR.
The full harness is ~80 lines. Here's the dataflow, end to end.
Skipped here — see FFI from Python for the complete mirror. The harness defines BarC, TradeC, and ReportC exactly matching pf_bar_t, pf_trade_t, pf_report_t.
(BarC * n)() allocates a contiguous block — the runtime walks it as pf_bar_t[] directly, no copying.
argtypes. Without them, Python silently passes int as 32-bit — your timestamps lose half their bits.Order matters — see Lifecycle § Free everything.
The four pages below pick up where this tutorial leaves off — each one is a self-contained, runnable example targeting a specific use case.
| Example | What it shows |
|---|---|
| Pure C example | Same MACD run, no Python. End-to-end C code with gcc build. |
| Historical to realtime streaming | Warm the same MACD instance on OHLCV, then continue it on ordered trade ticks. |
| Parameter sweep in Python | Re-run one .so with a 2-D MACD grid. No recompile per run. |
| Multi-strategy harness | Load N .so files, run them in parallel against the same feed. |
| Magnifier on vs off | A/B comparison showing how intra-bar fills change the trade list. |
| Calling from Rust | Idiomatic safe Rust wrapper around the C ABI. |
pf_report_t