Backtesting with PineForge Data¶
The harness accepts raw PineScript. Data acquisition stays in Python while
transpilation, compilation, and deterministic execution stay in
pineforge-release.
Execution modes¶
Local release container¶
Without a server URL, the harness pulls and runs the pinned release image
locally. The container has networking disabled, a read-only root filesystem,
dropped capabilities, no-new-privileges, a read-only input mount, and an
executable /tmp tmpfs required for strategy compilation.
FastAPI server¶
Set --server-url or PINEFORGE_SERVER_URL to send raw Pine and normalized
bars to the concurrent server. Provider credentials and provider API calls stay
on the harness host. Set PINEFORGE_SERVER_API_KEY for bearer authentication.
The server returns synchronously while accepting multiple requests. Capacity, queueing, timeouts, authentication, deployment, and compiled-strategy caching are documented in the server guide.
CLI reference¶
pineforge-backtest \
--pine strategy.pine \
--provider ccxt \
--venue kraken \
--symbol BTC/USD \
--timeframe 15m \
--start 2025-07-01T00:00:00Z \
--end 2025-07-08T00:00:00Z
| Group | Options |
|---|---|
| Strategy | --pine, --strategy-params, --strategy-overrides |
| Data source | --provider, --venue/--exchange, --symbol, --timeframe, --start, --end, --limit, --warmup-bars, --provider-config |
| Pine context | --timezone, --session, --engine-timeframe, --script-timeframe |
| Fill modeling | --bar-magnifier, --magnifier-samples |
| Local runtime | --runtime-image/--image, --pull-policy, --execution-timeout |
| Remote runtime | --server-url, --server-api-key-env, --execution-timeout |
| Output | --output, --pretty |
--start and --end accept Unix milliseconds or timezone-aware ISO-8601. The
end is exclusive. --engine-timeframe defaults to a Pine-compatible conversion
of the provider timeframe, and --script-timeframe defaults to the engine
timeframe.
Indicator warmup¶
Use --warmup-bars to load source bars before --start without allowing the
strategy to place orders during that earlier interval:
pineforge-backtest \
--pine strategy.pine \
--provider ccxt \
--venue kraken \
--symbol BTC/USD \
--timeframe 15m \
--start 2025-07-01T00:00:00Z \
--end 2025-07-08T00:00:00Z \
--warmup-bars 500
The warmup bars initialize indicators, higher-timeframe feeds, and persistent
Pine variables. PineForge suppresses order commands until --start, so broker
state and trade counters begin at the requested backtest boundary. The default
is 0 for backward compatibility.
Providers can return fewer warmup bars when history is unavailable or the
market has gaps. The report records warmup_bars_requested,
warmup_bars_loaded, the expanded provider_start_ms, and the effective
trade_start_time_ms. When --limit is set, warmup capacity is added to that
limit so it does not consume the requested-window allowance.
Configuration files¶
Provider constructor configuration:
Pine input overrides:
strategy() header overrides use a separate file:
Input and override values sent to the FastAPI service must be scalar strings, numbers, or booleans.
The same harness accepts --provider csv, --provider sqlite, or
--provider sqlalchemy. Their provider configuration maps arbitrary source
columns to normalized OHLCV, while raw Pine and normalized bars follow the
same local-container or FastAPI path. See
the provider catalog for their individual API and configuration
guides.
Runtime image policy¶
The package default is an exact pineforge-release version and OCI digest. The
missing pull policy downloads it only when absent; never supports offline
runs; always refreshes a tag before running.
The rolling channel is explicit:
Use the pinned default for reproducible research. A rolling tag may change
engine or codegen behavior without a pineforge-data version change.
Report envelope¶
The harness combines provider provenance with the release report:
{
"schema_version": 1,
"request_id": null,
"provider": {
"name": "ccxt:kraken",
"adapter": "ccxt",
"venue": "kraken",
"source_timeframe": "15m",
"market": {
"symbol": "BTC/USD",
"provider_id": "XXBTZUSD",
"market_type": "spot",
"contract": null
}
},
"data": {
"requested_start_ms": 1751328000000,
"requested_end_ms": 1751932800000,
"provider_start_ms": 1746828000000,
"first_bar_ms": 1746828000000,
"last_bar_ms": 1751931900000,
"bars": 1172,
"requested_bars": 672,
"warmup_bars_requested": 500,
"warmup_bars_loaded": 500,
"trade_start_time_ms": 1751328000000
},
"runtime": {
"mode": "local-container",
"release_image": "ghcr.io/...@sha256:..."
},
"backtest": {
"summary": {},
"trades": [],
"metrics": {},
"equity_curve": [],
"fingerprint": {}
}
}
Remote responses include a request ID. Server runtime provenance also includes the generated C++ digest, compile-cache key/hit, and engine/codegen/release versions. Local runs record the resolved image digest and OCI component labels when Docker exposes them.
Reproducibility checklist¶
Retain:
- raw Pine source and strategy input/override files;
- provider adapter and venue;
- exact resolved symbol and provider market ID;
- requested interval and normalized OHLCV snapshot or checksum;
- release image reference and resolved digest;
- report fingerprint and request ID.
The pinned release currently does not expose trace collection. --trace fails
explicitly rather than producing an incomplete report.