Skip to main content

Embeddable pre-trade risk SDK

Project description

Pit (Pre-trade Integrity Toolkit) for Python

Verify Release Python versions PyPI License

openpit is an embeddable pre-trade risk SDK for integrating policy-driven risk checks into trading systems from Python.

For an overview and links to all resources, see the project website openpit.dev. For the Python API guide and generated reference, see openpit.readthedocs.io. For full project documentation, see the repository README. For conceptual and architectural pages, see the project wiki.

Versioning Policy (Pre‑1.0)

Until Pit reaches a stable 1.0 release, the project follows a relaxed interpretation of Semantic Versioning.

During this phase:

  • PATCH releases are used for bug fixes and small internal corrections.
  • MINOR releases 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.

Getting Started

Visit the PyPI package.

Install

For normal end-user installation, use the published PyPI package:

pip install openpit

If you need local development/debugging, clone this repository and build from source with Maturin:

maturin develop --manifest-path bindings/python/Cargo.toml

Local release build:

maturin develop --release --manifest-path bindings/python/Cargo.toml

Engine

Overview

The engine evaluates an order through a deterministic pre-trade pipeline:

  • engine.start_pre_trade(order=...) runs start-stage policies and makes lightweight check policies
  • request.execute() runs main-stage check policies
  • reservation.commit() applies reserved state
  • reservation.rollback() reverts reserved state
  • engine.apply_execution_report(report=...) updates post-trade policy state

Start-stage policies stop on the first reject. Main-stage policies aggregate rejects and run rollback mutations in reverse order when any reject is produced.

Built-in policies currently include:

  • OrderValidationPolicy
  • PnlBoundsKillSwitchPolicy
  • RateLimitPolicy
  • OrderSizeLimitPolicy

The primary integration model is to write project-specific policies against the public Python policy API described in the manual: Custom Python policies.

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.

Threading

Canonical contract: Threading Contract.

The Python binding follows the same SDK threading contract. Public methods acquire the GIL when needed; the SDK does not release the GIL across callback boundaries, so Python policies execute on the calling thread.

Usage

import openpit

# 1. Configure policies.
pnl_policy = openpit.pretrade.policies.PnlBoundsKillSwitchPolicy(
    settlement_asset="USD",
    lower_bound=openpit.param.Pnl("-1000"),
    initial_pnl=openpit.param.Pnl("0"),
)

rate_limit_policy = openpit.pretrade.policies.RateLimitPolicy(
    max_orders=100,
    window_seconds=1,
)

order_size_policy = openpit.pretrade.policies.OrderSizeLimitPolicy(
    limit=openpit.pretrade.policies.OrderSizeLimit(
        settlement_asset="USD",
        max_quantity=openpit.param.Quantity("500"),
        max_notional=openpit.param.Volume("100000"),
    ),
)

# 2. Build the engine (one time at the platform initialization).
engine = (
    openpit.Engine.builder()
    .check_pre_trade_start_policy(
        policy=openpit.pretrade.policies.OrderValidationPolicy(),
    )
    .check_pre_trade_start_policy(policy=pnl_policy)
    .check_pre_trade_start_policy(policy=rate_limit_policy)
    .check_pre_trade_start_policy(policy=order_size_policy)
    .build()
)

# 3. Check an order.
order = openpit.Order(
    operation=openpit.OrderOperation(
        instrument=openpit.Instrument("AAPL", "USD"),
        account_id=openpit.param.AccountId.from_u64(99224416),
        side=openpit.param.Side.BUY,
        trade_amount=openpit.param.TradeAmount.quantity(100.0),
        price=openpit.param.Price(185.0),
    ),
)

start_result = engine.start_pre_trade(order=order)

if not start_result:
    messages = ", ".join(
        f"{r.policy} [{r.code}]: {r.reason}: {r.details}"
        for r in start_result.rejects
    )
    raise RuntimeError(messages)

request = start_result.request

# 4. Quick, lightweight checks, such as fat-finger scope or enabled kill
# switch, 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. 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.
execute_result = request.execute()

# Optional shortcut for the same two-stage flow:
# execute_result = engine.execute_pre_trade(order=order)

if not execute_result:
    messages = ", ".join(
        f"{reject.policy} [{reject.code}]: {reject.reason}: {reject.details}"
        for reject in execute_result.rejects
    )
    raise RuntimeError(messages)

reservation = execute_result.reservation

# 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.
try:
    send_order_to_venue(order)
except Exception:
    reservation.rollback()
    raise

reservation.commit()

