/** * Order WebSocket Event Types * * TypeScript types for order websocket events matching the Rust backend definitions. * Each event type has specific data fields based on the event context. */ import type { OrderRole, OrderSide, OrderStatus, OrderType, TimeInForce, TradingMode } from "../../trading"; import type { RawEventMessage } from "../base"; /** * Order event types */ export type OrderEventType = "OrderPlaced" | "OrderMatched" | "OrderPartiallyFilled" | "OrderFilled" | "OrderCancelled" | "OrderRejected" | "OrderExpired"; /** * Base order event structure * All order events share these common fields */ export interface OrderEvent { /** Order ID (UUID) */ orderId: string; /** Event type */ eventType: OrderEventType; /** ISO 8601 timestamp */ timestamp: string; /** Event-specific data */ data: OrderEventData; } /** * Common fields shared across most order events * Note: orderId is duplicated (exists in both OrderEvent and data) to match backend structure */ export interface CommonOrderEventData { /** Order ID (UUID) - duplicated from parent for backend compatibility */ orderId: string; /** User ID (UUID) */ userId: string; /** Trading pair ID (UUID) */ tradingPairId?: string; /** Application ID (UUID) - present in several events */ applicationId?: string; /** Trading pair symbol (e.g., "BTC/USDC") */ symbol: string; /** Trading mode (e.g., "SPOT", "MARGIN") */ tradingMode: TradingMode; /** Order type - present in most events */ orderType?: OrderType; /** Order side - present in most events */ side?: OrderSide; /** Order price - present in most events */ price?: string; /** Order quantity - present in most events */ quantity?: string; /** Time in force - present in most events */ timeInForce?: TimeInForce; } /** * OrderPlaced event - emitted when a new order is placed */ export interface OrderPlacedEvent extends OrderEvent { eventType: "OrderPlaced"; data: CommonOrderEventData & { /** Order status */ status: OrderStatus; }; } /** * OrderMatched event - emitted when an order is matched but not necessarily filled * This event is only emitted for taker orders */ export interface OrderMatchedEvent extends OrderEvent { eventType: "OrderMatched"; data: CommonOrderEventData & { /** Taker order ID */ takerOrderId?: string; /** Reference price used for slippage calculation */ referencePrice?: string; /** Best price achieved in matching */ bestPrice?: string; /** Worst price achieved in matching */ worstPrice?: string; /** Actual slippage in basis points */ actualSlippageBps?: number; /** Maximum allowed slippage in basis points */ maxSlippageBps?: number; /** Number of trades executed (taker only) */ tradesCount?: number; /** Total quantity filled (taker only) */ totalFilled?: string; /** Remaining quantity to be filled (taker only) */ remainingQuantity?: string; /** Average fill price across all trades */ averageFillPrice?: string; /** Order status */ status?: OrderStatus; }; } /** * OrderPartiallyFilled event - emitted when an order is partially filled * Can be emitted for both taker and maker orders with different field sets * * Taker events include: trades_count, total_filled, slippage data * Maker events include: trade_id, execution_price, execution_quantity, maker_fee */ export interface OrderPartiallyFilledEvent extends OrderEvent { eventType: "OrderPartiallyFilled"; data: CommonOrderEventData & { /** Taker order ID (taker orders only) */ takerOrderId?: string; /** Maker order ID (maker orders only) */ makerOrderId?: string; /** Reference price (taker orders only) */ referencePrice?: string; /** Best price (taker orders only) */ bestPrice?: string; /** Worst price (taker orders only) */ worstPrice?: string; /** Actual slippage in basis points (taker orders only) */ actualSlippageBps?: number; /** Maximum slippage in basis points (taker orders only) */ maxSlippageBps?: number; /** Number of trades (taker orders only - not present for maker) */ tradesCount?: number; /** Total filled quantity (taker orders only - not present for maker) */ totalFilled?: string; /** Remaining quantity (present for both taker and maker) */ remainingQuantity?: string; /** Average fill price (taker orders only) */ averageFillPrice?: string; /** Order status (taker orders only) */ status?: OrderStatus; /** Trade ID (maker orders only) */ tradeId?: string; /** Execution price (maker orders only) */ executionPrice?: string; /** Execution quantity (maker orders only) */ executionQuantity?: string; /** Maker fee (maker orders only) */ makerFee?: string; /** Trade execution timestamp (maker orders only) */ executedAt?: string; /** Role of the order in the trade (taker or maker) */ role?: OrderRole; }; } /** * OrderFilled event - emitted when an order is completely filled * Can be emitted for both taker and maker orders with different field sets * * Taker events include: trades_count, total_filled, slippage data * Maker events include: trade_id, execution_price, execution_quantity, maker_fee */ export interface OrderFilledEvent extends OrderEvent { eventType: "OrderFilled"; data: CommonOrderEventData & { /** Taker order ID (taker orders only) */ takerOrderId?: string; /** Maker order ID (maker orders only) */ makerOrderId?: string; /** Reference price (taker orders only) */ referencePrice?: string; /** Best price (taker orders only) */ bestPrice?: string; /** Worst price (taker orders only) */ worstPrice?: string; /** Actual slippage in basis points (taker orders only) */ actualSlippageBps?: number; /** Maximum slippage in basis points (taker orders only) */ maxSlippageBps?: number; /** Number of trades (taker orders only - not present for maker) */ tradesCount?: number; /** Total filled quantity (taker orders only - not present for maker) */ totalFilled?: string; /** Remaining quantity (present for both, should be 0 for filled orders) */ remainingQuantity?: string; /** Average fill price (taker orders only) */ averageFillPrice?: string; /** Order status (taker orders only) */ status?: OrderStatus; /** Trade ID (maker orders only) */ tradeId?: string; /** Execution price (maker orders only) */ executionPrice?: string; /** Execution quantity (maker orders only) */ executionQuantity?: string; /** Maker fee (maker orders only) */ makerFee?: string; /** Trade execution timestamp (maker orders only) */ executedAt?: string; /** Role of the order in the trade (taker or maker) */ role?: OrderRole; }; } /** * OrderCancelled event - emitted when an order is canceled */ export interface OrderCancelledEvent extends OrderEvent { eventType: "OrderCancelled"; data: CommonOrderEventData & { /** Reason for cancellation */ reason?: string; /** Total filled quantity before cancellation */ totalFilled?: string; /** Remaining quantity when canceled */ remainingQuantity?: string; /** Number of trades executed before cancellation */ tradesCount?: number; }; } /** * OrderRejected event - emitted when an order is rejected */ export interface OrderRejectedEvent extends OrderEvent { eventType: "OrderRejected"; data: CommonOrderEventData & { /** Reason for rejection */ reason: string; /** Order status */ status: OrderStatus; /** Total filled quantity (may-be partially filled) */ totalFilled: string; /** Remaining quantity that couldn't be filled */ remainingQuantity: string; }; } /** * OrderExpired event - emitted when a GTC order expires */ export interface OrderExpiredEvent extends OrderEvent { eventType: "OrderExpired"; data: CommonOrderEventData & { /** Filled quantity before expiration */ filledQuantity?: string; /** Remaining quantity at expiration */ remainingQuantity?: string; /** Average fill price (if any fills occurred) */ averageFillPrice?: string; /** Reason for expiration */ reason: string; }; } /** * Union type of all possible order event data */ export type OrderEventData = OrderPlacedEvent["data"] | OrderMatchedEvent["data"] | OrderPartiallyFilledEvent["data"] | OrderFilledEvent["data"] | OrderCancelledEvent["data"] | OrderRejectedEvent["data"] | OrderExpiredEvent["data"]; /** * Subscription configuration for order events */ export interface OrderSubscriptionConfig { eventTypes: OrderEventType[]; } /** * Raw event message interface * This is the raw message received from the backend */ export type RawOrderEventMessage = RawEventMessage & { /** Event data */ data: BackendOrderEvent; }; /** * Backend order event * These will be in snake case and should match the non-camelCase types */ export interface BackendOrderEvent { /** Order ID (UUID) */ order_id: string; /** Event type */ event_type: OrderEventType; /** ISO 8601 timestamp */ timestamp: string; /** Event-specific data */ data: BackendCommonOrderEventData & unknown; } /** * Common fields shared across most order events */ export interface BackendCommonOrderEventData { /** User ID (UUID) */ user_id: string; /** Trading pair ID (UUID) */ trading_pair_id?: string; /** Trading pair symbol (e.g., "BTC/USDC") */ symbol: string; /** Trading mode (e.g., "Spot", "Margin") */ trading_mode: string; }