Skip to main content

Wickra Backtest — backtest and live are byte-identical

Built on Wickra Status CI CodeQL codecov GitHub release crates.io PyPI npm NuGet Maven Central Go module R-universe License: MIT OR Apache-2.0 OpenSSF Scorecard OpenSSF Best Practices Build provenance Docs Verified across 10 languages Live demo


Backtest and live — byte-identical, in 10 languages. A streaming-native, event-driven backtester built on the Wickra indicator core.

▶ Live demo: run a strategy in your browser and watch the equity curve build bar by bar — backtest-live.wickra.org · zero backend, the same engine this repository ships, compiled to WebAssembly.

Part of the Wickra ecosystem: the same data-driven core and ten-language binding surface also power wickra-exchange, wickra-terminal, wickra-screener, wickra-xray, wickra-radar, wickra-copilot and wickra-shazam.

The engine consumes the exact same wickra-core O(1) indicator kernels that power live Wickra, and a strategy is data (a JSON spec), not code — so a backtest and a live run over the same spec produce identical signals, across every Wickra language binding. The same engine, fed live instead of historical bars, becomes the live bot: backtest ≡ live, by construction.

The strategy spec can reference 495 wickra-core indicators by name — every backtestable scalar, candle, multi-output, pairwise, derivatives, order-book, trade, trade-quote and cross-section indicator, with multi-output fields addressed as "name.field" (macd.signal, bb.upper, adx.plus_di, …). The registry is generated directly from the wickra-core sources, so it stays in lock-step with the kernel.

pip install wickra-backtest
import wickra_backtest as wbt

spec = {                                  # a strategy is data, not code
    "symbol": "BTCUSDT", "timeframe": "1h",
    "indicators": {"fast": {"type": "Ema", "params": [12]},
                   "slow": {"type": "Ema", "params": [26]}},
    "entry": {"cross_above": ["fast", "slow"]},
    "exit":  {"cross_below": ["fast", "slow"]},
    "sizing": {"type": "fixed_fraction", "fraction": 0.95},
}

# Backtest: the whole series at once.
report = wbt.run(opens, highs, lows, closes, spec=spec)
print(report["metrics"]["return_pct"], report["metrics"]["sharpe"])

# Live: the same spec, the same engine, one bar at a time. Point `step` at a
# socket instead of an array and nothing else changes.
with wbt.StreamingBacktest(spec=spec) as live:
    for bar in feed:
        live.step(bar.open, bar.high, bar.low, bar.close)
        print(live.num_trades, live.latest_equity())
    report = live.finish()

The two reports are byte-identical. That is the whole claim, and a shared golden corpus holds every one of the ten bindings to it.

What it does differently:

  • O(1) per tick — years of tick data in seconds, not hours (no recompute-on-every-tick).
  • Backtest = live, value-identical across 10 languages — no reimplementation drift, pinned by a shared golden corpus for the OHLCV path and every microstructure feed.
  • Microstructure backtesting — replay the order book, trades, perpetual funding and open interest as strategy inputs, not just OHLCV. Most Python backtesters have no place to put them.
  • Realistic execution — long/short, market/limit/stop orders, leverage and position caps, five sizing models, intrabar stop-loss / take-profit / trailing stops, maker/taker fees, three slippage models, perpetual funding, liquidation and execution latency.
  • Polyglot — the same StrategySpec runs from Rust, Python, Node.js, WASM, C, C++, C#, Go, Java and R.
Backtester Languages Engine Strategy is Book / funding inputs Latest release
★ wickra-backtest Rust · Python · Node.js · WASM · C · C++ · C# · Go · Java · R event-driven, O(1)/bar data (a JSON spec) yes unreleased
nautilus_trader Rust · Python event-driven code yes 2026-08
vectorbt Python vectorised code — 2026-07
backtesting.py Python vectorised code — 2026-07
zipline-reloaded Python event-driven code — 2025-07
backtrader Python event-driven code — 2023-04

