Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ for the full tool catalog, request schemas, and env vars (`PINEFORGE_ALLOW_ANYWH

- 🎯 **TradingView-exact.** 251 of 252 reference strategies match TV trade-for-trade. The lone outlier is a stress probe at the 1× margin boundary where TV's broker emulator is non-deterministic — engine is correct. **100 of 100** PineForge excellent vs PyneCore + PineTS on the public three-way benchmark (~167,000 TV trades; PyneCore: 85 of 100; PineTS indicator-only).
- ⚡ **Microsecond-class.** Median **162× faster than PyneCore** across 99 commonly-timed strategies (full 41,307-bar OHLCV, magnifier-on hot loop; see [benchmarks/results/speed.md](benchmarks/results/speed.md)). Parameter sweeps load one `.so` and re-run with new inputs — no recompile, no fork, no IPC.
- 🔒 **Stable C ABI.** 26 functions, one header (`<pineforge/pineforge.h>`). Append-only across minor versions, `static_assert`-pinned struct layouts, hidden-visibility hygiene. Drop a strategy `.so` in any harness; it just runs.
- 🔒 **Stable C ABI.** 27 functions, one header (`<pineforge/pineforge.h>`). Append-only across minor versions, `static_assert`-pinned struct layouts, hidden-visibility hygiene. Drop a strategy `.so` in any harness; it just runs.
- 🧪 **Reproducible to the bit.** Deterministic float ordering, deterministic bar magnifier, no internal RNG seeded from time. Two runs with the same inputs produce bit-identical trade lists.
- 🧰 **FFI-friendly.** Call from Python (`ctypes`), Rust (`libloading`), Go (`cgo`), Node, Julia. Worked examples for [pure C](https://cdocs.pineforge.dev/examples_c.html), [Python sweep](https://cdocs.pineforge.dev/examples_python_sweep.html), [Rust](https://cdocs.pineforge.dev/examples_rust.html), [multi-strategy harness](https://cdocs.pineforge.dev/examples_multi.html), and [magnifier A/B](https://cdocs.pineforge.dev/examples_magnifier.html) ship in the docs.
- 🌍 **Cross-platform CI.** Linux + macOS × Release + Debug. Universal mac binary. Static library, no runtime DSO surprises at deploy time.
Expand All @@ -129,7 +129,7 @@ for the full tool catalog, request schemas, and env vars (`PINEFORGE_ALLOW_ANYWH

## For developers: embed the runtime directly

PineForge ships as a static C library (`libpineforge.a`) with a stable 26-symbol C ABI. Call from C, Python, Rust, Go, Node, Julia — one harness, swap strategies forever.
PineForge ships as a static C library (`libpineforge.a`) with a stable 27-symbol C ABI. Call from C, Python, Rust, Go, Node, Julia — one harness, swap strategies forever.

### See it in 30 seconds

Expand Down Expand Up @@ -337,6 +337,7 @@ int main(void) {
| `strategy_set_syminfo_mintick` | Set symbol tick size |
| `strategy_set_syminfo_pointvalue` | Set symbol point value |
| `strategy_set_syminfo_metadata` | Inject numeric symbol metadata |
| `strategy_set_account_currency_fx_series`| Set effective-time quote-to-account FX |
| `strategy_get_last_error` | Read the latest runtime error |
| `pf_version_get` | Runtime version |
| `pf_abi_version` | Struct-layout version (`PF_ABI_VERSION`) |
Expand Down Expand Up @@ -397,7 +398,7 @@ cmake/smoke_consumer/ - Minimal find_package(PineForge) CI smoke project

## Visibility hygiene

Every compiled strategy `.so` that statically links `libpineforge.a` exports **exactly the 26 documented C ABI symbols** and zero internal C++ symbols. This is enforced at the library level:
Every compiled strategy `.so` that statically links `libpineforge.a` exports **exactly the 27 documented C ABI symbols** and zero internal C++ symbols. This is enforced at the library level:

- `libpineforge.a` is built with `-fvisibility=hidden -fvisibility-inlines-hidden`
- Public symbols are tagged `PF_API` (visibility=default)
Expand Down
8 changes: 7 additions & 1 deletion docs/cheatsheet-runtime-and-execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ recompiling. "Compile-time" = baked into `generated.cpp` from the Pine
| `strategy_set_syminfo_timezone(s, tz)` | `UTC` | Exchange TZ → feeds `session.ismarket` / `time(session)`. **Separate slot** from chart tz. |
| `strategy_set_syminfo_session(s, str)` | `24x7` | Session string e.g. `0930-1600:23456` (days 1=Sun..7=Sat). |
| `strategy_set_syminfo_metadata(s, key, double)` | reads `na` | Inject a fundamental field (`shares_outstanding_total`, `target_price_*`, …); engine only computes — data fed externally. |
| `strategy_set_account_currency_fx_series(s, timestamps, rates, n)` | scalar metadata fallback | Copy a strictly increasing effective-time quote-to-account FX curve. Selection is inclusive as-of, carries forward, and uses the scalar fallback before the first point. Curve presence selects the converted-currency broker ledger even when the effective rate equals 1. Passing `n=0` clears it. Ordinary historical, non-COOF, non-magnifier runs only; a broker-open rate change on a margin-call-enabled carried position is supported for TV-pinned 1x longs, while carried shorts and leveraged positions fail closed. |

Run entry points: `run_backtest(s,bars,n,out)` (auto-detect TF, no magnifier) /
`run_backtest_full(s,bars,n,input_tf,script_tf,bar_magnifier,magnifier_samples,magnifier_dist,out)`.
Expand Down Expand Up @@ -94,7 +95,12 @@ Any non-meta key → `strategy_set_input`. Recognized: `ohlcv_csv`,
`ohlcv_start_ms`, `script_tf`, `input_tf`, `chart_timezone`, and a
`runtime_overrides` block: `bar_magnifier`, `magnifier_distribution`,
`magnifier_samples`, `magnifier_volume_weighted`, `timezone`, `session`,
`syminfo_metadata`. `tv_trades_csv` / `tv_trades_csv_tz` are verify-only.
`syminfo_metadata`, `account_currency_fx_daily_close_json`.
The FX JSON is a non-empty `{\"YYYY-MM-DD\": close}` object. The adapter sorts
dates and makes day D's UTC close effective at D+1 00:00 UTC; the latest point
whose effective timestamp is at or before the broker event carries forward.
Duplicate dates and non-positive/non-finite rates fail closed. The Docker runner
does not support this input. `tv_trades_csv` / `tv_trades_csv_tz` are verify-only.

> `engine_chart_timezone` is **NOT** a `run_strategy.py` key — it's consumed
> only by the private canonical validator. In this harness use `chart_timezone`.
Expand Down
5 changes: 3 additions & 2 deletions docs/coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
## Public C ABI

`<pineforge/pineforge.h>` is the **single canonical consumer header**.
Every compiled PineForge strategy `.so` exports exactly the 26 symbols
Every compiled PineForge strategy `.so` exports exactly the 27 symbols
declared there:


Expand Down Expand Up @@ -88,6 +88,7 @@ declared there:
| `strategy_set_syminfo_mintick` | Instrument tick size (`syminfo.mintick`) |
| `strategy_set_syminfo_pointvalue` | Futures $-per-point multiplier (`syminfo.pointvalue`) |
| `strategy_set_syminfo_metadata` | Inject fundamental / exchange metadata by Pine member name |
| `strategy_set_account_currency_fx_series`| Effective-time quote-to-account conversion curve |
| `strategy_get_last_error` | Error message from the most recent failed run |
| `pf_version_get` | Runtime version (struct) |
| `pf_abi_version` | Caller-allocated POD layout version |
Expand Down Expand Up @@ -119,7 +120,7 @@ single `.hpp`):

| Module | Header | Source | Pine-facing role |
| ------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Public C ABI | `pineforge.h` | `c_abi.cpp` (+ layout `static_assert`s) | The 26 documented C symbols every compiled strategy `.so` exports. |
| Public C ABI | `pineforge.h` | `c_abi.cpp` (+ layout `static_assert`s) | The 27 documented C symbols every compiled strategy `.so` exports. |
| Engine | `engine.hpp` | `engine_run.cpp`, `engine_stream.cpp`, `engine_orders.cpp`, `engine_fills.cpp`, `engine_path_resolve.cpp`, `engine_strategy_commands.cpp`, `engine_trade_accessors.cpp`, `engine_security.cpp`, `engine_lower_tf.cpp`, `engine_risk.cpp`, `engine_report.cpp` | One-shot and continuous lifecycle, orders, raw-trade/bar fills, risk, reports, inputs / syminfo, magnifier, TF aggregation, and `request.security` plumbing. |
| Engine internals | `engine_internal.hpp` | (private cross-TU header) | `pineforge::internal::`* types and helpers shared between engine `.cpp` partitions; not part of the public ABI. |
| Technical analysis | `ta.hpp` | `ta_moving_averages.cpp`, `ta_oscillators.cpp`, `ta_volatility_trend.cpp`, `ta_extremes_volume.cpp`, `ta_misc.cpp` | Official `ta.`* functions and series variables backed by stateful runtime classes with `compute` / `recompute`, plus `pivot_point_levels(...)` free function. |
Expand Down
3 changes: 2 additions & 1 deletion docs/pages/abi-stability.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Three layers:

## Symbol inventory

A compiled strategy `.so` exports **exactly these 26 C symbols** and
A compiled strategy `.so` exports **exactly these 27 C symbols** and
zero internal C++ symbols:

| Symbol | Group |
Expand All @@ -81,6 +81,7 @@ zero internal C++ symbols:
| `strategy_set_syminfo_mintick` | @ref pf_config |
| `strategy_set_syminfo_pointvalue` | @ref pf_config |
| `strategy_set_syminfo_metadata` | @ref pf_config |
| `strategy_set_account_currency_fx_series` | @ref pf_config |
| `strategy_get_last_error` | Diagnostics |
| `pf_version_get` | @ref pf_version |
| `pf_abi_version` | @ref pf_version |
Expand Down
6 changes: 3 additions & 3 deletions docs/pages/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,18 @@ End-to-end, runnable examples that go beyond the MACD tutorial:

## API at a glance

The entire public surface fits in **one header** and **26 functions**:
The entire public surface fits in **one header** and **27 functions**:

| Group | Symbols | Reference |
| --- | --- | --- |
| Lifecycle | `strategy_create`, `strategy_free`, `run_backtest`, `run_backtest_full`, `report_free` | @ref pf_lifecycle |
| Streaming | `strategy_stream_begin`, `strategy_stream_push_tick`, `strategy_stream_push_ticks`, `strategy_stream_advance_time`, `strategy_stream_end`, `strategy_stream_fill_report` | @ref pf_streaming |
| Configuration | Inputs, strategy overrides, tracing, trade start, chart / symbol timezone, session, tick size, point value, and numeric metadata | @ref pf_config |
| Configuration | Inputs, strategy overrides, tracing, trade start, chart / symbol timezone, session, tick size, point value, numeric metadata, and timestamped account-currency FX | @ref pf_config |
| Diagnostics | `strategy_get_last_error` | #strategy_get_last_error |
| Version | `pf_version_get`, `pf_abi_version`, `pf_version_string` | @ref pf_version |
| Types | `pf_bar_t`, `pf_trade_tick_t`, `pf_trade_t`, `pf_report_t`, metrics, diagnostics, trace, equity, version, and `pf_magnifier_distribution_t` | @ref pf_types |

Every PineForge-generated strategy `.so` exports exactly these 26 symbols
Every PineForge-generated strategy `.so` exports exactly these 27 symbols
and zero internal C++ symbols — see
**[ABI stability](@ref abi_stability)** for the full guarantee.

Expand Down
Loading
Loading