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
[]
= "0.1.0"
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.