Skip to content

Order Management Service

tien.nguyen edited this page Jul 30, 2026 · 1 revision

Order Management Service (OMS)

The Order Management Service (OMS) is the central core service of the Emporia Trading Platform. It acts as the authoritative ledger and state machine manager for all equity order lifecycles, execution fill roll-ups, idempotency records, and order domain event broadcasting.


πŸ“Œ Service Specifications

  • Directory: order-management-service
  • HTTP Port: 8086
  • Database Boundary: emporia_order_data (PostgreSQL)
  • Primary Roles:
    • State machine authority for TradingOrder entities.
    • Idempotent handler for order placement (CREATE), modifications (MODIFY), and cancellations (CANCEL).
    • Execution fill processor (FILL), deduplicating venue executions.
    • CQRS query API provider (GET /api/orders).

πŸ—οΈ Architecture & Component Flow

flowchart TD
    subgraph InboundEvents ["Inbound Kafka Channels"]
        K1[["emporia.order.commands.v1"]] -->|OrderCommand| OCH["OrderCommandHandler"]
        K2[["emporia.execution.commands.v1"]] -->|ExecutionCommand| ECH["ExecutionCommandHandler"]
    end

    subgraph CoreOMS ["Order Management Service Core"]
        OCH --> IdempotencyCheck{"Processed Before?"}
        IdempotencyCheck -- Yes --> CachedOutcome["Return Cached ProcessingOutcome"]
        IdempotencyCheck -- No --> OrderSM["TradingOrder Entity (State Machine)"]

        ECH --> DeduplicateFill{"Execution Ref Exists?"}
        DeduplicateFill -- Yes --> IgnoreFill["Ignore Duplicate Venue Fill"]
        DeduplicateFill -- No --> OrderSM

        OrderSM --> DB[("PostgreSQL: emporia_order_data")]
    end

    subgraph OutboundEvents ["Outbound Event Channels"]
        OrderSM --> K3[["emporia.orders.v1 (OrderDomainEvents)"]]
        OCH --> K4[["emporia.order.results.v1 (OrderCommandResult)"]]
    end

    subgraph RestClients ["REST API Clients"]
        WebUI["React 19 Trading Dashboard"] -->|GET /api/orders| QueryCtrl["OrderQueryController"]
        QueryCtrl --> DB
    end
Loading

πŸ”‘ Core Handlers & Service Logic

1. OrderCommandHandler.java

Handles order command records produced by order-command-service:

  • CREATE: Instantiates a new TradingOrder in PENDING_NEW status, validates lot/tick sizes, saves to DB, advances to LIVE, and publishes OrderCreated to emporia.orders.v1.
  • MODIFY: Validates new quantity/price parameters against static data constraints and updates active orders.
  • CANCEL: Invokes TradingOrder.requestCancel() to transition order to CANCELLED.
  • CANCEL_ALL: Performs bulk cancellation of active orders for a trading desk.
  • Idempotency Guard: Checks ProcessedCommandRepository by commandId. If a command was previously processed, it immediately returns the cached ProcessingOutcome without re-executing logic.

2. ExecutionCommandHandler.java

Processes venue execution updates produced by execution-service or exchange matching engines:

  • FILL: Invokes TradingOrder.applyFill(fillQuantity, fillPrice). Recalculates traded quantity, remaining quantity, and volume-weighted average price (VWAP).
  • REJECT: Transitions order to REJECTED status with failure error messages.
  • CANCEL: Confirms venue cancellation via TradingOrder.confirmCancel().
  • Fill Deduplication: Checks ExecutionRepository.existsByExecutionReference() to ignore duplicate venue fill messages.

3. Synchronized State Machine (TradingOrder.java)

Synchronized domain methods ensure thread safety under high concurrency:

  • Quantity Conservation Invariant: quantity = tradedQuantity + remainingQuantity
  • Volume-Weighted Average Price (VWAP): Recalculates average price on each fill: P_new = ((P_prev Γ— Q_prev) + (P_fill Γ— Ξ”Q)) / (Q_prev + Ξ”Q)
  • Late Fill Safety: Accepts fills on orders even if in CANCELLED status, ensuring zero execution accounting is lost.

πŸ—„οΈ Database Schema (emporia_order_data)

Table Name Entity Class Purpose
trading_orders TradingOrder Primary table storing order status, side, quantities, VWAP price, user ID, and desk ID.
order_events OrderEvent Immutable audit trail storing domain state events (OrderCreated, OrderFilled, etc.).
executions Execution Log of all execution fills received from market venues with unique execution references.
processed_commands ProcessedCommand Idempotency table storing command IDs and correlated command results.

πŸ”’ Concurrency & Resilience Protections

  1. Optimistic Locking: JPA @Version annotation on TradingOrder triggers OptimisticLockException if two threads attempt to mutate the same order record concurrently.
  2. Pessimistic Locking: TradingOrderRepository.findByIdWithLock() executes SELECT ... FOR UPDATE for critical execution fill roll-ups.
  3. Verified Concurrency: Validated under 200 controlled thread schedule iterations by Fray (TradingOrderFraySpec) and PostgreSQL container concurrency specs (TradingOrderPostgresConcurrencySpec).

Clone this wiki locally