rusty_feeder/exchange/bybit/data/
trade.rs

1use rust_decimal::Decimal;
2use rusty_common::collections::FxHashMap;
3use serde::{Deserialize, Serialize};
4use simd_json::OwnedValue as Value;
5use smartstring::alias::String;
6
7/// Bybit WebSocket trade message
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct TradeResponse {
10    /// Topic name for the trade stream
11    pub topic: String,
12    /// List of trade data
13    pub data: Vec<TradeData>,
14    /// Server timestamp when the message was created
15    pub ts: u64,
16    /// Type field for the message (optional)
17    pub type_field: Option<String>,
18}
19
20/// Individual trade data
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct TradeData {
23    /// Trading symbol
24    pub symbol: String,
25    /// Direction of the tick ("PlusTick", "MinusTick", "ZeroTick")
26    pub tick_direction: String,
27    /// Trade price
28    pub price: Decimal,
29    /// Trade quantity
30    pub size: Decimal,
31    /// Trade timestamp as string
32    pub timestamp: String,
33    /// Trade timestamp in milliseconds
34    pub trade_time_ms: u64,
35    /// Trade side ("Buy" or "Sell")
36    pub side: String,
37    /// Unique trade identifier
38    pub trade_id: String,
39    /// Whether this is a block trade
40    #[serde(default)]
41    pub is_block_trade: bool,
42}
43
44/// Bybit REST API trade response
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct TradeHistoryResponse {
47    /// Return code (0 for success)
48    pub ret_code: i32,
49    /// Return message
50    pub ret_msg: String,
51    /// Trade history result data
52    pub result: TradeHistoryResult,
53    /// Extended information (optional)
54    pub ext_info: Option<FxHashMap<String, Value>>,
55    /// Current server time
56    pub time_now: String,
57}
58
59/// Trade history result wrapper
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct TradeHistoryResult {
62    /// List of trade data
63    pub list: Vec<TradeData>,
64}
65
66/// Bybit ping request
67#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct PingRequest {
69    /// Operation type ("ping")
70    pub op: String,
71    /// Arguments for ping request (empty)
72    pub args: Vec<String>,
73}
74
75impl Default for PingRequest {
76    fn default() -> Self {
77        Self::new()
78    }
79}
80
81impl PingRequest {
82    /// Create a new ping request
83    #[must_use]
84    pub fn new() -> Self {
85        Self {
86            op: "ping".into(),
87            args: vec![],
88        }
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use super::*;
95
96    #[test]
97    fn test_ping_request_serialization() {
98        let ping = PingRequest::new();
99        let json = simd_json::to_string(&ping).unwrap();
100        let json = String::from(&json);
101        assert_eq!(json, r#"{"op":"ping","args":[]}"#);
102    }
103}