Skip to main content

Wickra Strategy-CI — golden-pin your strategy's backtest report, catch regressions in CI, and property-test against fuzzed data, in ten languages plus a reusable GitHub Action

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


Jest for trading strategies. Golden-pin your strategy's backtest report, catch regressions in CI, and property-test it against fuzzed market data — in ten languages, plus a reusable composite GitHub Action.

▶ Live demos: the backtester compiled to WebAssembly, an equity curve building bar by bar — backtest-live.wickra.org; one StrategySpec side by side in Python, Rust, JS and Go — playground.wickra.org; all 514 indicators of the core over a real Binance feed — live.wickra.org. Zero backend, all of them.

Part of the Wickra ecosystem. Strategy-CI is the test harness for the deterministic wickra-backtest engine: it runs a strategy through the engine, pins the resulting BacktestReport, and fails the build when the numbers drift.

# Run a directory of strategy tests against a directory of OHLCV data.
# Exits non-zero the moment a report drifts, so CI fails on it.
wickra-strategy-ci run tests/ --data data/

# Re-pin the goldens after a change you meant to make.
wickra-strategy-ci bless tests/ --data data/

Status

0.1.4 — the current release. The core, the CLI, all ten language bindings, the byte-exact golden corpus, property + fuzz tests, benchmarks and one runnable example per language are in place and green across the full CI matrix (10 languages × 3 OS). ROADMAP.md has what is done, what is open and what is not planned.

Documentation

See docs/ — TESTS.md for the test model, TOLERANCES.md for the golden diff, PROPERTIES.md for the invariants, FUZZING.md for the perturbations, GITHUB_ACTION.md for the action, and Cookbook.md for task-shaped recipes.

Why

A backtest is only trustworthy if it is reproducible. Wickra's engine is deterministic, so a strategy's report is a stable artifact you can pin — like a snapshot test. Strategy-CI turns that into a workflow:

  • Golden tests — pin a strategy's BacktestReport and fail when it changes beyond a tolerance you set — absolute or relative, per field, with exact equality as the default when you set none.
  • Property tests — assert invariants that must hold for any run: no field is NaN or infinite, drawdown stays inside a bound, the trade count clears a floor, Sharpe or PnL clears a threshold, a named field stays in range.
  • Fuzz tests — perturb the input data with a seeded PRNG and re-run, catching strategies that only work on one specific history.

Quickstart

Install the CLI, point it at a directory of test files and a directory of candle data, and pin the reports once:

cargo install wickra-strategy-ci-cli      # the crate; the binary is wickra-strategy-ci

wickra-strategy-ci list  golden/tests/                       # the test ids found under a path
wickra-strategy-ci bless golden/tests/ --data golden/data/   # pin every report (first run)
wickra-strategy-ci run   golden/tests/ --data golden/data/   # fail when a report moves

run exits non-zero when any pinned report drifts further than its tolerances allow, when a property check fails, or when a fuzzed re-run breaks — which is what makes it a CI gate. The next section is what a test file looks like.

A test is a file, not a function

There is no test API to learn. A test is JSON: which strategy, over which dataset, pinned to which report, under which tolerances.

{
  "id": "crossover",
  "dataset_ref": "sym-04",            // resolves to <data>/sym-04.csv
  "strategy": { /* opaque StrategySpec, forwarded to wickra-backtest */ },
  "expected": { /* the pinned BacktestReport — written by `bless` */ },
  "tolerances": {
    "*": { "kind": "rel", "value": 0.0001 },        // default for every field
    "metrics.sharpe": { "kind": "abs", "value": 0.01 }
  },
  "property_checks": [
    { "kind": "no_nan" },
    { "kind": "max_drawdown_le", "value": 1.0 }
  ],
  "fuzz": { "seed": 42, "runs": 8,
            "perturbation": { "kind": "jitter", "amount": 0.001 } }
}

Write the strategy, run bless once to pin the report, and commit the file. From then on run fails the build whenever the numbers move further than you allowed. Working examples live in golden/tests/.

wickra-strategy-ci list  tests/                 # the test ids found under a path
wickra-strategy-ci run   tests/ --data data/    # --format json for machine output
wickra-strategy-ci bless tests/ --data data/    # re-pin after an intended change

As a GitHub Action

Run your strategy tests on every push — a failing test fails the workflow:

- uses: wickra-lib/wickra-strategy-ci@v0.1.4
  with:
    tests: tests/
    data: data/

Pin the exact release. Pre-1.0 the moving major tag is @v0, and it floats across minor versions, which may break.

See docs/GITHUB_ACTION.md for the full inputs/outputs.

How it works