# 7. The order goes to the venue and returns with an execution report.
report = openpit.ExecutionReport(
    operation=openpit.ExecutionReportOperation(
        instrument=openpit.Instrument("AAPL", "USD"),
        account_id=openpit.param.AccountId.from_u64(99224416),
        side=openpit.param.Side.BUY,
    ),
    financial_impact=openpit.FinancialImpact(
        pnl=openpit.param.Pnl("-50"),
        fee=openpit.param.Fee("3.4"),
    ),
)

result = engine.apply_execution_report(report=report)

# 8. 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 result.kill_switch_triggered is False

Errors

Policy rejects from engine.start_pre_trade() and request.execute() are returned as StartPreTradeResult and ExecuteResult.

Input validation errors and API misuse still raise exceptions:

  • ValueError for invalid assets/sides/malformed numeric inputs
  • RuntimeError for lifecycle misuse, for example executing the same request twice or finalizing the same reservation twice
  • Business rejects use stable reject codes such as openpit.pretrade.RejectCode.ORDER_VALUE_CALCULATION_FAILED when a policy cannot evaluate order value without price

Local Testing

Recommended local flow:

maturin develop --manifest-path bindings/python/Cargo.toml
python -m pytest bindings/python/tests

Run only unit tests:

maturin develop --manifest-path bindings/python/Cargo.toml
python -m pytest bindings/python/tests/unit

Run only integration test:

maturin develop --manifest-path bindings/python/Cargo.toml
python -m pytest bindings/python/tests/integration

For full build/test command matrix (manual and just), see the repository README.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openpit-0.3.0.tar.gz (200.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

openpit-0.3.0-cp310-abi3-win_amd64.whl (393.2 kB view details)

Uploaded CPython 3.10+Windows x86-64

openpit-0.3.0-cp310-abi3-musllinux_1_2_x86_64.whl (509.5 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

openpit-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (512.0 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

openpit-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (494.4 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

openpit-0.3.0-cp310-abi3-macosx_11_0_arm64.whl (439.7 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

openpit-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl (470.3 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file openpit-0.3.0.tar.gz.

File metadata

  • Download URL: openpit-0.3.0.tar.gz
  • Upload date:
  • Size: 200.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for openpit-0.3.0.tar.gz
Algorithm Hash digest
SHA256 c4da41b2a833820f79522ca906d55f559ede9bfd995f53c658e8f188c92cf66b
MD5 ddf19726dbf26c6ebbe2990ce99e50ba
BLAKE2b-256 40a3761374de59cec2e0d831ae83b59204ed1aecfd0f068842fcec0a9a9bf5e9

See more details on using hashes here.

File details

Details for the file openpit-0.3.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: openpit-0.3.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 393.2 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for openpit-0.3.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 f5f221acc228363670cb7edbc76274eef217b88d6ec1dcbfc87cfaeabe7a095e
MD5 7720200ef6c0dd82b1bc5cd0160c8ced
BLAKE2b-256 22bd9798f58096cc483be57548e0d9a2b3aae853a58da4f196b8f9197bdb1e7f

See more details on using hashes here.

File details

Details for the file openpit-0.3.0-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for openpit-0.3.0-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 7aab7d6d994c8a434c0a14f0d724e6c159154d2a41f926dd591eff223f6612fe
MD5 1493be3989f8e8a39383e68b03ffc1f2
BLAKE2b-256 03b8f737bb5fa3645839320b4f77518ae0782b053a351ab3648a3a45a6b78b88

See more details on using hashes here.

File details

Details for the file openpit-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for openpit-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 664502aece3da2b712b3c1c11e42df2b3963d6e073cff32538a489faa2f69689
MD5 ff43800406f413bb0ccf1703d6460843
BLAKE2b-256 230089259a77c64bd841d002ca07a635b02594726781c0c59fa1996799952360

See more details on using hashes here.

File details

Details for the file openpit-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for openpit-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a88127b12e92e953fee7ef4272d7d9198db73742710296634b766d44eda79401
MD5 3fd11c1e1ce96bd2df8bf8191c40d242
BLAKE2b-256 7b825c8678baa6238e58ec5a78dd8a42d3fc37e7eaa624c286ff97e9f2603fbe

See more details on using hashes here.

File details

Details for the file openpit-0.3.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for openpit-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 966808b2772942390eb7a1ef970daed30ef921178e49d1631495f3da711ce015
MD5 0a833affeb59d1a8f4e455fe7424b38d
BLAKE2b-256 38973bfa8d8d922b06b8160149835562947ffb90d8769559b43c7a44af0a7174

See more details on using hashes here.

File details

Details for the file openpit-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for openpit-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 b5c0775bf0023bef66506f83d3c16426fe77511467683b9fc9a89052a2554e54
MD5 4de938f70ddaf8d1b51cd25f247ebf0f
BLAKE2b-256 450eb21331221ea5c0c7e9549e205ccd373decaac5d9e3e84641eb690a6700b9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page