Skip to content

Backtesting

Runtime options and reports

BacktestOptions dataclass

BacktestOptions(
    input_timeframe: str = "",
    script_timeframe: str = "",
    bar_magnifier: bool = False,
    magnifier_samples: int = 4,
    magnifier_distribution: MagnifierDistribution = ENDPOINTS,
    trace_enabled: bool = False,
    chart_timezone: str | None = None,
    trade_start_time_ms: int | None = None,
)

Runtime options passed to run_backtest_full.

MagnifierDistribution

Bases: IntEnum

PineForge bar-magnifier path sampling distributions.

BacktestReport dataclass

BacktestReport(
    summary: Mapping[str, JsonValue],
    metrics: Mapping[str, Mapping[str, JsonValue]],
    trades: tuple[Mapping[str, JsonValue], ...],
    security_diagnostics: tuple[
        Mapping[str, JsonValue], ...
    ],
    trace: tuple[Mapping[str, JsonValue], ...],
    equity_curve: tuple[Mapping[str, JsonValue], ...],
)

A detached, JSON-safe copy of pf_report_t.

Each trade's max_runup and max_drawdown are the whole-trade favorable and adverse excursions in account currency, net of entry fees. A trade whose open_at_end is true closes a position that was still open after the final bar, at that bar's close rounded to the tick size, without slippage; summary["total_trades"] counts it.

to_dict

to_dict() -> dict[str, JsonValue]

Return a mutable JSON-shaped representation.

PineForgeBacktestRunner runs a compiled strategy library in-process. It accepts libraries that report PineForge C ABI 4, which engine 1.x builds. It refuses any other library before any strategy call, with an EngineBacktestError that says what to do. Libraries without pf_abi_version (engine v0.10.1 or earlier), ABI 2 (engine v0.10.2 through v0.12.3) and ABI 3 (engine v0.13.x) need a rebuild with engine 1.x; pineforge-data 0.2.0 still reads ABI 2. A newer ABI needs a newer pineforge-data. The release container and the FastAPI server do not use this class.

A trade's max_runup and max_drawdown are whole-trade excursions in account currency, net of entry fees, as engine 1.0's pineforge.h documents them. Headers before 1.0 described them as price travel per unit of quantity, but the values did not change: on the README quick start, engines 0.11.0 and 1.0.0 report identical excursions for the 88 trades both report. A trade whose open_at_end is true closes a position still open after the final bar, at that bar's close rounded to the tick size, without slippage. Engine 0.11.0 reports no such row, so the README quick start has 88 trades on it and 89 on engine 1.0.0.

PineForgeBacktestRunner

PineForgeBacktestRunner(library: CDLL)

Thin owner-safe wrapper around one compiled PineForge strategy library.

The library must report PineForge C ABI 4, which engine 1.x builds; like the release image's own harness, the runner requires the exact ABI that pineforge.h asks every caller to check. Libraries that report ABI 2 (engine v0.10.2 to v0.12.3) or ABI 3 (engine v0.13.x) are refused with EngineBacktestError before any strategy call. An ABI 2 trade row lacks open_at_end and is 8 bytes shorter, so every row after the first would be misread; an ABI 3 report lacks the broker-state hash.

load classmethod

load(
    strategy_library: str | Path,
) -> PineForgeBacktestRunner

Load a compiled strategy shared library from disk.

run

run(
    bars: Sequence[Bar],
    *,
    instrument: Instrument,
    options: BacktestOptions | None = None,
    strategy_params: Mapping[str, JsonValue] | None = None,
) -> BacktestReport

Run confirmed normalized bars and return a detached report.

EngineBacktestError

Bases: RuntimeError

A PineForge historical backtest could not be completed.

Published release container

DockerBacktestRuntime dataclass

DockerBacktestRuntime(
    image: str = DEFAULT_RELEASE_IMAGE,
    pull_policy: PullPolicy = "missing",
    timeout_seconds: float = 300.0,
)

Pull and execute an immutable pineforge-release image.

ensure_image

ensure_image() -> str

Apply the configured pull policy and return the immutable image ref.

run

run(
    pine_source: str,
    bars: Sequence[Bar],
    *,
    instrument: Instrument,
    source: str,
    options: BacktestOptions,
    strategy_params: Mapping[str, JsonValue] | None = None,
    strategy_overrides: Mapping[str, JsonValue]
    | None = None,
) -> dict[str, object]

Run PineScript and normalized OHLCV in pineforge-release.

DockerPrerequisiteError

Bases: RuntimeError

Docker or the configured release image is unavailable.

DockerExecutionError

Bases: RuntimeError

The isolated release-container backtest failed.

DEFAULT_RELEASE_IMAGE module-attribute

DEFAULT_RELEASE_IMAGE = "ghcr.io/pineforge-4pass/pineforge-release:1.0.0@sha256:b271873d0e91a9eeeb4595daaded9bdfbdbcd3925d3ec1300a833395e2004c86"

ReleaseContractError

Bases: ValueError

A request or release-image response violates the integration contract.

Remote FastAPI client

FastApiBacktestClient dataclass

FastApiBacktestClient(
    base_url: str,
    timeout_seconds: float = 330.0,
    api_key: str | None = None,
    max_response_bytes: int = 128 * 1024 * 1024,
)

Submit normalized bars to a bounded remote PineForge runtime.

BacktestServerError

Bases: RuntimeError

The configured FastAPI server rejected or failed a backtest.