Order ticket
Side, type (market / limit / stop / stop-limit), TIF (day, GTC, IOC, FOK), allocation across accounts.
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.
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.
Side, type (market / limit / stop / stop-limit), TIF (day, GTC, IOC, FOK), allocation across accounts.
Five OPA checks in parallel. Decisions returned within 50ms typical. Each check has its own data file.
Per-tenant approval policy. Notional-band thresholds; senior-advisor / supervisor / two-person.
QuickFIX/J 2.3 gateway. NewOrderSingle, OrderCancelRequest, OrderCancelReplaceRequest. Webhook-back fills.
Toggle FIX_SIMULATOR_ENABLED=true in staging. Counterparty replies for the full lifecycle.
One ticket → many accounts. Pro-rata, equal-weight, or custom split. Each child has its own audit chain.
Each fill captured with venue, latency, slippage. Reportable per regulator (Reg BI, MiFID, COBS).
OrderCancelRequest sequencing handled correctly with QuickFIX/J's CCG semantics.
| Check | Allow | Warn | Deny |
|---|---|---|---|
| Suitability | Instrument risk ≤ client risk tolerance | One band higher (Conservative buys Moderate) | Two+ bands higher · approval required to override |
| Restricted list | Symbol absent from list | — | Symbol on tenant or jurisdiction restricted list |
| Concentration | Position would remain < 5% of portfolio | Position would land between 5% and 10% | Position would exceed 10% · supervisor required |
| AML | No flags | Cash threshold approaching | Cash structuring, jurisdiction mismatch, sanction touch |
| Jurisdiction | Order valid for client residency | Cross-listed; ensure tax handling | Restricted instrument for client jurisdiction |
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.
Options, futures, structured notes — supported in road-mapped extensions; pre-trade policy packs are jurisdiction-specific.
Pre-trade checks share the same OPA bundles compliance officers edit in the Rego editor.
FeatureFills land here as transactions; positions update; performance recalculates with the next snapshot.
FeatureEvery transition writes an audit event. Approvers and rejecters are durably linked to specific OPA decisions.
Bring a sample blotter. We'll route it through pre-trade OPA, approval, FIX simulator, and ExecutionReport back.