Release dates are the latest published version on PyPI, checked when this table was written; "—" means the feed is not a first-class strategy input, not that the library is bad at what it does. nautilus_trader is the closest comparison and is ahead of this project in places — it is a full trading platform with live venue adapters, and it has shipped for years. The distinction here is narrower and worth stating plainly: a strategy is data rather than code, so the same spec runs unchanged from ten languages and a shared golden corpus pins every one of them to the same report, byte for byte. No other engine in this table offers that because none of them needs to.

Status

Alpha / work in progress. The engine, the data-driven StrategySpec, the full execution and cost model, the microstructure feeds and all ten language bindings are implemented and tested; a shared golden corpus pins the cross-language equality byte-for-byte. Not yet released to any registry.

Documentation

  • Strategy spec reference — the full DSL: operands, conditions, sizing, costs, slippage, risk, execution and the report shape.
  • Cookbook — six ready-to-run strategies (RSI mean reversion, MACD trend, Bollinger breakout, Donchian breakout, funding carry, order-book imbalance), each validated against the engine.
  • Microstructure guide — backtesting on the order book, trades, perpetual funding and market breadth (the differentiator).
  • Architecture — crates, data flow and design decisions.
  • Benchmarks — throughput methodology and caveats.
  • Examples — runnable specs and a sample dataset.
  • The JSON Schema for the spec is at schema/strategy_spec.schema.json and is printed by wkbt schema.

Quickstart

A strategy is data — a JSON spec. Run one over a candle file with the wkbt CLI:

cargo run --bin wkbt -- run --data examples/sample.csv --spec examples/ema-cross.json
bars       80
trades     4
return     -2.68%
pnl        -268.21
sharpe     -0.186
max dd     2.68%
win rate   0.0%
fees       37.50

A spec declares named indicators and entry/exit rules over them:

{
  "symbol": "BTCUSDT", "timeframe": "1h",
  "indicators": { "ema_fast": { "type": "Ema", "params": [5] },
                  "ema_slow": { "type": "Ema", "params": [15] } },
  "entry": { "cross_above": ["ema_fast", "ema_slow"] },
  "exit":  { "cross_below": ["ema_fast", "ema_slow"] },
  "sizing": { "type": "fixed_fraction", "fraction": 0.95 },
  "risk": { "trailing_stop_pct": 5.0 }
}

See the cookbook and examples/ for complete strategies, and the spec reference for the full grammar.

From Rust, the same thing is wickra_backtest::run(&spec, &candles). For live use, StreamingBacktest::new(&spec, capital) then step(candle) per bar feeds the same engine one bar at a time — backtest and live are one code path. A single run_json request bundles candles, the spec and any feeds, and is the uniform entry point every binding wraps.

Run the same spec in any language

Every binding takes the same OHLCV arrays (or a run_json request) and JSON spec and returns the same report — byte-identical (a dict in Python). Each has a quickstart:

Binding Install Example
Rust cargo add wickra-backtest examples/rust
Python (PyO3) pip install wickra-backtest examples/python/backtest.py
Node.js (napi-rs) npm install wickra-backtest examples/node/backtest.js
Browser / WASM npm install wickra-backtest-wasm examples/wasm/backtest.cjs
C / C++ (C ABI) header + library, see bindings/c examples/c/streaming.c · cpp_smoke.cpp
C# (C ABI) dotnet add package Wickra.Backtest, see bindings/csharp examples/csharp
Go (cgo, C ABI) go get github.com/wickra-lib/wickra-backtest-go, see bindings/go examples/go
Java (FFM, C ABI) Maven Central org.wickra:wickra-backtest, see bindings/java examples/java
R (.Call, C ABI) R CMD INSTALL bindings/r, see bindings/r examples/r/backtest.R

Every example does the same thing in its own language: read the shared sample data, run the series both ways, and fail if the two reports differ. examples/README.md is the cross-language index.

The C, C++, C#, Go, Java and R bindings all call through the same C ABI hub; the golden corpus asserts every language produces the same report, for both the plain OHLCV path and the order-book / trade / derivatives / cross-section feed paths.

Performance

O(1) per bar — about 1.7M bars/second on one core (a year of 1-minute bars in ~0.3 s). See BENCHMARKS.md for the methodology and caveats.

Project layout

