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.
For a compact path without manual request handling, use
engine.execute_pre_trade(order)as a shortcut. - 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, a small set of foundational built-in controls, and an API for building project-specific strategy and risk policies:
- 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. For custom policy APIs, see the wiki:
Until Pit reaches a stable 1.0 release, the project follows a relaxed
interpretation of Semantic Versioning.
During this phase:
PATCHreleases are used for bug fixes and small internal corrections.MINORreleases may introduce new features and may also change the public interface.
This means that breaking API changes can appear in minor releases before 1.0.
Consumers of the library should take this into account when declaring
dependencies and consider using version constraints that tolerate API
evolution during the pre‑stable phase.
The project website openpit.dev for an overview and links to all documentation.
The Go SDK README if you want to integrate Pit from Go.
The Python SDK README if you want to work
with Pit from Python via the openpit package.
The openpit crate README if you want to start
with the Rust interface and a runnable example.
The C SDK README if you want to integrate Pit from C or from environments that integrate through a C ABI.
Conceptual pages and longer architecture notes wiki.
- Rust toolchain
- Python
>=3.10if you build or test Python bindings maturinandpytestif you build or test Python bindings- Go
1.22if you build or test Go bindings
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.
Verified with Go 1.22.
With Just:
just test-go
just test-go-raceManual:
cargo build -p pit-ffi --release --locked
cd bindings/go
export OPENPIT_RUNTIME_LIBRARY_PATH="$(pwd)/../../target/release/libpit_ffi.so"
export LD_LIBRARY_PATH="$(pwd)/../../target/release${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
export CGO_LDFLAGS="-L$(pwd)/../../target/release -lpit_ffi"
go test ./...
go test -race ./...With Just:
# All tests:
just test-all
# Rust:
just test-rust
# Python:
just test-python
just test-python-unit
just test-python-integration
# Go:
just test-go
just test-go-raceManual:
# 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
# Go:
cargo build -p pit-ffi --release --locked
cd bindings/go
export OPENPIT_RUNTIME_LIBRARY_PATH="$(pwd)/../../target/release/libpit_ffi.so"
export LD_LIBRARY_PATH="$(pwd)/../../target/release${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
export CGO_LDFLAGS="-L$(pwd)/../../target/release -lpit_ffi"
go test ./...
go test -race ./...