Skip to content

OMS API

The Order Management System API surface manages order creation, modification, cancellation, compliance evaluation, and allocation. All operations go through the sidecar on localhost:9191 and are routed to the order-book kernel via command topics.


Order Management

CreateOrder

Creates a new order. The kernel assigns order_id, created_at, updated_at and sets state to CREATED. Compliance checks are not triggered automatically.

order_id = client.oms.create_order(
    portfolio_id="PORT-001",
    instrument_id="INS-01936d8a-7c1e-7b2a-8f3d-4e5a6b7c8d9e",
    direction="Buy",            # Buy | Sell | SellShort | BuyToCover
    ordered_quantity=1000,
    order_type="Limit",         # Market | Limit | Stop | StopLimit | PreviouslyQuoted
    time_in_force="Day",        # Day | GTC | IOC | FOK | GTD | AtTheOpen | AtTheClose
    limit_price=150.25,         # required for Limit / StopLimit
)
orderID, err := client.OMS.CreateOrder(ctx, &oms.CreateOrderRequest{
    PortfolioID:     "PORT-001",
    InstrumentID:    "INS-01936d8a-7c1e-7b2a-8f3d-4e5a6b7c8d9e",
    Direction:       oms.DirectionBuy,
    OrderedQuantity: decimal.NewFromFloat(1000),
    OrderType:       oms.OrderTypeLimit,
    TimeInForce:     oms.TIFDay,
    LimitPrice:      decimal.NewFromFloat(150.25),
})

Fields: portfolio_id, instrument_id, direction, ordered_quantity, order_type, time_in_force, limit_price (optional), stop_price (optional), basket_id (optional), metadata (optional).

Errors: INVALID_INSTRUMENT, INVALID_PORTFOLIO, INVALID_ORDER_TYPE, DUPLICATE_ORDER.


UpdateOrder

Updates a mutable field on an existing order. Economic fields (ordered_quantity, limit_price, stop_price, time_in_force) lock after compliance passes. Booking fields (counterparty_id, metadata) remain updatable post-trade.

updated = client.oms.update_order(
    order_id=order_id,
    changes={"limit_price": 151.00},
)
updated, err := client.OMS.UpdateOrder(ctx, orderID, &oms.OrderChanges{
    LimitPrice: decimal.NewFromFloat(151.00),
})

Errors: ORDER_NOT_FOUND, INVALID_STATE, FIELD_LOCKED.


CancelOrder

Cancels an order. Active placements are canceled by the EMS separately. Cancel authority is role-scoped:

Role Allowed States
PM CREATED, PENDING_PRE_TRADE_COMPLIANCE, PRE_TRADE_COMPLIANCE_PASSED, PRE_TRADE_COMPLIANCE_FAILED
Trader SENT_TO_TRADER, ROUTED (only if no fills exist)
Ops Cannot cancel orders
client.oms.cancel_order(order_id=order_id, reason="Client instruction")
err := client.OMS.CancelOrder(ctx, orderID, "Client instruction")

Errors: ORDER_NOT_FOUND, INVALID_STATE, CANCEL_NOT_AUTHORIZED.


CloseOrder

Closes an order after execution completes (full or partial). Returns the executed and unfilled quantities. The OMS can then create a remainder order for the unfilled portion.

result = client.oms.close_order(order_id=order_id)
# result.executed_quantity  -> Decimal("750")
# result.unfilled_quantity  -> Decimal("250")
result, err := client.OMS.CloseOrder(ctx, orderID)
// result.ExecutedQuantity -> 750
// result.UnfilledQuantity -> 250

GetOrder

Retrieves a single order by ID.

order = client.oms.get_order(order_id=order_id)

ListOrders

Queries orders with optional filters. Results are ordered by created_at descending.

orders = client.oms.list_orders(
    portfolio_id="PORT-001",
    instrument_id="INS-01936d8a-...",   # optional
    state="ROUTED",                      # optional
    direction="Buy",                     # optional
    created_after="2026-03-01",          # optional
    created_before="2026-03-27",         # optional
    limit=50,                            # default 100
    offset=0,                            # default 0
)

All filter parameters are optional. Supported filters: portfolio_id, instrument_id, state, direction, basket_id, created_after, created_before, limit, offset.


Basket and Order Restructuring

CreateBasket

Groups orders for coordinated execution. Orders must not already belong to another basket.

basket_id = client.oms.create_basket(
    name="Tech Rebalance 2026-03-27",
    order_ids=[order_id_1, order_id_2, order_id_3],
)

MergeOrders

Merges multiple orders into a single order. Source orders are linked to the merged order via OrderLink.

merged_id = client.oms.merge_orders(order_ids=[order_id_1, order_id_2])

SplitOrder

Splits one order into multiple orders by quantity. Source order is linked to the split orders via OrderLink.

split_ids = client.oms.split_order(
    order_id=order_id,
    split_quantities=[400, 600],
)

Compliance

Pre-Trade Compliance

Compliance plugins evaluate rules and publish results via kernel commands. The order-book kernel gates state transitions based on these results.

# Compliance plugin passes pre-trade compliance
client.oms.pass_pre_trade_compliance(order_id=order_id)

# Compliance plugin fails pre-trade compliance with violations
client.oms.fail_pre_trade_compliance(
    order_id=order_id,
    violations=[
        {"rule_id": "R-001", "rule_name": "Max Position Size", "severity": "HARD", "description": "Would exceed 5% single-name limit"},
    ],
)