wickra-backtest/
├── crates/
│   ├── wickra-backtest-core/   engine: spec DSL, registry, rules, execution, portfolio, metrics, report
│   ├── wickra-backtest-data/   loaders (CSV / JSON / JSONL / Parquet) + resampling + Renko/Kagi/PnF
│   ├── wickra-backtest/        facade crate (re-exports the engine + runners)
│   ├── wickra-backtest-cli/    the `wkbt` command-line backtester
│   └── wickra-backtest-bench/  criterion throughput benchmarks
├── bindings/
│   ├── python/   PyO3 + maturin          ├── csharp/  P/Invoke over the C ABI
│   ├── node/     napi-rs                 ├── go/      cgo over the C ABI
│   ├── wasm/     wasm-bindgen            ├── java/    FFM over the C ABI
│   ├── c/        C ABI (cdylib/staticlib + generated header)
│   └── r/        .Call over the C ABI
├── golden/       shared cross-language parity corpus (cases + feed requests)
├── schema/       generated JSON Schema for the strategy spec
├── examples/     runnable strategies + a sample dataset
├── docs/         strategy spec reference + cookbook
└── fuzz/         cargo-fuzz targets (nightly)

Building from source

# Rust core + tests + lints
cargo test --workspace --all-features
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo bench -p wickra-backtest-bench

# Python binding (requires a Rust toolchain + maturin)
cd bindings/python && maturin develop --release && pytest

# Node binding (requires @napi-rs/cli)
cd bindings/node && npm install && npm run build && npm test

# WASM binding (requires wasm-pack)
cd bindings/wasm && wasm-pack build --target nodejs --out-dir pkg && node --test tests/

# C ABI (cdylib + staticlib + generated header)
cargo build -p wickra-backtest-c --release

# C# binding (requires the .NET 8 SDK; links the C ABI above)
dotnet test bindings/csharp/Wickra.Backtest.Tests/Wickra.Backtest.Tests.csproj

# Go binding (requires a C compiler for cgo; links the C ABI above)
cd bindings/go && go test ./...

# Java binding (requires JDK 22+ and Maven; links the C ABI above)
mvn -f bindings/java test

# R binding (requires a C toolchain / Rtools; links the C ABI above)
WKBT_INC="$PWD/bindings/c/include" WKBT_LIB="$PWD/target/debug" R CMD INSTALL bindings/r

The Go, Java and R bindings load the C ABI shared library at run time; put target/debug (or target/release) on the library path. Fuzzing requires a nightly toolchain — see fuzz/; the same never-panic invariants are covered on stable by the property tests.

Testing

Every layer is covered; the commands are in Building from source.

  • wickra-backtest-core — 113 unit tests: hand-computed round trips (entry at the next open, exit on the signal after it), every sizing model, the cost and slippage models, intrabar stops and liquidation, funding, the rule evaluator, bounded history, and the feed requirements a spec declares. Plus five integration suites: property tests, the shipped example specs, and the three golden runners (batch, streaming, and the microstructure requests).
  • wickra-backtest-data — 17 unit tests over CSV, JSONL, JSON-array and Binance kline decoding, plus the resamplers.
  • bindings/c — 12 Rust tests driving the ABI itself, including the streaming handle's lifecycle and every error path, so a null or finished handle is proven to be reported rather than dereferenced.
  • bindings/python — 21 pytest cases: smoke, streaming, golden parity, completeness of the module and class surface, and the feed path.
  • bindings/node — 19 node --test cases, same shape.
  • bindings/wasm — 8 node --test cases against the built package.
  • bindings/csharp — 15 xUnit cases. bindings/java — 15 JUnit cases. bindings/go — 15 go test cases. bindings/r — 3 script suites.
  • fuzz/ — five targets covering the whole untrusted-input surface: the spec parser, the JSON request, the engine loop, the fill model and the data loader.

On top of those, all ten languages replay a shared, language-neutral golden corpus — four OHLCV cases and five microstructure requests in golden/ — and assert equality with the Rust reference report. Since the streaming work, each also replays the corpus one bar at a time and asserts the same report, so the claim that a backtest and a live loop agree is pinned per language rather than argued.

