Feature · Trading

Eleven states. Five pre-trade checks. One audited path to fill.

Every order walks through suitability, restricted-list, concentration, AML, and jurisdiction policies before it can leave for approval. Then through FIX. Then back as fills.

What it does

An order is not a row in a table. It is a workflow.

Every order in Modir is owned by a tradeOrderWorkflow in Temporal. The workflow walks through eleven states — draft, submitted, checks_running, checks_failed, pending_approval, approved, routing, working, partial, filled, cancelled — and each transition is a signal, not a database write. State is durable; if the worker restarts mid-route, the order picks up exactly where it was.

Pre-trade checks run as Open Policy Agent decisions in data.ai_actions and data.suitability packages. The five checks — suitability (risk tolerance vs instrument risk), restricted-list (per-tenant, per-jurisdiction blocklists), concentration (single-position limits), AML (large cash, structuring, jurisdiction-mismatched transfers), and jurisdiction (per-residency rules) — return one of allow, warn, deny. A warn surfaces in the UI but does not block; a deny blocks.

Approval routing is policy-driven: orders above a notional threshold for a given client risk tier require senior-advisor or supervisor approval. The approver sees the OPA decision rationale (per check, with the matching policy data row) and signs off — or rejects with a reason. Approved orders route to the FIX gateway: a Spring Boot service running QuickFIX/J 2.3, with NewOrderSingle out and ExecutionReport back via webhook into the API.

For staging, an embedded FIX simulator answers as a counterparty would: partial fills, cancels, rejects, mass-cancel events. CI runs the full state machine against the simulator on every PR.

State machine

Eleven states, fully observable.

Order state machine
Capabilities

Eight things the trading context owns.

Order ticket

Side, type (market / limit / stop / stop-limit), TIF (day, GTC, IOC, FOK), allocation across accounts.

Pre-trade matrix

Five OPA checks in parallel. Decisions returned within 50ms typical. Each check has its own data file.

Approval chains

Per-tenant approval policy. Notional-band thresholds; senior-advisor / supervisor / two-person.

FIX 4.4

QuickFIX/J 2.3 gateway. NewOrderSingle, OrderCancelRequest, OrderCancelReplaceRequest. Webhook-back fills.

Embedded simulator

Toggle FIX_SIMULATOR_ENABLED=true in staging. Counterparty replies for the full lifecycle.

Multi-allocation

One ticket → many accounts. Pro-rata, equal-weight, or custom split. Each child has its own audit chain.

Best-execution log

Each fill captured with venue, latency, slippage. Reportable per regulator (Reg BI, MiFID, COBS).

Cancel + amend

OrderCancelRequest sequencing handled correctly with QuickFIX/J's CCG semantics.

Pre-trade matrix

Five checks. Three outcomes.

CheckAllowWarnDeny
SuitabilityInstrument risk ≤ client risk toleranceOne band higher (Conservative buys Moderate)Two+ bands higher · approval required to override
Restricted listSymbol absent from listSymbol on tenant or jurisdiction restricted list
ConcentrationPosition would remain < 5% of portfolioPosition would land between 5% and 10%Position would exceed 10% · supervisor required
AMLNo flagsCash threshold approachingCash structuring, jurisdiction mismatch, sanction touch
JurisdictionOrder valid for client residencyCross-listed; ensure tax handlingRestricted instrument for client jurisdiction
FIX session diagram

FIX session topology

The FIX gateway maintains one initiator per counterparty. Sessions persist; sequence numbers stored in Postgres for failover. ExecutionReports come back as webhooks signed with HMAC-SHA256; the API verifies the signature and signals the workflow.

Drop-copy sessions are supported: a separate listener writes to a read-only ledger for compliance review and reconciliation. Drop-copy never leaks into the live order machine.

Instrument types

What we route today.

Options, futures, structured notes — supported in road-mapped extensions; pre-trade policy packs are jurisdiction-specific.

Order ticket
Trading walkthrough

See an order from ticket to fill.

Bring a sample blotter. We'll route it through pre-trade OPA, approval, FIX simulator, and ExecutionReport back.