Skip to content

Settlement Service

The Settlement Service orchestrates the liquidation lifecycle — from margin call escalation through position closeout via the normal Order → Matching pipeline. It does not directly mutate positions or wallets; instead it creates system liquidation orders that flow through the standard execution path.

  • Liquidation Orchestration: Receive liquidation triggers from the Position Service, create system liquidation orders routed through Order Service → Matching Engine.
  • Margin Call Handling: Escalate margin calls, provide grace period, and proceed to liquidation if not resolved.
  • Settlement Record Keeping: Persist every settlement action with full audit trail.
  • ADL / Insurance Fund Fallback: When liquidation orders can’t fill at bankruptcy price, use Auto-Deleveraging (ADL) or insurance fund to cover shortfall.
  • Compliance-Grade Audit: Every liquidation produces a compliance-grade record with timestamps, prices, and reasons.

The Settlement Service is an orchestrator only — it does not have direct DB access to positions, wallets, or order books. All mutations flow through the respective service APIs.

graph TB PosSvc[Position Service] -->|risk.liquidation.trigger.v1| Kafka[Kafka] RiskSvc[Risk Service] -->|risk.liquidation.v1| Kafka Kafka --> Settlement[Settlement Service] Settlement -->|gRPC InitiateLiquidation| OrderSvc[Order Service] OrderSvc --> ME[Matching Engine] ME -->|engine.event.v1| Kafka2[Kafka] Kafka2 --> Settlement Settlement -->|gRPC| Wallet[Wallet Service] Settlement -->|Stores| PG[(PostgreSQL)] Settlement -->|Events| Kafka3[Kafka]
FieldTypeDescription
idUUID (PK)Settlement record ID
user_idUUIDAccount being settled
symbolVARCHAR(32)Instrument symbol
settlement_typeENUM(liquidation, margin_call, expiry, manual_closeout)Type of settlement
statusENUM(initiated, pending_fill, partially_filled, completed, failed, abl_triggered)Settlement status
position_sizeNUMERIC(24,12)Position size at time of settlement
entry_priceNUMERIC(24,12)Position entry price
mark_price_at_triggerNUMERIC(24,12)Mark price when triggered
bankruptcy_priceNUMERIC(24,12)Bankruptcy price (no margin left)
liquidation_priceNUMERIC(24,12)Liquidation trigger price
fill_priceNUMERIC(24,12)Actual fill price (weighted avg)
filled_qtyNUMERIC(24,12)Quantity filled
shortfallNUMERIC(24,12)Shortfall if fill worse than bankruptcy (covered by insurance/ADL)
insurance_fund_usedNUMERIC(24,12)Amount covered by insurance fund
adl_triggeredBOOLEANWhether ADL was used
reasonTEXTHuman-readable reason
initiated_atTIMESTAMPTZWhen settlement was triggered
completed_atTIMESTAMPTZWhen settlement completed
FieldTypeDescription
idUUID (PK)Liquidation order ID
settlement_idUUID (FK)References settlement_records
order_idUUIDOrder ID in Order Service
sideENUM(buy, sell)Close direction
quantityNUMERIC(24,12)Order quantity
priceNUMERIC(24,12)Limit price (bankruptcy price)
statusENUM(submitted, accepted, partially_filled, filled, failed)Order status
created_atTIMESTAMPTZSubmission time
updated_atTIMESTAMPTZLast status update
RPCDescriptionCalled By
InitiateSettlement(user_id, symbol, settlement_type, reason)Begin settlement processRisk Service, Admin
GetSettlementStatus(settlement_id)Query settlement statusAdmin, Monitoring
ProcessMarginCall(user_id, symbol, margin_shortfall)Handle margin callPosition Service
MethodEndpointDescription
GET/v1/settlementsList settlement records (paginated)
GET/v1/settlements/{id}Get settlement details
POST/v1/settlements/manual-closeoutInitiate manual closeout
GET/v1/settlements/insurance-fundGet insurance fund balance
TopicDescription
risk.liquidation.trigger.v1Liquidation needed (from Position Service)
risk.liquidation.v1Liquidation confirmed (from Risk Service)
risk.margin_call.v1Margin call (from Risk Service)
engine.event.v1Liquidation order fill events
TopicDescription
settlement.initiated.v1Settlement process started
settlement.completed.v1Settlement completed (position closed)
settlement.failed.v1Settlement failed (requires manual intervention)
settlement.adl.triggered.v1Auto-deleveraging activated
settlement.insurance.used.v1Insurance fund used to cover shortfall
  1. Receive risk.liquidation.trigger.v1 for (user_id, symbol)
  2. Create settlement_records row (status = initiated)
  3. Compute bankruptcy price from position data
  4. Create liquidation order: IOC sell (for longs) or IOC buy (for shorts) at bankruptcy price
  5. Submit order via Order Service gRPC → CreateOrder(system_liquidation_order)
  6. Order flows through normal pipeline: Order Service → Matching Engine
  7. Create liquidation_orders row tracking the order
  8. Update status to pending_fill
  1. Consume engine.event.v1 matching the liquidation order
  2. Update liquidation_orders.status and settlement_records.filled_qty
  3. If fully filled:
    • Calculate shortfall: fill_price vs bankruptcy_price
    • If no shortfall: complete settlement
    • If shortfall: trigger insurance fund / ADL
  4. If partially filled: keep monitoring, may submit additional orders
  5. Emit settlement.completed.v1

If liquidation order fills at a price worse than bankruptcy:

  1. Insurance Fund First: Draw from insurance fund to cover shortfall
  2. ADL Second: If insurance fund insufficient:
    • Identify most profitable counterparties on the opposite side
    • Force-reduce their positions proportionally (Auto-Deleveraging)
    • Create settlement records for ADL participants
  3. Emit settlement.adl.triggered.v1
  1. Receive risk.margin_call.v1
  2. Notify user (via Notification Service)
  3. Start grace period timer (e.g., 30 minutes)
  4. During grace period: monitor if user adds margin or reduces position
  5. If margin restored: cancel margin call
  6. If grace period expires without resolution: escalate to liquidation
  • Settlement keyed by (user_id, symbol, settlement_cycle_timestamp)
  • Prevents duplicate liquidation for the same position in the same cycle
  • If settlement already in progress: skip new trigger
  • ❌ Directly modify positions or position tables
  • ❌ Directly modify wallet balances
  • ❌ Directly modify order books
  • ❌ Bypass the Order Service → Matching Engine pipeline
  • ❌ Execute market orders (uses IOC limit at bankruptcy price)
  • ✅ Routes liquidation orders through the normal Order → Matching pipeline
  • ✅ Records every action in settlement_records with full audit trail
  • ✅ Uses insurance fund before ADL
  • ✅ Notifies users before and after liquidation
  • ✅ Requires manual intervention for failed settlements
MetricTarget
Liquidation order submission (p95)< 500 ms after trigger
Settlement completion (p95)< 5 seconds
Insurance fund accuracy100%
ADL fairness (proportional to profit)100%
Settlement record completeness100%
VariableDescriptionDefault
POSTGRES_URLPostgreSQL connection stringRequired
KAFKA_BROKERSKafka broker addressesRequired
ORDER_SERVICE_GRPC_URLOrder Service gRPC endpointRequired
WALLET_SERVICE_GRPC_URLWallet Service gRPC endpointRequired
MARGIN_CALL_GRACE_PERIOD_MINGrace period before liquidation30
INSURANCE_FUND_MIN_BALANCEMinimum insurance fund balanceConfigurable