What "parity" means here, precisely. The reports are compared byte for byte, not to a tolerance. That is possible because every binding calls the same Rust engine — the arithmetic is not reimplemented anywhere — and because the indicators the corpus names use only IEEE-754 arithmetic, which every conforming platform rounds identically. It is not free, though: a spec can name any indicator in the core, and some of those call a transcendental from the platform's math library (ln, atan, exp and friends). No mainstream libm rounds those correctly, and implementations differ in the last bit — the sibling indicator library measured a one-ulp difference on 24 of 67 bars for a single indicator. A golden case built on one of those would have to compare to a relative tolerance instead. None currently does, and that is a property of the corpus worth keeping deliberately rather than by accident.

Requirements

The minimum supported version per language. The same engine kernel runs behind every binding; the C-ABI bindings that compile on install — Go (cgo) and R (.Call) — also need a C compiler, and Java runs with --enable-native-access=ALL-UNNAMED.

Language Package Minimum supported
Rust crates.io · wickra-backtest 1.86 (MSRV)
Python PyPI · wickra-backtest (abi3 wheel) 3.9 (tested through 3.13)
Node.js npm · wickra-backtest (N-API 8) 22 (tested on 22 · 24 LTS)
WASM npm · wickra-backtest-wasm any modern JS engine
C wickra_backtest.h + library (releases) C99 compiler
C++ the C ABI + optional wickra_backtest.hpp C++14 compiler
C# NuGet · Wickra.Backtest .NET 8 (net8.0)
Go module · wickra-lib/wickra-backtest-go Go 1.23 (cgo)
Java Maven Central · org.wickra:wickra-backtest Java 22 (FFM / Panama)
R r-universe · wickrabacktest R ≥ 2.10 (Rtools on Win.)

Ecosystem

Part of the Wickra family — each one a data-driven core with a CLI and the same ten-language binding surface:

  • wickra — the core library: 514 O(1) streaming indicators across ten languages
  • wickra-exchange — unified market-data + execution across ten crypto exchanges
  • wickra-backtest — event-driven backtester over the Wickra core
  • wickra-terminal — the trading terminal: a TUI and a browser renderer over the stack
  • wickra-screener — parallel multi-symbol screening over 514 streaming indicators
  • wickra-xray — market-microstructure explorer: footprint, order-book heatmap, liquidation map, funding/OI divergence
  • wickra-radar — perp-universe alert radar: OI delta, funding flip, book imbalance, liquidation clusters, OI/price divergence
  • wickra-copilot — local market copilot grounded in real order-book, liquidation and funding microstructure
  • wickra-shazam — match an asset's current microstructure fingerprint against its entire history

This project's own site is backtest.wickra.org and its in-browser demo backtest-live.wickra.org. The indicator core it is built on documents itself at docs.wickra.org.

Contributing

Contributions are welcome — issues, bug reports, ideas and pull requests all land at https://github.com/wickra-lib/wickra-backtest. See CONTRIBUTING.md for the orientation: the engine lives in crates/wickra-backtest-core, every binding under bindings/<lang> keeps the golden-corpus parity invariant, and cargo fmt --all + cargo clippy --workspace --all-targets --all-features -- -D warnings are CI gates. For larger changes, open an issue first.

Security

Found a security issue? Please don't open a public issue. Report it privately via the repository's Security tab ("Report a vulnerability") or email support@wickra.org. Full policy: SECURITY.md.

License

Licensed under either of

at your option. Use it, fork it, modify it, redistribute it — commercially or not — file issues, send pull requests; all welcome.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Disclaimer

Not a trading system. Backtest results are deterministic transforms of the input data — they are not financial advice and are not indicative of future performance. Any use in a live trading context is at your own risk. The software is provided as is, without warranty of any kind; see the license files for the full terms.


Built on Wickra. If it saved you time, ⭐ the repo.

Metadata

Release files for wickra-backtest 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wickra-backtest 0.1.0
File Size Uploaded
wickra_backtest-0.1.0.tar.gz 143.2 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for wickra-backtest 0.1.0
File
wickra_backtest-0.1.0-cp39-abi3-win_arm64.whl CPython 3.9 abi3 Windows ARM64 Details
wickra_backtest-0.1.0-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
wickra_backtest-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl CPython 3.9 abi3 Linux musl 1.2+ x86-64 Details
wickra_backtest-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl CPython 3.9 abi3 Linux musl 1.2+ ARM64 Details
wickra_backtest-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
wickra_backtest-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
wickra_backtest-0.1.0-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
wickra_backtest-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details

