rusty_feeder/exchange/bybit/futures/data/
trade.rs1use rust_decimal::Decimal;
7use serde::{Deserialize, Serialize};
8use smartstring::alias::String;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct TradeResponse {
13 pub topic: String,
15
16 #[serde(rename = "type")]
18 pub message_type: String,
19
20 pub ts: u64,
22
23 pub data: Vec<TradeData>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct TradeData {
30 pub symbol: String,
32
33 #[serde(rename = "tickDirection")]
35 pub tick_direction: String,
36
37 pub price: String,
39
40 pub size: String,
42
43 pub timestamp: String,
45
46 #[serde(rename = "tradeId")]
48 pub trade_id: String,
49
50 pub side: String,
52}
53
54impl TradeResponse {
56 pub fn price_decimal(&self) -> Option<Decimal> {
58 self.data.first().and_then(|trade| trade.price.parse().ok())
59 }
60
61 pub fn size_decimal(&self) -> Option<Decimal> {
63 self.data.first().and_then(|trade| trade.size.parse().ok())
64 }
65
66 pub fn symbol(&self) -> Option<&str> {
68 self.data.first().map(|trade| trade.symbol.as_str())
69 }
70
71 pub const fn timestamp_ns(&self) -> u64 {
73 self.ts * 1_000_000
75 }
76
77 pub fn is_buy(&self) -> Option<bool> {
79 self.data
80 .first()
81 .map(|trade| trade.side.to_lowercase() == "buy")
82 }
83}
84
85#[derive(Debug, Serialize, Deserialize)]
87pub struct PingRequest {
88 pub op: String,
90
91 pub args: Vec<String>,
93}
94
95impl Default for PingRequest {
96 fn default() -> Self {
97 Self::new()
98 }
99}
100
101impl PingRequest {
102 #[must_use]
104 pub fn new() -> Self {
105 Self {
106 op: "ping".into(),
107 args: vec![],
108 }
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115
116 #[test]
117 fn test_ping_request_serialization() {
118 let ping = PingRequest::new();
119 let json = simd_json::to_string(&ping).unwrap();
120 let json = String::from(&json);
121 assert_eq!(json, r#"{"op":"ping","args":[]}"#);
122 }
123}