Pit: Pre-trade Integrity Toolkit
openpit is an embeddable pre-trade risk SDK for integrating policy-driven
risk checks into trading systems.
For full project documentation, see the repository README. For conceptual and architectural pages, see the project wiki.
Install
Run the following Cargo command in your project directory:
Engine
Overview
The engine evaluates an order through a deterministic pre-trade pipeline:
start_pre_trade(order)runs lightweight start-stage policiesRequest::execute()runs main-stage policiesReservation::commit()applies reserved state- dropping
Reservationrolls state back automatically apply_execution_report(report)updates post-trade policy state
Start-stage policies stop on the first reject. Main-stage policies aggregate rejects and roll back registered mutations in reverse order when any reject is produced.
Built-in start-stage policies currently include:
OrderValidationPolicyPnlKillSwitchPolicyRateLimitPolicyOrderSizeLimitPolicy
There are two types of rejections: a full kill switch for the account and a rejection of only the current request. This is useful in algorithmic trading when automatic order submission must be halted until the situation is analyzed.
Usage
use Duration;
use ;
use ;
use OrderValidationPolicy;
use PnlKillSwitchPolicy;
use RateLimitPolicy;
use ;
use Engine;
let usd = new.expect;
// 1. Configure policies.
let pnl = new;
let rate_limit = new;
let size = new;
// 2. Build the engine (one time at the platform initialization).
let engine = builder
.check_pre_trade_start_policy
.check_pre_trade_start_policy
.check_pre_trade_start_policy
.check_pre_trade_start_policy
.build
.expect;
// 3. Check an order.
let order = Order ;
let request = engine
.start_pre_trade
.expect;
// 4. Quick, lightweight checks, such as fat-finger scope or enabled killswitch,
// were performed during pre-trade request creation. The system state has not
// yet changed, except in cases where each request, even rejected ones, must be
// considered (for example, to prevent frequent transfers). Before the
// heavy-duty checks, other work on the request can be performed simply by
// holding the request object.
// 5. Real pre-trade and risk control.
let reservation = request.execute.expect;
// 6. If the request is successfully sent to the venue, it must be committed.
// The rollback must be called otherwise to revert all performed reservations.
reservation.commit;
// 5. The order goes to the venue and returns with an execution report.
let report = ExecutionReport ;
let result = engine.apply_execution_report;
// 6. After each execution report is applied, the system may report that it has
// been determined in advance that all subsequent requests will be rejected if
// the account status does not change.
assert!;
Errors
Rejects from start_pre_trade(order) and Request::execute() are returned as
Err(Reject) and Result<Reservation, Vec<Reject>>.
Each Reject contains:
policy: policy namecode: stable machine-readable code (for exampleRejectCode::OrderQtyExceedsLimit)reason: short human-readable reject type (for example"order quantity exceeded")details: concrete case details (for example"requested 11, max allowed: 10")scope:RejectScope::OrderorRejectScope::Account
RejectCode values are standardized and stable across Rust, Python, and C FFI.