Total release size: 6.3 MB

Release files / wickra_backtest-0.1.0.tar.gz

Download URL wickra_backtest-0.1.0.tar.gz
Size 143.2 kB
Tags Source
SHA-256 checksum
How to use checksums
89fae28a8cde59012d1c985e90b458e290fbc2a51b612e7a1fba6ada763e4995
BLAKE2b-256 checksum
How to use checksums
d729c751db5eb26cbe0e77e8ce8ae3c18ddb60a739b26bc3c1d71a370b80cd2f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_backtest-0.1.0-cp39-abi3-win_arm64.whl

Download URL wickra_backtest-0.1.0-cp39-abi3-win_arm64.whl
Size 627.5 kB
Tags CPython 3.9 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
950360f81dae54f0524989c1266d60405c54e284c03170d61288e6468988d5c7
BLAKE2b-256 checksum
How to use checksums
27b8a6c7ce57e943b290f74c0109ae12f71d095ccd67b78a7cab0ee83c4cd06e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_backtest-0.1.0-cp39-abi3-win_amd64.whl

Download URL wickra_backtest-0.1.0-cp39-abi3-win_amd64.whl
Size 702.7 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
ddd83f6a6926b05a3e0bf9fb84694ed4456fbfec18f3cacef1ebdbcfe4588a9b
BLAKE2b-256 checksum
How to use checksums
a74e54befbbaa1fad5ed489d0b06bc7c84a9ac96342b414ac6378c799445bc1c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_backtest-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl

Download URL wickra_backtest-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl
Size 1.0 MB
Tags CPython 3.9 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
0153f9d06beb3381ab2b7d68f7e20a2f999e585aa674a7f5dc104b951110d3a7
BLAKE2b-256 checksum
How to use checksums
5fca8c024ec9cff5d514bdf8e2228999b833586365cb1955b28e65562985c1ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_backtest-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl

Download URL wickra_backtest-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl
Size 902.9 kB
Tags CPython 3.9 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
e316a516943cd625aad298a246dff321fa4126c88251272028cc5d579f3c859f
BLAKE2b-256 checksum
How to use checksums
e0174a559e6189c75f51cd88081e8255de8015d9524011ac6b04891bef865864
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_backtest-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL wickra_backtest-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 790.6 kB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
ca9735070866725b10e3e34e6daa16f57d1701c33f034f3f41992e9c13b6d85a
BLAKE2b-256 checksum
How to use checksums
4e58cc408f10c27ec4fbff7843e6e14b22478650dd54c60bc0e06321bcb13384
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_backtest-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL wickra_backtest-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 723.0 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
5194bd10f616c67bea780e412ed6f42ff735de9c02c5d86bbe09a210134e3fe4
BLAKE2b-256 checksum
How to use checksums
47faa35c9ee7311c5b2360215a2a08acaef0b925ae12909f530787acd2ffcd64
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_backtest-0.1.0-cp39-abi3-macosx_11_0_arm64.whl

Download URL wickra_backtest-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
Size 699.0 kB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0a87968b2757f106b67c302b85d68d73bd3df7a86e6acc973b55f549a829cfcc
BLAKE2b-256 checksum
How to use checksums
a690d14c28f91d934b3600d334c8b702c19623786b6b70b8da9ddd5b6556fffd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_backtest-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl

Download URL wickra_backtest-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl
Size 753.3 kB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
8b2e5c9d5c41c7a90e8c9e5e8d79e79040b7bd274f4f0a7dbfcd3799d324c107
BLAKE2b-256 checksum
How to use checksums
84462be73570ef0868dbfc2a6cf63c22293739100c3322bf17c02e84a82ddd61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release history Release notifications | RSS feed

0.1.9

9 release files

0.1.8

9 release files

0.1.7

9 release files

0.1.6

9 release files

0.1.5

9 release files

0.1.4

9 release files

0.1.3

9 release files

0.1.2

9 release files

0.1.1

9 release files

This release

0.1.0 This release

9 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page