rusty_feeder/exchange/binance/futures/data/
trade.rs

1//! Trade message types for Binance Futures WebSocket API
2//!
3//! This module provides optimized data structures for processing
4//! trade messages from Binance Futures WebSocket streams.
5
6use rust_decimal::Decimal;
7use rust_decimal_macros::dec;
8use serde::{Deserialize, Serialize};
9use smartstring::alias::String;
10
11/// Aggregate trade message from Binance Futures WebSocket
12#[derive(Debug, Clone, Serialize, Deserialize)]
13#[repr(align(16))] // Align for better memory access
14pub struct AggTradeMessage {
15    /// Event type
16    #[serde(rename = "e")]
17    pub event_type: String,
18
19    /// Event time
20    #[serde(rename = "E")]
21    pub event_time: u64,
22
23    /// Symbol
24    #[serde(rename = "s")]
25    pub symbol: String,
26
27    /// Aggregate trade ID
28    #[serde(rename = "a")]
29    pub agg_trade_id: u64,
30
31    /// Price
32    #[serde(rename = "p")]
33    pub price: String,
34
35    /// Quantity
36    #[serde(rename = "q")]
37    pub quantity: String,
38
39    /// First trade ID
40    #[serde(rename = "f")]
41    pub first_trade_id: u64,
42
43    /// Last trade ID
44    #[serde(rename = "l")]
45    pub last_trade_id: u64,
46
47    /// Trade time
48    #[serde(rename = "T")]
49    pub trade_time: u64,
50
51    /// Is the buyer the market maker?
52    #[serde(rename = "m")]
53    pub is_buyer_market_maker: bool,
54}
55
56/// Parsed aggregate trade data with Decimal values
57#[derive(Debug, Clone)]
58#[repr(align(16))] // Align for better memory access
59pub struct ParsedAggTradeData {
60    /// Symbol
61    pub symbol: String,
62
63    /// Aggregate trade ID
64    pub agg_trade_id: u64,
65
66    /// Price
67    pub price: Decimal,
68
69    /// Quantity
70    pub quantity: Decimal,
71
72    /// Buy or sell side (true for maker is buyer)
73    pub is_buyer_market_maker: bool,
74
75    /// Trade timestamp
76    pub trade_time: u64,
77
78    /// Event timestamp (when message was generated)
79    pub event_time: u64,
80}
81
82impl From<AggTradeMessage> for ParsedAggTradeData {
83    fn from(msg: AggTradeMessage) -> Self {
84        ParsedAggTradeData {
85            symbol: msg.symbol,
86            agg_trade_id: msg.agg_trade_id,
87            price: msg.price.parse().unwrap_or(dec!(0)),
88            quantity: msg.quantity.parse().unwrap_or(dec!(0)),
89            is_buyer_market_maker: msg.is_buyer_market_maker,
90            trade_time: msg.trade_time,
91            event_time: msg.event_time,
92        }
93    }
94}
95
96/// Liquidation order message from Binance Futures WebSocket
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct LiquidationOrderMessage {
99    /// Event type
100    #[serde(rename = "e")]
101    pub event_type: String,
102
103    /// Event time
104    #[serde(rename = "E")]
105    pub event_time: u64,
106
107    /// Liquidation order
108    #[serde(rename = "o")]
109    pub order: LiquidationOrder,
110}
111
112/// Liquidation order data
113#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct LiquidationOrder {
115    /// Symbol
116    #[serde(rename = "s")]
117    pub symbol: String,
118
119    /// Side ("BUY" or "SELL")
120    #[serde(rename = "S")]
121    pub side: String,
122
123    /// Order type
124    #[serde(rename = "o")]
125    pub order_type: String,
126
127    /// Time in force
128    #[serde(rename = "f")]
129    pub time_in_force: String,
130
131    /// Original quantity
132    #[serde(rename = "q")]
133    pub quantity: String,
134
135    /// Price
136    #[serde(rename = "p")]
137    pub price: String,
138
139    /// Average price
140    #[serde(rename = "ap")]
141    pub avg_price: String,
142
143    /// Order status
144    #[serde(rename = "X")]
145    pub status: String,
146
147    /// Last filled quantity
148    #[serde(rename = "l")]
149    pub last_filled_quantity: String,
150
151    /// Order last filled price
152    #[serde(rename = "z")]
153    pub last_filled_price: String,
154
155    /// Order filled accumulated quantity
156    #[serde(rename = "L")]
157    pub filled_accumulated_quantity: String,
158
159    /// Order trade time
160    #[serde(rename = "T")]
161    pub trade_time: u64,
162}
163
164/// Parsed liquidation order data with Decimal values
165#[derive(Debug, Clone)]
166#[repr(align(16))] // Align for better memory access
167pub struct ParsedLiquidationOrder {
168    /// Symbol
169    pub symbol: String,
170
171    /// Side (Buy or Sell)
172    pub side: String,
173
174    /// Price
175    pub price: Decimal,
176
177    /// Quantity
178    pub quantity: Decimal,
179
180    /// Trade timestamp
181    pub trade_time: u64,
182
183    /// Event timestamp (when message was generated)
184    pub event_time: u64,
185}
186
187impl From<LiquidationOrderMessage> for ParsedLiquidationOrder {
188    fn from(msg: LiquidationOrderMessage) -> Self {
189        ParsedLiquidationOrder {
190            symbol: msg.order.symbol,
191            side: msg.order.side,
192            price: msg.order.price.parse().unwrap_or(dec!(0)),
193            quantity: msg.order.quantity.parse().unwrap_or(dec!(0)),
194            trade_time: msg.order.trade_time,
195            event_time: msg.event_time,
196        }
197    }
198}