Market Wave is a seeded, in-memory continuous double auction driven by an adaptive ensemble of N predictive distributions. Orders arrive in continuous time, walk a live limit-order book, and match with price-time priority. Prices, spreads, and liquidity emerge only from those orders and executions—never from a latent price path or a post-generation correction.
The model represents aggregate market intent, not named traders. It is built for market-microstructure experiments and synthetic scenario generation, not for forecasting or calibrating a particular venue.
One 300-second run (seed 7, N=64). Top: step-end best quotes and matched trades at their event times. Bottom: step-end resting quantity by side-relative rank; absolute price never enters the depth axis.
Install
Market Wave requires CPython 3.10 or newer. Published wheels contain the Rust simulation engine; source installations require a Rust 1.83+ toolchain.
pip install market-wave
The renderer is optional, so simulation-only installs do not pull in Matplotlib:
pip install "market-wave[visualization]"
Quick start
Every configuration field is explicit. With the same Market Wave wheel target,
a fresh Market with the same configuration and seed produces exactly the same
sequence. Version 2.1 intentionally starts a new seeded sequence and is not
trace-compatible with 2.0.
from market_wave import Market, MarketConfig, Trade
market = Market(
MarketConfig(
initial_price=100_000,
tick_size=1,
step_seconds=1.0,
order_rate=20.0,
mean_price_offset_ticks=4.0,
mean_order_size_lots=3.0,
mean_order_lifetime_seconds=5.0,
flow_component_count=64,
seed=7,
)
)
steps = tuple(market.stream(count=300))
last = steps[-1]
trade_count = sum(
isinstance(event, Trade)
for step in steps
for event in step.events
)
print("best bid:", last.book.best_bid)
print("best ask:", last.book.best_ask)
print("trades:", trade_count)
For eager native batching, market.step(n) advances n consecutive feedback
intervals in one extension call. step() and step(1) return one Step,
step(0) returns (), and values above one return tuple[Step, ...].
flow_component_count=64 is an ensemble-resolution choice, not a calibrated
market constant. Larger values sample the unit retention interval more densely
and closer to both endpoints, at greater ensemble cost; values down to one are
valid.
Visualize depth
Pass an already-produced, finite sequence of consecutive steps to the pure renderer:
from market_wave import render_depth_heatmap
path = render_depth_heatmap(
steps,
"artifacts/depth.png",
level_count=12,
title="Reference run · symmetric level ladder",
)
print(path)
The visualization contract is deliberately narrow:
- x-axis: simulation time, with one step-end book snapshot per column;
- y-axis: side-relative book rank, independent of absolute price;
- row order:
Ask L{N} ... Ask L1 | Bid L1 ... Bid L{N}from top to bottom; - color: a shared
log(1 + resting quantity)scale; - input: a non-empty
Sequence[Step]with consecutive indices and contiguous times; - output: a PNG file; missing parent directories are created and the resolved
Pathis returned.
Rendering never advances or mutates the market. A larger six-scenario comparison shows how activity, lifetime, placement width, seed, and N change the visible market.
How the engine works
N adaptive predictive laws in the Rust engine
│
├── combine side probabilities and price PMFs
├── combine quantity distributions
└── combine lifetime distributions
│
▼
sample each exact marginal by conditional factorization
│
▼
submit → match → rest → expire
│
▼
completed Step feedback returns to every law
1. N memory scales, one completed observation
Every predictive law observes the same completed step. Law i retains a
different fraction of its prior evidence:
rho_i = (i + 0.5) / N
rho_i is the evidence retained at each update, so larger values mean longer
memory. The evenly spaced spectrum supplies multiple time scales without a
hand-tuned decay schedule. Each law tracks order intensity, side probability,
relative-price scale, order-size scale, and cancellation hazard.
2. Preserve the aggregate marginal, then sample directly
The engine combines all N laws into side-conditional aggregate distributions. For each price, quantity, and lifetime marginal it chooses an ephemeral conditional component and samples the corresponding truncated law directly. Those choices are independent, are never stored on an order, and never select which predictive law receives feedback. Price offsets use discrete-Laplace probability mass functions (PMFs), quantities use geometric components, and resting lifetimes use exponential components. Their support is unbounded except for the positive-price boundary.
3. Let visible liquidity reshape flow
When both book sides provide a support-preserving solution, the engine divides each price PMF into marketable, spread-improving, and neutral regions. It then applies the minimum-KL reweighting that balances predicted buy and sell quote impact while preserving the conditional shape inside each region. If such a projection is infeasible, the unconditioned aggregate distributions are used.
Likelihood-ratio correction keeps the resulting liquidity constraint from teaching the base price law its own selection bias. This feedback changes order flow; it never moves a price directly.
4. Match before learning
Crossing orders consume resting liquidity at maker prices under strict price-time priority. Only an unfilled remainder rests. Expiration clocks begin when orders rest, and fully filled orders cannot emit later cancellation events. The resulting submissions, sides, offsets, sizes, expirations, and live-order exposure feed every predictive law exactly once at the end of the half-open step.
Public contract
All MarketConfig fields are required:
| Field | Contract |
|---|---|
initial_price |
positive integer and an exact multiple of tick_size |
tick_size |
positive integer |
step_seconds |
finite seconds greater than zero |
order_rate |
finite expected orders/second, at least zero |
mean_price_offset_ticks |
finite mean absolute offset in ticks, at least zero |
mean_order_size_lots |
finite mean quantity in lots, at least one |
mean_order_lifetime_seconds |
finite mean resting lifetime greater than zero |
flow_component_count |
positive integer N |
seed |
integer |
The constructor rejects non-finite or numerically unrepresentable values. Prices and quantities remain exact Python integers.
The top-level API is intentionally small:
| Surface | Contract |
|---|---|
Market.step(n=1) |
eagerly advances n intervals; returns one Step for n=1, otherwise a tuple |
Market.stream(count) |
lazily advances the same market; count=None is unbounded |
Step.events |
chronological Submission, Trade, and Cancellation values in [start_time, end_time) |
Step.book |
immutable step-end BookSnapshot with ranked Level values |
Market.book |
current immutable book snapshot |
Market.buy_distribution, sell_distribution |
current aggregate price laws |
EntryDistribution.probability(), .cdf() |
exact public aggregate price PMF and CDF |
render_depth_heatmap() |
optional, non-mutating PNG renderer |
Calling step() or consuming stream() mutates only the market's forward
simulation state. Returned steps and snapshots do not retain a back-reference
to mutable engine state.
Quantitative checks
The test suite covers matching invariants, event lifecycles, exact seeded reproducibility, direct conditional marginal sampling, numerical boundaries, native batching, independent threaded markets, feedback, and visualization semantics. A separate fixed regression run is also compared with 256 permuted, Poisson, or Gaussian null samples: sign persistence, activity persistence, one-step absolute-return persistence, event-count dispersion, and return kurtosis must each exceed the 99th percentile of the relevant null. Its 10-step variance ratio must remain inside the central 98% of the permuted-return null.
The repository includes a reproducible native-engine benchmark:
python benchmarks/benchmark_market.py
On the 2.1.0 release validation host (Linux x86-64, CPython 3.14), the default
flow_component_count=64 workload measured 4.04 ms/step after warm-up, or
247.6 steps/s. This is a workload and machine measurement rather than a runtime
guarantee; use the script to compare builds on the target deployment host.
Scope
Market Wave is an in-memory CPython package backed by a Rust engine. It intentionally provides no CLI, persistence layer, replay engine, hidden calibration state, named-agent model, or financial forecast. The engine retains only bounded predictive state and the live order book; callers choose which yielded results to keep.
Released under the MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file market_wave-2.1.0.tar.gz.
File metadata
- Download URL: market_wave-2.1.0.tar.gz
- Upload date:
- Size: 39.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c789a87c6b9fc9764fed2c0a8459008c33ceb682f170fefeb71d0e78d9705d8
|
|
| MD5 |
abb4a677b4d66c903d44d0eb75fbbdaa
|
|
| BLAKE2b-256 |
53e1a2b4ec0f169ed2bc92d4b3328852c4a31d269626aabea6cb88db61f46b14
|
Provenance
The following attestation bundles were made for market_wave-2.1.0.tar.gz:
Publisher:
workflow.yml on smturtle2/market-wave
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
market_wave-2.1.0.tar.gz -
Subject digest:
1c789a87c6b9fc9764fed2c0a8459008c33ceb682f170fefeb71d0e78d9705d8 - Sigstore transparency entry: 2153971386
- Sigstore integration time:
-
Permalink:
smturtle2/market-wave@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/smturtle2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file market_wave-2.1.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: market_wave-2.1.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 260.0 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97fae92dcf1d239807ab5dd3739ddc84916c6abb4fbdffb30f471e5a2866fb2c
|
|
| MD5 |
7e0f15f11b528867bca7b81459076ffa
|
|
| BLAKE2b-256 |
0f15c02514f8966e1eebd86b6edde0736ebd21aca7675407f6e1ac4db04bfe85
|
Provenance
The following attestation bundles were made for market_wave-2.1.0-cp310-abi3-win_amd64.whl:
Publisher:
workflow.yml on smturtle2/market-wave
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
market_wave-2.1.0-cp310-abi3-win_amd64.whl -
Subject digest:
97fae92dcf1d239807ab5dd3739ddc84916c6abb4fbdffb30f471e5a2866fb2c - Sigstore transparency entry: 2153971778
- Sigstore integration time:
-
Permalink:
smturtle2/market-wave@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/smturtle2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file market_wave-2.1.0-cp310-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: market_wave-2.1.0-cp310-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 563.5 kB
- Tags: CPython 3.10+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44d9b1d9ec4b5a320017c0b93f458601f487e7bb0822bac3a9e9ec64475dd01b
|
|
| MD5 |
c992f715a79cdebfed579f0953f93211
|
|
| BLAKE2b-256 |
3983008fffab1878cca2d5995fcfc79851da08468b770327968e484aa2579026
|
Provenance
The following attestation bundles were made for market_wave-2.1.0-cp310-abi3-musllinux_1_2_x86_64.whl:
Publisher:
workflow.yml on smturtle2/market-wave
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
market_wave-2.1.0-cp310-abi3-musllinux_1_2_x86_64.whl -
Subject digest:
44d9b1d9ec4b5a320017c0b93f458601f487e7bb0822bac3a9e9ec64475dd01b - Sigstore transparency entry: 2153972938
- Sigstore integration time:
-
Permalink:
smturtle2/market-wave@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/smturtle2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file market_wave-2.1.0-cp310-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: market_wave-2.1.0-cp310-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 508.5 kB
- Tags: CPython 3.10+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f245653d8879d6ef1c00aa5a9d0e313522d7d1178f56f1eade530b84ea2922a0
|
|
| MD5 |
ad877ecfaa80abe67526091413253a05
|
|
| BLAKE2b-256 |
ec9645e0d6f4808b66cd95e47ff5bf0b1e2b2f13b5be4850e5db6e9deab0daac
|
Provenance
The following attestation bundles were made for market_wave-2.1.0-cp310-abi3-musllinux_1_2_aarch64.whl:
Publisher:
workflow.yml on smturtle2/market-wave
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
market_wave-2.1.0-cp310-abi3-musllinux_1_2_aarch64.whl -
Subject digest:
f245653d8879d6ef1c00aa5a9d0e313522d7d1178f56f1eade530b84ea2922a0 - Sigstore transparency entry: 2153973143
- Sigstore integration time:
-
Permalink:
smturtle2/market-wave@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/smturtle2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file market_wave-2.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: market_wave-2.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 357.7 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59f9ec403c4e894a5c27cd699b65d683bf23689fee15f9c00ec081b229bd08bd
|
|
| MD5 |
3a946a15b16fba8fb41a430b9b172b27
|
|
| BLAKE2b-256 |
41bab91ad62c9a7060b7a7d2aabffdad3402a3aefe559ad2d34bda35f0f2e4eb
|
Provenance
The following attestation bundles were made for market_wave-2.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
workflow.yml on smturtle2/market-wave
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
market_wave-2.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
59f9ec403c4e894a5c27cd699b65d683bf23689fee15f9c00ec081b229bd08bd - Sigstore transparency entry: 2153972696
- Sigstore integration time:
-
Permalink:
smturtle2/market-wave@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/smturtle2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file market_wave-2.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: market_wave-2.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 332.8 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3eb7f535c604875813d94e3a244757a72118c75c90e7871b6dc152ce27c99836
|
|
| MD5 |
51f2285314a04654919a88b1b23819a9
|
|
| BLAKE2b-256 |
0fb6624e57fe1ec22ddd803a8426d04ed5e10eceff5d7ad8d7aa65650f58d2d4
|
Provenance
The following attestation bundles were made for market_wave-2.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
workflow.yml on smturtle2/market-wave
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
market_wave-2.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
3eb7f535c604875813d94e3a244757a72118c75c90e7871b6dc152ce27c99836 - Sigstore transparency entry: 2153972127
- Sigstore integration time:
-
Permalink:
smturtle2/market-wave@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/smturtle2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file market_wave-2.1.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.
File metadata
- Download URL: market_wave-2.1.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
- Upload date:
- Size: 606.7 kB
- Tags: CPython 3.10+, macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ee784ec79c8d111a2ef05aef3039d0810cde18a6833e90e4b60e21eff5481f1
|
|
| MD5 |
07e013da4930770df3dbf38f10cb2b72
|
|
| BLAKE2b-256 |
a3fe3cbd54bd7c71d13ba3765ef59465692356119303bf5ac824ceb00b90dbdc
|
Provenance
The following attestation bundles were made for market_wave-2.1.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:
Publisher:
workflow.yml on smturtle2/market-wave
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
market_wave-2.1.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl -
Subject digest:
7ee784ec79c8d111a2ef05aef3039d0810cde18a6833e90e4b60e21eff5481f1 - Sigstore transparency entry: 2153972351
- Sigstore integration time:
-
Permalink:
smturtle2/market-wave@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/smturtle2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@82fd6dd2c3aef17c243a71449e07c0cbfb2d71a2 -
Trigger Event:
push
-
Statement type: