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
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,39 @@ the same `LiveTradeProvider` contract later.
after an engine warmup. `start_sequence` is the last accepted sequence, so the
adapter emits `start_sequence + 1` next.

## Direct backtest harness

`pineforge-backtest` fetches confirmed OHLCV through a data provider, packs the
normalized bars into the PineForge C ABI, and calls a compiled strategy library
directly. It does not create an intermediate CSV.

```bash
pineforge-backtest \
--strategy /path/to/strategy.so \
--exchange kraken \
--symbol BTC/USD \
--timeframe 15m \
--start 2026-07-01T00:00:00Z \
--end 2026-07-08T00:00:00Z \
--output report.json \
--pretty
```

The JSON report contains data provenance, processed-bar counts, every closed
trade, all/long/short trade statistics, equity statistics, security-feed
diagnostics, optional trace values, and the complete equity curve. Unix
millisecond timestamps can be used instead of ISO-8601 values.

Use `--provider-config config.json` for CCXT constructor options and
`--strategy-params inputs.json` for Pine input overrides. The provider config
file may contain credentials, so keep it outside version control.

Provider implementations are organized by their strongest supported runtime.
The current Python bucket contains CCXT and the harness; native low-latency
providers will live in the C++ bucket. Both buckets must emit the same
normalized records, but an individual provider does not need implementations
in both languages.

## Development

```bash
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ classifiers = [
]
dependencies = []

[project.scripts]
pineforge-backtest = "pineforge_data.cli.backtest:main"

[project.optional-dependencies]
ccxt = ["ccxt>=4.5.64,<5"]
dev = [
Expand Down
9 changes: 9 additions & 0 deletions scripts/backtest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python3
"""Repository wrapper for the installed ``pineforge-backtest`` command."""

from __future__ import annotations

from pineforge_data.cli.backtest import main

if __name__ == "__main__":
raise SystemExit(main())
12 changes: 12 additions & 0 deletions src/pineforge_data/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
"""Provider-neutral market and macro data contracts for PineForge."""

from .backtest import (
BacktestOptions,
BacktestReport,
EngineBacktestError,
MagnifierDistribution,
PineForgeBacktestRunner,
)
from .engine import EngineStreamSink, PfBar, PfTradeTick, pack_bars, pack_trade_ticks
from .errors import EngineStreamError
from .models import Bar, Instrument, MacroObservation, TradeTick
Expand All @@ -16,13 +23,16 @@
from .requests import BarRequest, MacroRequest, TradeSubscription

__all__ = [
"BacktestOptions",
"BacktestReport",
"Bar",
"BarRequest",
"CcxtCapabilityError",
"CcxtDataError",
"CcxtDependencyError",
"CcxtError",
"CcxtProvider",
"EngineBacktestError",
"EngineStreamError",
"EngineStreamSink",
"HistoricalBarProvider",
Expand All @@ -31,8 +41,10 @@
"MacroDataProvider",
"MacroObservation",
"MacroRequest",
"MagnifierDistribution",
"PfBar",
"PfTradeTick",
"PineForgeBacktestRunner",
"TradeSubscription",
"TradeTick",
"pack_bars",
Expand Down
Loading