rusty_ems/exchanges/coinbase/models.rs
1//! Data models for Coinbase Advanced Trading API responses.
2//!
3//! This module contains the data structures used to deserialize responses from the
4//! Coinbase Advanced Trading API WebSocket and REST endpoints. These models are
5//! designed for high-performance parsing with minimal allocations.
6//!
7//! # Key Model Types
8//!
9//! - [`L2Snapshot`] - Complete order book snapshot
10//! - [`L2Update`] - Incremental order book updates
11//! - [`TradeMatch`] - Completed trade information
12//!
13//! # Performance Considerations
14//!
15//! All models use `String` types for decimal values to maintain precision
16//! and avoid floating-point errors. In performance-critical paths, consider
17//! using `SmartString` or `rust_decimal::Decimal` for better memory efficiency.
18//!
19//! # Data Sources
20//!
21//! These models correspond to the following Coinbase WebSocket channels:
22//! - `level2` - L2 order book data
23//! - `matches` - Trade execution data
24
25use serde::Deserialize;
26
27/// Level 2 (L2) order book snapshot from Coinbase Advanced Trading API.
28///
29/// This structure represents a complete snapshot of the order book for a specific product,
30/// containing all current bid and ask levels. Each level includes price and size information.
31///
32/// # WebSocket Channel
33/// This data is received via the `level2` channel subscription.
34///
35/// # Performance Notes
36/// - Uses `String` for flexibility with decimal parsing
37/// - Consider using `SmallString` for better performance in hot paths
38/// - Arrays are used for bids/asks to maintain order and minimize allocations
39#[derive(Debug, Deserialize)]
40pub struct L2Snapshot {
41 /// The trading pair identifier (e.g., "BTC-USD", "ETH-USD")
42 pub product_id: String,
43 /// Current bid levels as [price, size] pairs, ordered from highest to lowest price
44 pub bids: Vec<[String; 2]>,
45 /// Current ask levels as [price, size] pairs, ordered from lowest to highest price
46 pub asks: Vec<[String; 2]>,
47}
48
49/// Level 2 (L2) order book update from Coinbase Advanced Trading API.
50///
51/// This structure represents incremental changes to the order book that should be applied
52/// to maintain a real-time view of the market depth. Updates can include new orders,
53/// order cancellations, or order modifications.
54///
55/// # WebSocket Channel
56/// This data is received via the `level2` channel subscription.
57///
58/// # Update Processing
59/// Changes should be applied in sequence order to maintain book integrity.
60/// A size of "0" indicates the price level should be removed from the book.
61#[derive(Debug, Deserialize)]
62pub struct L2Update {
63 /// The trading pair identifier (e.g., "BTC-USD", "ETH-USD")
64 pub product_id: String,
65 /// ISO 8601 timestamp when the update occurred
66 pub time: String,
67 /// Array of changes as [side, price, size] tuples
68 /// - side: "buy" or "sell" indicating bid or ask side
69 /// - price: The price level being updated
70 /// - size: The new size at this price level ("0" means remove the level)
71 pub changes: Vec<[String; 3]>,
72}
73
74/// Trade match event from Coinbase Advanced Trading API.
75///
76/// This structure represents a completed trade (match) between two orders on the exchange.
77/// It contains comprehensive information about the trade including the maker/taker orders,
78/// execution price, size, and timing.
79///
80/// # WebSocket Channel
81/// This data is received via the `matches` channel subscription.
82///
83/// # Trade Direction
84/// The `side` field indicates the taker's side:
85/// - "buy": Taker bought (aggressive buy, price moved up)
86/// - "sell": Taker sold (aggressive sell, price moved down)
87#[derive(Debug, Deserialize)]
88pub struct TradeMatch {
89 /// Message type identifier, typically "match"
90 #[serde(rename = "type")]
91 pub type_field: String,
92 /// Unique identifier for this trade
93 pub trade_id: i64,
94 /// Sequence number for ordering events
95 pub sequence: i64,
96 /// Order ID of the maker (passive order already in the book)
97 pub maker_order_id: String,
98 /// Order ID of the taker (aggressive order that caused the match)
99 pub taker_order_id: String,
100 /// ISO 8601 timestamp when the trade occurred
101 pub time: String,
102 /// The trading pair identifier (e.g., "BTC-USD", "ETH-USD")
103 pub product_id: String,
104 /// The quantity of the asset traded (as decimal string)
105 pub size: String,
106 /// The price at which the trade executed (as decimal string)
107 pub price: String,
108 /// The taker's side: "buy" (aggressive buy) or "sell" (aggressive sell)
109 pub side: String,
110}