README.md
July 6, 2026 · View on GitHub
Backtest and live — byte-identical, in 10 languages. A streaming-native, event-driven backtester built on the Wickra indicator core.
▶ Live demo: all 514 indicators over real Binance market data, computed live in your browser — live.wickra.org · zero backend, powered by
wickra-wasm.
Part of the Wickra ecosystem: the same data-driven core and ten-language binding surface also power wickra-exchange, wickra-backtest, 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.
Why it is different from vectorbt / backtrader:
- 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; off-the-shelf backtesters can't.
- 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
StrategySpecruns from Rust, Python, Node.js, WASM, C, C++, C#, Go, Java and R.
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.jsonand is printed bywkbt 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:
| Language | Binding | Quickstart |
|---|---|---|
| Rust | wickra-backtest crate | this README |
| Python | PyO3 / maturin | bindings/python |
| Node.js | napi-rs | bindings/node |
| WASM | wasm-bindgen | bindings/wasm |
| C / C++ | C ABI (cbindgen) | bindings/c |
| C# | P/Invoke | bindings/csharp |
| Go | cgo | bindings/go |
| Java | FFM / Panama | bindings/java |
| R | .Call | bindings/r |
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.
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++ | over the C ABI | 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
Docs at docs.wickra.org; the marketing site and in-browser demo at 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
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
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.
