Pit is a workspace for embeddable pre-trade risk components.
The project is built around a simple idea: before an order reaches a venue, it should pass through a deterministic risk pipeline that can reject, reserve state, and later absorb post-trade outcomes back into the same control system.
- The engine is configured once during platform initialization.
- Each order first goes through lightweight start-stage checks. This stage is meant for fast decisions and for controls that must observe every request, even when the order is rejected early.
- If the order passes the start stage, the caller receives a deferred request object. That object represents the heavier pre-trade stage, but the heavy checks have not run yet.
- When the deferred request is executed, the engine runs the main-stage risk policies and collects all registered mutations. If the stage fails, the collected state is rolled back. If it succeeds, the caller receives a reservation.
- The reservation must then be finalized explicitly. Commit keeps the reserved state. Rollback cancels it. Dropping the reservation without finalization rolls it back automatically.
- After execution, post-trade reports are fed back into the engine so that policies depending on realized outcomes can update their internal state.
The current implementation focuses on the pre-trade pipeline and a set of foundational controls:
- P&L kill switch
- sliding-window rate limit
- per-settlement order size limits
The engine is intentionally in-memory and deterministic. It is designed to be embedded into a larger trading system rather than replace one.
The openpit crate README if you want to start
with the Rust interface and a runnable example.
The Python bindings README if you want to work
with Pit from Python via the openpit package.
Conceptual pages and longer architecture notes wiki..
- Rust toolchain
- Python
>=3.9 maturinfor Python bindings buildpytestfor Python tests
python3 -m venv .venv
source .venv/bin/activate
pip install -r ./requirements.txtWith Just:
just buildManual:
cargo build --workspaceWith Just:
just python-develop
just python-develop-releaseManual:
maturin develop --manifest-path bindings/python/Cargo.toml
maturin develop --release --manifest-path bindings/python/Cargo.tomlThe recommended Python test flow is to run maturin develop before pytest.
This runs against the current checkout (including a dirty worktree). If sources
did not change, Cargo can reuse cached artifacts and avoid a full rebuild.
With Just:
# All tests:
just test-all
# Rust:
just test-rust
# Python:
just test-python
just test-python-unit
just test-python-integrationManual:
# All tests:
cargo test --workspace
maturin develop --manifest-path bindings/python/Cargo.toml
python -m pytest bindings/python/tests
# Rust:
cargo test --workspace
# Python
maturin develop --manifest-path bindings/python/Cargo.toml
python -m pytest bindings/python/tests
python -m pytest bindings/python/tests/unit
python -m pytest bindings/python/tests/integration