Skip to main content

Crate of_execution_core

Crate of_execution_core 

Source
Expand description

Low-latency execution-domain primitives for Orderflow.

§of_execution_core

Crates.io Docs.rs CI License

of_execution_core is the canonical execution-domain model for Orderflow. It contains the low-level types used by the order-management and execution layers: fixed-size identifiers, typed order requests, execution reports, order-state transitions, and pre-trade risk contracts.

This crate is intentionally small. It has no broker SDKs, no sockets, no worker threads, no JSON payloads, and no dependency on the market-data analytics runtime. Higher-level crates build on it:

  • of_execution adds routes, adapters, journals, simulated execution, concurrency, and OMS helpers.
  • of_execution_adapters adds optional provider adapter scaffolds.
  • of_ffi_c, Python, and Java expose execution APIs through additive handles and classes.

§First Release: 0.1.0

of_execution_core starts at 0.1.0 even though the broader Orderflow release line is 0.4.0. This crate is a new public execution-domain surface. It is kept independent from the mature analytics crates so its identifiers, state machine, and risk contracts can stabilize honestly without implying the same API age as of_core.

Compatibility expectations:

  • all public APIs are intended to be additive where possible;
  • provider adapters should pin compatible 0.1.x versions while the execution trait family matures;
  • analytics crates do not depend on this crate;
  • bindings expose these concepts through additive execution handles/classes, not by changing existing analytics types.

§Design Goals

  • Keep hot-path order data as typed structs, not dynamic maps.
  • Use fixed-size ASCII identifiers instead of heap-owned strings.
  • Use integer-normalized prices and quantities.
  • Preserve deterministic, auditable state transitions.
  • Keep provider-specific behavior outside the core schema.
  • Make pre-trade risk decisions structured and testable.
  • Keep the model suitable for Rust, C ABI, Python, and Java integration.

§Public API Inventory

Constants:

Identifier types:

Errors and domain types:

Request and report types:

State-machine types:

Risk types:

§Identifier Model

Execution identifiers use FixedAscii<N>. A fixed ASCII value stores a length and an inline byte array. This avoids heap allocation in ordinary command and report structs, keeps FFI boundaries predictable, and prevents accidental Unicode normalization differences between host languages.

AliasCapacityPurpose
ClientOrderId40Strategy/client-assigned order id
VenueOrderId48Venue-assigned order id
ExecutionId48Venue fill/report id
AccountId32Trading account
RouteId32Execution route
StrategyId32Strategy attribution
VenueId16Venue/exchange id
InstrumentId32Venue-native instrument id
ExecutionText128Bounded diagnostic text

Identifier rules:

Example:

use of_execution_core::{ClientOrderId, ExecutionCoreError};

let id = ClientOrderId::new("STRAT-0001")?;
assert_eq!(id.as_str(), "STRAT-0001");
assert_eq!(id.capacity(), 40);
assert!(!id.is_empty());

let too_long = "X".repeat(41);
assert!(matches!(
    ClientOrderId::new(&too_long),
    Err(ExecutionCoreError::IdentifierTooLong { .. })
));

§Symbols, Quantity, And Price

ExecutionSymbol is the venue-native execution symbol:

  • venue: venue or exchange identifier
  • instrument: venue-native instrument id

OrderQty and OrderPrice are integer-normalized wrappers. Use symbol metadata outside this crate to convert user-facing decimals into the integer representation expected by a provider.

OrderQty::new rejects zero and negative values. OrderPrice::new rejects zero and negative values. Some request fields still use OrderPrice(0) as a sentinel when a price is not applicable, for example a market order limit price.

use of_execution_core::{ExecutionSymbol, OrderPrice, OrderQty};

let symbol = ExecutionSymbol::new("CME", "ESM6")?;
let qty = OrderQty::new(10)?;
let price = OrderPrice::new(505_000)?;

assert_eq!(symbol.instrument.as_str(), "ESM6");
assert_eq!(qty.0, 10);
assert_eq!(price.0, 505_000);

§Order Classification

OrderSide variants:

  • Buy
  • Sell

OrderType variants:

  • Market
  • Limit
  • Stop
  • StopLimit

