rusty_feeder/exchange/bybit/data/
orderbook.rs1use rust_decimal::Decimal;
2use serde::{Deserialize, Serialize};
3use smallvec::SmallVec;
4use smartstring::alias::String;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct OrderbookResponse {
9 pub topic: String,
11 pub type_field: Option<String>,
13 pub ts: u64,
15 pub data: OrderbookData,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct OrderbookData {
22 pub symbol: String,
24 pub b: SmallVec<[[String; 2]; 32]>,
26 pub a: SmallVec<[[String; 2]; 32]>,
28 pub u: u64,
30 pub seq: u64,
32}
33
34#[derive(Debug, Clone)]
36pub struct ParsedOrderbookData {
37 pub symbol: String,
39 pub timestamp: u64,
41 pub update_id: u64,
43 pub sequence: u64,
45 pub bids: SmallVec<[(Decimal, Decimal); 16]>,
47 pub asks: SmallVec<[(Decimal, Decimal); 16]>,
49}
50
51impl ParsedOrderbookData {
52 pub fn from_response(response: &OrderbookResponse) -> Option<Self> {
54 let data = &response.data;
55
56 let bids = data
58 .b
59 .iter()
60 .filter_map(|bid| {
61 if bid.len() != 2 {
62 return None;
63 }
64
65 let price = bid[0].parse::<Decimal>().ok()?;
66 let size = bid[1].parse::<Decimal>().ok()?;
67
68 Some((price, size))
69 })
70 .collect();
71
72 let asks = data
74 .a
75 .iter()
76 .filter_map(|ask| {
77 if ask.len() != 2 {
78 return None;
79 }
80
81 let price = ask[0].parse::<Decimal>().ok()?;
82 let size = ask[1].parse::<Decimal>().ok()?;
83
84 Some((price, size))
85 })
86 .collect();
87
88 Some(Self {
89 symbol: data.symbol.clone(),
90 timestamp: response.ts,
91 update_id: data.u,
92 sequence: data.seq,
93 bids,
94 asks,
95 })
96 }
97}