A StrategyTest is data, not code: a serde model carrying an opaque StrategySpec sub-JSON. Strategy-CI forwards that spec verbatim to wickra-backtest::run, takes the returned BacktestReport, and asserts it against the test's expectations and properties. Because the engine is deterministic and every binding forwards the core's response string unchanged, results are reproducible byte-for-byte across languages and between the parallel (rayon) and sequential (WASM) execution paths.

The diff works on numeric leaves. Both reports are flattened to a sorted map of numbers — metrics.sharpe, equity[3].equity — rounded to eight decimals and compared field by field, reporting mismatches, fields that vanished and fields that appeared. Strings, booleans and nulls are not pinned, so a report field that is text is outside what a golden can catch.

Use in any language

The core is exposed as a JSON-over-C-ABI data API in ten languages: Rust, Python, Node.js and WASM natively, plus C, C++, C#, Go, Java and R over the C ABI hub. A Session handle plus command(json) -> json and version is the whole surface; the same test JSON produces a byte-identical result in every binding.

cargo add wickra-strategy-ci-core      # Rust
pip install wickra-strategy-ci         # Python
npm install wickra-strategy-ci         # Node.js
dotnet add package Wickra.StrategyCi   # C#
go get github.com/wickra-lib/wickra-strategy-ci/bindings/go   # Go

Java ships to Maven Central (org.wickra:wickra-strategy-ci), R to r-universe (wickrastrategyci), and the C ABI ships as a per-platform library with a vendored header. See each binding's README.md under bindings/.

Project layout

crates/wickra-strategy-ci-core     the runner: model, tolerances, properties, fuzz, session
crates/wickra-strategy-ci-cli      the reference CLI (run / bless / list / version)
crates/strategy-ci-bench    criterion benchmarks
bindings/c                  the C ABI hub — every non-native binding goes through it
bindings/python             PyO3 native binding
bindings/node               napi-rs native binding
bindings/wasm               wasm-bindgen binding (sequential path)
bindings/{csharp,go,java,r} thin clients over the C ABI
golden/                     cross-language fixtures: tests, data, expected reports
examples/                   one runnable example per binding
fuzz/                       cargo-fuzz targets (its own detached workspace)
action.yml                  the composite GitHub Action

Building everything from source

cargo build --workspace --all-features        # core, CLI, bench, native bindings
cargo build -p wickra-strategy-ci-c --release # the C ABI library + header

( cd bindings/python && maturin develop --release )
( cd bindings/node   && npm ci && npm run build )
( cd bindings/wasm   && wasm-pack build --target web )
( cd bindings/java   && mvn -q package )
( cd bindings/csharp && dotnet build )

The C ABI library is the prerequisite for the C, C++, C#, Go, Java and R bindings: build it first, then point WKSTRATEGYCI_LIB and WKSTRATEGYCI_INC at the resulting library and bindings/c/include.

Testing

cargo test --workspace --all-features         # core, integration, C ABI
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo fmt --all --check

( cd bindings/python && pytest tests -q )
( cd bindings/node   && npm test )
( cd bindings/go     && go test ./... )

Every binding runs the same golden/ fixtures through its own command(json) -> json surface, so a passing suite is evidence that the languages agree byte-for-byte — not just that each one runs. The CLI is covered end-to-end against golden/tests in CI.

Requirements

To use You need
The CLI or the GitHub Action Nothing — the action installs a prebuilt binary, or builds from git as a fallback.
Rust 1.86 or newer (workspace MSRV).
Python 3.9 or newer.
Node.js 22 or newer.
Go 1.23 or newer.
Java 22 or newer.
R 4.1 or newer.
C / C++ / C# / R The C ABI library plus its vendored header; see each binding's README.md.

Building from source additionally needs a Rust toolchain; the polyglot bindings need their own toolchain (maturin, napi, wasm-pack, dotnet, go, Maven, R CMD) only for the binding you are building.

Benchmarks

A suite is cheap enough to gate every pull request. Median wall-clock for run_suite, parallel path, from the strategy-ci-bench criterion suite:

Dataset Tests Suite Per test
small (200 bars) 100 13.4 ms ~134 µs
small (200 bars) 1000 143 ms ~143 µs
large (2000 bars) 100 156 ms ~1.56 ms
large (2000 bars) 1000 1.24 s ~1.24 ms

Per-test cost is dominated by the engine walking the price history — roughly linear in bar count, near-flat in test count once the rayon pool is saturated. The golden diff and property checks are O(fields) on top. A fuzz axis multiplies a test's cost by its runs. Full method and caveats in BENCHMARKS.md; reproduce with cargo bench -p strategy-ci-bench.

Ecosystem

Strategy-CI is one repo in the Wickra family:

Repo What it does
wickra The indicator core — 514 streaming indicators, O(1) per tick, in ten languages.
wickra-backtest The deterministic engine whose BacktestReport this repo pins.
wickra-data Candle types and CSV/exchange loading.
wickra-proof Verifiable report hashes — a roadmap item for this repo.
wickra-synth Deterministic synthetic market data, useful as fuzz input.
wickra-exchange Live and historical exchange connectivity.