TimeInForce variants:

  • Day
  • Gtc
  • Ioc
  • Fok
  • Gtd

These are canonical values. Provider adapters can translate them to native protocol values or reject unsupported combinations through capabilities/risk.

§Request Types

§OrderRequest

OrderRequest is the canonical new-order command.

Fields:

  • client_order_id: client-assigned id for the new order
  • account_id: trading account
  • route_id: execution route
  • strategy_id: strategy attribution
  • symbol: target venue/instrument
  • side: buy/sell
  • order_type: canonical type
  • time_in_force: canonical TIF
  • quantity: requested quantity
  • limit_price: limit price, or zero when not applicable
  • stop_price: stop trigger price, or zero when not applicable
  • ts_exchange_ns: exchange/session timestamp when known
  • ts_recv_ns: local creation/receive timestamp

OrderRequest::validate checks:

  • quantity must be positive
  • limit orders require positive limit_price
  • stop orders require positive stop_price
  • stop-limit orders require both positive limit_price and stop_price

§CancelRequest

CancelRequest carries:

  • client_order_id: client id for the cancel request itself
  • orig_client_order_id: client id of the order being cancelled
  • account_id
  • route_id
  • symbol
  • ts_exchange_ns
  • ts_recv_ns

This mirrors FIX-style cancel semantics where the cancel command may need a new client id separate from the original order id.

§AmendRequest

AmendRequest is the canonical cancel/replace command. It carries a new client id, the original client id, replacement quantity, replacement limit price, and timestamps. The higher-level engine checks that the original order is locally known before routing the request.

§Execution Reports

ExecutionType explains why an execution event exists:

  • Ack
  • Reject
  • Trade
  • CancelPending
  • CancelAck
  • CancelReject
  • ReplacePending
  • ReplaceAck
  • ReplaceReject
  • Expired
  • Status
  • Restated
  • Degraded

OrderStatus explains the state after the event is applied. Terminal states are detected with OrderStatus::is_terminal().

ExecutionEvent is the canonical report shape. It includes:

  • current and original client order ids
  • venue order id
  • execution id
  • account, route, and symbol
  • execution type and resulting order status
  • last fill quantity/price
  • cumulative quantity
  • leaves quantity
  • average price
  • exchange and receive timestamps
  • structured rejection reason
  • bounded diagnostic text

Constructors:

  • ExecutionEvent::accepted(&OrderRequest, VenueOrderId)
  • ExecutionEvent::rejected(&OrderRequest, RiskRejectReason, ExecutionText)

Provider adapters can construct events directly, but these helpers keep common local ack/reject reports consistent.

§Order State Machine

OrderStateMachine owns one OrderState and applies ExecutionEvent values. Illegal transitions return ExecutionCoreError::InvalidTransition.

Typical lifecycle:

  1. OrderStateMachine::new(&request) starts at PendingNew.
  2. ExecutionType::Ack moves to New.
  3. ExecutionType::Trade moves to PartiallyFilled or Filled.
  4. ExecutionType::CancelAck moves to Cancelled.
  5. ExecutionType::ReplaceAck moves to Replaced and updates the active client order id.
  6. ExecutionType::Restated updates local state from recovery reports.

The state machine is deliberately strict. It accepts status-style reports after terminal states, but rejects ordinary lifecycle transitions that would mutate a terminal order.

use of_execution_core::{
    AccountId, ClientOrderId, ExecutionEvent, ExecutionSymbol, OrderPrice,
    OrderQty, OrderRequest, OrderSide, OrderStateMachine, OrderType, RouteId,
    StrategyId, TimeInForce, VenueOrderId,
};

let req = OrderRequest {
    client_order_id: ClientOrderId::new("C1")?,
    account_id: AccountId::new("ACC")?,
    route_id: RouteId::new("SIM")?,
    strategy_id: StrategyId::new("STRAT")?,
    symbol: ExecutionSymbol::new("SIM", "ES")?,
    side: OrderSide::Buy,
    order_type: OrderType::Limit,
    time_in_force: TimeInForce::Day,
    quantity: OrderQty::new(1)?,
    limit_price: OrderPrice::new(5000)?,
    stop_price: OrderPrice(0),
    ts_exchange_ns: 0,
    ts_recv_ns: 1,
};