# Authorized user overrides a failed check
override_id = client.oms.override_pre_trade_compliance(
    order_id=order_id,
    reason="CIO approved exception for concentrated position",
    approver_id="USER-0042",
)

Post-Trade Compliance

Same pattern as pre-trade, applied after execution:

client.oms.pass_post_trade_compliance(order_id=order_id)
client.oms.fail_post_trade_compliance(order_id=order_id, violations=[...])
override_id = client.oms.override_post_trade_compliance(
    order_id=order_id, reason="...", approver_id="USER-0042"
)

What-If Compliance Check

Simulates compliance for proposed orders without committing state changes.

results = client.oms.check_compliance_what_if(proposed_orders=[
    {"portfolio_id": "PORT-001", "instrument_id": "INS-...", "direction": "Buy", "ordered_quantity": 5000},
])
# results[0].passed -> False
# results[0].violations -> [...]

Query Compliance Headroom

Returns how much capacity remains before a rule limit is breached.

headroom = client.oms.query_compliance_headroom(
    portfolio_id="PORT-001",
    rule_id="R-001",
)
# headroom.current_value  -> Decimal("3200000")
# headroom.limit_value    -> Decimal("5000000")
# headroom.headroom       -> Decimal("1800000")
# headroom.headroom_pct   -> 0.36

Subscribe to Compliance Events

Real-time stream of compliance events, including market-driven breaches.

for event in client.oms.subscribe_compliance(portfolio_id="PORT-001"):
    print(event.rule_id, event.event_type, event.severity)

Compliance Rule Management

Plugins create and maintain rules via CRUD operations. The kernel stores rules and gates lifecycle transitions.

# Create a rule
rule_id = client.oms.create_rule(
    rule_type="concentration_limit",
    parameters={"max_pct": 0.05, "scope": "single_name"},
    target_accounts=["PORT-001", "PORT-002"],
    active=True,
)

# Update a rule (immutable fields: rule_id, deployment_id, created_by, created_at)
client.oms.update_rule(rule_id=rule_id, changes={"parameters": {"max_pct": 0.10}})

# Soft-delete a rule (sets active=False, record retained)
client.oms.delete_rule(rule_id=rule_id)

# Query rules
rules = client.oms.list_rules(portfolio_id="PORT-001", rule_type="concentration_limit")

Allocation

Allocation operations create per-account allocations for filled orders.

CreateAllocation

allocation_id = client.oms.create_allocation(
    order_id=order_id,
    account_id="ACCT-001",
    portfolio_id="PORT-001",
    quantity=500,
)
allocID, err := client.OMS.CreateAllocation(ctx, &oms.CreateAllocationRequest{
    OrderID:     orderID,
    AccountID:   "ACCT-001",
    PortfolioID: "PORT-001",
    Quantity:    decimal.NewFromFloat(500),
})

UpdateAllocation

updated = client.oms.update_allocation(
    allocation_id=allocation_id,
    changes={"quantity": 450},
)

GetAllocation

alloc = client.oms.get_allocation(allocation_id=allocation_id)

Ownership Handoff

SendToTrader

Transfers order ownership from the PM to the trading desk. Valid only after pre-trade compliance passes.

client.oms.send_to_trader(order_id=order_id)

SendToOperations

Transfers order ownership from the trading desk to operations. Valid after the order is closed.

client.oms.send_to_operations(order_id=order_id)

18-State Order Lifecycle

CREATED
  -> PENDING_PRE_TRADE_COMPLIANCE
    -> PRE_TRADE_COMPLIANCE_PASSED
      -> SENT_TO_TRADER               (PM -> Trader handoff)
        -> ROUTED
          -> PARTIALLY_FILLED
            -> FILLED
              -> CLOSED
                -> SENT_TO_OPERATIONS  (Trader -> Ops handoff)
                  -> PENDING_POST_TRADE_COMPLIANCE
                    -> POST_TRADE_COMPLIANCE_PASSED
                      -> CONFIRMED
                        -> SETTLED
                          -> RECONCILED (terminal)

Branching states:
  PRE_TRADE_COMPLIANCE_FAILED   (from PENDING_PRE_TRADE_COMPLIANCE)
  POST_TRADE_COMPLIANCE_FAILED  (from PENDING_POST_TRADE_COMPLIANCE)
  CANCELED                      (from any non-terminal state, subject to cancel authority)
  REJECTED                      (terminal, system-initiated)
# State Owner Description
1 CREATED PM Order intent recorded
2 PENDING_PRE_TRADE_COMPLIANCE System Awaiting compliance evaluation
3 PRE_TRADE_COMPLIANCE_PASSED PM Cleared for trading
4 PRE_TRADE_COMPLIANCE_FAILED PM Compliance violation detected
5 SENT_TO_TRADER Trader PM handed to trading desk
6 ROUTED Trader Placements created at venue(s)
7 PARTIALLY_FILLED Trader Some quantity executed
8 FILLED Trader Full quantity executed
9 CLOSED Trader Execution complete, unfilled mapped
10 SENT_TO_OPERATIONS Ops Handed to operations for post-trade
11 PENDING_POST_TRADE_COMPLIANCE System Awaiting post-trade compliance
12 POST_TRADE_COMPLIANCE_PASSED Ops Post-trade compliance cleared
13 POST_TRADE_COMPLIANCE_FAILED Ops Post-trade compliance violation
14 CONFIRMED Ops Middle office confirmed
15 SETTLED Ops Custodian settled
16 RECONCILED -- Terminal state, fully reconciled
17 CANCELED -- Terminal state, order canceled
18 REJECTED -- Terminal state, system rejected