Contributing

See CONTRIBUTING.md and the Code of Conduct.

Security

Report vulnerabilities per 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

wickra-strategy-ci is research and engineering tooling, not financial advice. A passing test attests only that a strategy's backtest report matches its pinned expectation under the given data — it makes no claim about the quality, profitability or future performance of any strategy. Trading carries risk; you are responsible for your own decisions.


GitHub stars GitHub forks GitHub issues

Built on Wickra. If it saved you time, the cheapest way to say thanks is to ⭐ the repo.

wickra-strategy-ci star history

Metadata

Release files for wickra-strategy-ci 0.1.4

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-strategy-ci 0.1.4
File Size Uploaded
wickra_strategy_ci-0.1.4.tar.gz 57.3 kB Details

Built distributions (wheels)

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

Total release size: 6.8 MB

Release files / wickra_strategy_ci-0.1.4.tar.gz

Download URL wickra_strategy_ci-0.1.4.tar.gz
Size 57.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7e2ac202f0164adb7ed91a7cb1a858ea911922f29ad5cff61f6d05af3f6354dd
BLAKE2b-256 checksum
How to use checksums
1e8903e1924059c04df651621df5fac0df4c416d2a3f58f800ceb56a52492dcd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_strategy_ci-0.1.4-cp39-abi3-win_arm64.whl

Download URL wickra_strategy_ci-0.1.4-cp39-abi3-win_arm64.whl
Size 653.6 kB
Tags CPython 3.9 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
9621191e5474a31defc78c3a9f336028f7aecc70a72ed6d394bea753d70624b2
BLAKE2b-256 checksum
How to use checksums
e788e9f89cb9597bc590ef0ec4ec5475caf561a0d807557416c36a8b1a76aebe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_strategy_ci-0.1.4-cp39-abi3-win_amd64.whl

Download URL wickra_strategy_ci-0.1.4-cp39-abi3-win_amd64.whl
Size 742.1 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
ef79956fc78df1d6d7b75af96f615ff57af7e71335f3c025125a7f9a0a389796
BLAKE2b-256 checksum
How to use checksums
6f9ac37c9f15a6d17cc2cebc872fabae2d1f71b6bed6d3e055f126f029699e03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_strategy_ci-0.1.4-cp39-abi3-musllinux_1_2_x86_64.whl

Download URL wickra_strategy_ci-0.1.4-cp39-abi3-musllinux_1_2_x86_64.whl
Size 1.1 MB
Tags CPython 3.9 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
ae7d1d7753c97d7dac4210ee57cc9bc3f8ddef62dab2b8a3f5fd5183e145bba1
BLAKE2b-256 checksum
How to use checksums
477064775acb53a680467c3f875b90b5b1e29a6d2f96e75279bbfd97d50bb8cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_strategy_ci-0.1.4-cp39-abi3-musllinux_1_2_aarch64.whl

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

Release files / wickra_strategy_ci-0.1.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

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

Release files / wickra_strategy_ci-0.1.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL wickra_strategy_ci-0.1.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 793.3 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
8087f8a41663fa9d6e64f9343fd800c225d958eb428e8fc7f8cbbcf37ba47a8b
BLAKE2b-256 checksum
How to use checksums
ca9e2ebbc411c56367e72b31b440547d9042fdfed2ac86701ebcf45b344871a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_strategy_ci-0.1.4-cp39-abi3-macosx_11_0_arm64.whl

Download URL wickra_strategy_ci-0.1.4-cp39-abi3-macosx_11_0_arm64.whl
Size 720.8 kB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
e212bd1f5f6e2328890936d2f6e017b700a1d73c8a46f3a36ce4eb517d86c9d3
BLAKE2b-256 checksum
How to use checksums
7a77b9b2712cdb542b6f51ed3303b3aca537240948d860964d63bac1f4bcee0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / wickra_strategy_ci-0.1.4-cp39-abi3-macosx_10_12_x86_64.whl

Download URL wickra_strategy_ci-0.1.4-cp39-abi3-macosx_10_12_x86_64.whl
Size 834.2 kB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
b0ab1431ce6142c338404107ba4d124ba86489be5db98d93f3d2269d1f2d25fb
BLAKE2b-256 checksum
How to use checksums
9c0d765301e41b8372c5884db3b4c7291e84b8e5efd639b76fb3188255286340
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release history Release notifications | RSS feed

0.2.0

9 release files

0.1.6

9 release files

0.1.5

9 release files

This release

0.1.4 This release

9 release files

0.1.3

9 release files

0.1.2

9 release files

0.1.1

9 release files

0.1.0

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