let mut state = OrderStateMachine::new(&req);
let ack = ExecutionEvent::accepted(&req, VenueOrderId::new("V1")?);
state.apply(&ack)?;
assert_eq!(state.state().client_order_id, req.client_order_id);

§Risk Model

RiskLimits is the basic per-route/account/symbol risk configuration:

  • kill_switch
  • max_order_qty
  • max_order_notional
  • max_open_orders
  • max_open_notional
  • price_band_ticks

Zero disables numeric checks. RiskLimits::default() enables the kill switch, so callers must explicitly disable it for test or live routes that should accept orders.

RiskContext is supplied by higher-level engines. It includes runtime facts:

  • open order count
  • open notional
  • reference price
  • duplicate client order id flag
  • whether the account, route, and symbol are enabled
  • whether the order type and TIF are supported

RiskCheck is the extension trait:

  • check_new
  • check_amend
  • check_cancel

BasicRiskGate implements deterministic checks for the basic limit set.

use of_execution_core::{BasicRiskGate, RiskCheck, RiskLimits};

let gate = BasicRiskGate::new(RiskLimits {
    kill_switch: false,
    max_order_qty: 100,
    max_order_notional: 1_000_000,
    max_open_orders: 5,
    max_open_notional: 5_000_000,
    price_band_ticks: 0,
});

// Higher-level engines build RiskContext and call the gate before routing.
let _ = gate;

§Low-Latency Notes

  • Requests and reports are fixed-layout structs.
  • Identifiers are inline fixed-size ASCII fields.
  • Numeric fields are integers.
  • Validation is explicit and local.
  • The crate does not allocate for ordinary order/request/event structs.
  • Provider strings and protocol-specific payloads should be translated at the adapter boundary before entering this model.

§What This Crate Does Not Do

This crate does not:

  • connect to brokers or exchanges
  • own order routes
  • run worker threads
  • expose a C ABI directly
  • persist journals
  • reconcile venue open orders
  • enforce provider rate limits
  • parse FIX/REST/WebSocket messages

Use of_execution for routing, adapter calls, simulated execution, journaling, recovery, and OMS helpers.

§Documentation

Additional project documentation:

  • docs/handbook/05g-of-execution-core-reference.md
  • docs/handbook/09-oms-architecture.md
  • docs/handbook/11-low-latency-design.md

Structs§

AmendRequest
Amend/cancel-replace request.
BasicRiskGate
Deterministic pre-trade risk gate.
CancelRequest
Cancel request.
ExecutionEvent
Canonical execution event.
ExecutionSymbol
Execution symbol in venue-native format.
FixedAscii
Fixed-size ASCII field used for low-allocation identifiers.
OrderPrice
Integer-normalized order price.
OrderQty
Integer-normalized order quantity.
OrderRequest
New order request.
OrderState
Current order state.
OrderStateMachine
Deterministic order state machine.
RiskContext
Runtime risk context supplied by the execution engine.
RiskDecision
Risk decision.
RiskLimits
Static risk limits for one route/account scope.

Enums§

ExecutionCoreError
Execution-core error.
ExecutionType
Canonical execution report purpose.
OrderSide
Buy/sell order side.
OrderStatus
FIX-style canonical order status.
OrderType
Supported canonical order types.
RiskRejectReason
Structured risk rejection reason.
TimeInForce
Time-in-force policy.

Constants§

EXECUTION_TEXT_CAP
Maximum bytes stored in an execution diagnostic text field.

Traits§

RiskCheck
Pre-trade risk-check contract.

Type Aliases§

AccountId
Trading account identifier.
ClientOrderId
Client-assigned order identifier.
ExecutionId
Venue execution/fill identifier.
ExecutionText
Bounded diagnostic text.
InstrumentId
Instrument identifier in venue/native format.
RouteId
Execution route identifier.
StrategyId
Strategy identifier used for attribution.
VenueId
Venue identifier used by execution routing.
VenueOrderId
Venue-assigned order identifier.