1use serde::{Deserialize, Serialize};
2use std::collections::BTreeMap;
3use std::fmt;
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
6pub struct Level {
7 pub price: u64,
9 pub pqty: u64,
11 pub cqty: u64,
13}
14
15impl fmt::Display for Level {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 write!(f, "Level(price: {}, pqty: {}, cqty: {})", self.price, self.pqty, self.cqty)
18 }
19}
20
21fn format_levels(levels: &[Level]) -> String {
23 if levels.is_empty() {
24 return "[]".to_string();
25 }
26 let formatted: Vec<String> = levels.iter()
27 .map(|level| format!("{}", level))
28 .collect();
29 format!("[{}]", formatted.join(", "))
30}
31
32#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
33pub struct PriceNode {
34 pub prev: Option<u64>,
35 pub next: Option<u64>,
36}
37
38#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
39pub struct L2 {
40 pub bid_price_head: Option<u64>,
42 pub ask_price_head: Option<u64>,
44 pub bid_price_tail: Option<u64>,
46 pub ask_price_tail: Option<u64>,
48 pub bid_price_nodes: BTreeMap<u64, PriceNode>,
50 pub ask_price_nodes: BTreeMap<u64, PriceNode>,
52 pub public_bid_level_map: BTreeMap<u64, u64>,
54 pub public_ask_level_map: BTreeMap<u64, u64>,
56 pub current_bid_level_map: BTreeMap<u64, u64>,
58 pub current_ask_level_map: BTreeMap<u64, u64>,
60 pub bid_level_list: BTreeMap<u64, Vec<Level>>,
64 pub ask_level_list: BTreeMap<u64, Vec<Level>>,
68}
69
70#[derive(Debug, thiserror::Error, PartialEq, Eq)]
71pub enum L2Error {
72 #[error("price is zero in L2 orderbook level")]
73 PriceIsZero,
74 #[error("price is missing in L2 orderbook level: {price} isBid: {is_bid} isPlaced: {is_placed}")]
75 PriceMissing { price: u64, is_bid: bool, is_placed: bool },
76 #[error("failed to set bid level: {price} {level}")]
77 FailedToSetBidLevel { price: u64, level: u64 },
78 #[error("failed to set ask level: {price} {level}")]
79 FailedToSetAskLevel { price: u64, level: u64 },
80 #[error("failed to set bid levels: scale={scale}, levels={}", format_levels(&levels))]
81 FailedToSetBidLevels { scale: u64, levels: Vec<Level> },
82 #[error("failed to set ask levels: scale={scale}, levels={}", format_levels(&levels))]
83 FailedToSetAskLevels { scale: u64, levels: Vec<Level> },
84}
85
86impl L2 {
87 pub fn new() -> Self {
88 Self {
89 bid_price_head: None,
90 bid_price_tail: None,
91 ask_price_head: None,
92 ask_price_tail: None,
93 bid_price_nodes: BTreeMap::new(),
94 ask_price_nodes: BTreeMap::new(),
95 public_bid_level_map: BTreeMap::new(),
96 public_ask_level_map: BTreeMap::new(),
97 current_bid_level_map: BTreeMap::new(),
98 current_ask_level_map: BTreeMap::new(),
99 bid_level_list: BTreeMap::new(),
100 ask_level_list: BTreeMap::new(),
101 }
102 }
103
104 fn ensure_price(price: u64) -> Result<(), L2Error> {
105 if price == 0 {
106 Err(L2Error::PriceIsZero)
107 } else {
108 Ok(())
109 }
110 }
111
112 pub fn bid_head(&self) -> Option<u64> {
113 self.bid_price_head
114 }
115
116 pub fn ask_head(&self) -> Option<u64> {
117 self.ask_price_head
118 }
119
120 pub fn public_bid_level(&self, price: u64) -> Option<u64> {
121 self.public_bid_level_map.get(&price).copied()
122 }
123
124 pub fn public_ask_level(&self, price: u64) -> Option<u64> {
125 self.public_ask_level_map.get(&price).copied()
126 }
127
128 pub fn current_bid_level(&self, price: u64) -> Option<u64> {
129 self.current_bid_level_map.get(&price).copied()
130 }
131
132 pub fn current_ask_level(&self, price: u64) -> Option<u64> {
133 self.current_ask_level_map.get(&price).copied()
134 }
135
136 pub fn bid_levels(&self, scale: u64) -> &Vec<Level> {
137 &self.bid_level_list.get(&scale).unwrap()
138 }
139
140 pub fn ask_levels(&self, scale: u64) -> &Vec<Level> {
141 &self.ask_level_list.get(&scale).unwrap()
142 }
143
144 pub fn scale_bid_levels(&self, scale: u64, n: u32) -> Vec<Level> {
145 let levels = self.bid_level_list.get(&scale).cloned().unwrap_or(Vec::new());
146 levels.iter().take(n as usize).cloned().collect()
147 }
148
149 pub fn scale_ask_levels(&self, scale: u64, n: u32) -> Vec<Level> {
150 let levels = self.ask_level_list.get(&scale).cloned().unwrap_or(Vec::new());
151 levels.iter().take(n as usize).cloned().collect()
152 }
153
154 pub fn set_current_bid_level(&mut self, price: u64, level: u64) -> Result<(), L2Error> {
155 self.current_bid_level_map.insert(price, level);
156 Ok(())
157 }
158
159 pub fn set_current_ask_level(&mut self, price: u64, level: u64) -> Result<(), L2Error> {
160 self.current_ask_level_map.insert(price, level);
161 Ok(())
162 }
163
164 pub fn set_public_bid_level(&mut self, price: u64, level: u64) -> Result<(), L2Error> {
165 self.public_bid_level_map.insert(price, level);
166 Ok(())
167 }
168
169 pub fn set_public_ask_level(&mut self, price: u64, level: u64) -> Result<(), L2Error> {
170 self.public_ask_level_map.insert(price, level);
171 Ok(())
172 }
173
174 pub fn set_bid_levels(&mut self, scale: u64, levels: Vec<Level>) -> Result<(), L2Error> {
175 self.bid_level_list.insert(scale, levels);
176 Ok(())
177 }
178
179 pub fn set_ask_levels(&mut self, scale: u64, levels: Vec<Level>) -> Result<(), L2Error> {
180 self.ask_level_list.insert(scale, levels);
181 Ok(())
182 }
183
184 pub fn clear_head(&mut self, is_bid: bool) -> Result<Option<u64>, L2Error> {
185 if is_bid {
186 let old_head = self.bid_price_head.unwrap();
187 if self.bid_price_nodes.get(&old_head).and_then(|node| node.next).is_none() {
190 self.bid_price_head = None;
191 self.bid_price_tail = None;
192 }
193 else {
194 self.bid_price_head = self.bid_price_nodes.get(&old_head).and_then(|node| node.next);
195 }
196 self.bid_price_nodes.remove(&old_head);
198 Ok(self.bid_price_head)
199 } else {
200 let old_head = self.ask_price_head.unwrap();
201 if self.ask_price_nodes.get(&old_head).and_then(|node| node.next).is_none() {
204 self.ask_price_head = None;
205 self.ask_price_tail = None;
206 }
207 else {
208 self.ask_price_head = self.ask_price_nodes.get(&old_head).and_then(|node| node.next);
209 }
210 self.ask_price_nodes.remove(&old_head);
212 Ok(self.ask_price_head)
213 }
214 }
215
216 pub fn price_exists(&self, is_bid: bool, price: u64) -> bool {
217 if is_bid {
218 self.bid_price_nodes.contains_key(&price)
219 }
220 else {
221 self.ask_price_nodes.contains_key(&price)
222 }
223 }
224
225 pub fn insert_price(&mut self, is_bid: bool, price: u64) -> Result<(), L2Error> {
226 if is_bid {
227 let _ = self._insert_bid_price(price)?;
228 self.set_public_bid_level(price, 0)?;
229 self.set_current_bid_level(price, 0)?;
230 Ok(())
231 }
232 else {
233 let _ = self._insert_ask_price(price)?;
234 self.set_public_ask_level(price, 0)?;
235 self.set_current_ask_level(price, 0)?;
236 Ok(())
237 }
238 }
239
240 fn _insert_bid_price(&mut self, price: u64) -> Result<(), L2Error> {
243 Self::ensure_price(price)?;
244 if self.bid_price_head == None {
246 self.bid_price_head = Some(price);
247 self.bid_price_tail = Some(price);
249 self.bid_price_nodes.insert(price, PriceNode {
251 prev: None,
252 next: None,
253 });
254 return Ok(());
255 }
256 else if price > self.bid_price_head.unwrap() {
257 let old_head = self.bid_price_head.unwrap();
258 self.bid_price_head = Some(price);
259 self.bid_price_nodes.get_mut(&old_head).map(|node| node.prev = Some(price));
261 self.bid_price_nodes.insert(price, PriceNode {
263 prev: None,
264 next: Some(old_head),
265 });
266 return Ok(());
267 }
268 else if price == self.bid_price_head.unwrap() {
269 return Ok(());
270 }
271 else {
272 let mut current = self.bid_price_head;
274 while current.is_some() {
275 let next = self.bid_price_nodes.get(¤t.unwrap()).and_then(|node| node.next);
276 if next.is_none() {
278 let curr = current.unwrap();
280 self.bid_price_nodes.get_mut(&curr).map(|node| node.next = Some(price));
281 self.bid_price_nodes.insert(price, PriceNode {
283 prev: Some(curr),
284 next: None,
285 });
286 self.bid_price_tail = Some(price);
288 return Ok(());
289 }
290 else {
291 let next_val = next.unwrap();
293 if next_val > price {
294 current = Some(next_val);
296 }
297 else if next_val < price {
298 let curr = current.unwrap();
300 self.bid_price_nodes.get_mut(&curr).map(|node| node.next = Some(price));
302 self.bid_price_nodes.get_mut(&next_val).map(|node| node.prev = Some(price));
304 self.bid_price_nodes.insert(price, PriceNode {
306 prev: Some(curr),
307 next: Some(next_val),
308 });
309 return Ok(());
310 }
311 }
312 }
313 return Ok(());
314 }
315 }
316
317 fn _insert_ask_price(&mut self, price: u64) -> Result<(), L2Error> {
320 Self::ensure_price(price)?;
321 if self.ask_price_head == None {
323 self.ask_price_head = Some(price);
324 self.ask_price_tail = Some(price);
326 self.ask_price_nodes.insert(price, PriceNode {
328 prev: None,
329 next: None,
330 });
331 return Ok(());
332 }
333 else if price < self.ask_price_head.unwrap() {
334 let old_head = self.ask_price_head.unwrap();
335 self.ask_price_head = Some(price);
336 self.ask_price_nodes.get_mut(&old_head).map(|node| node.prev = Some(price));
338 self.ask_price_nodes.insert(price, PriceNode {
340 prev: None,
341 next: Some(old_head),
342 });
343 return Ok(());
344 }
345 else if price == self.ask_price_head.unwrap() {
346 return Ok(());
347 }
348 else {
349 let mut current = self.ask_price_head;
351 while current.is_some() {
352 let next = self.ask_price_nodes.get(¤t.unwrap()).and_then(|node| node.next);
353 if next.is_none() {
355 let curr = current.unwrap();
357 self.ask_price_nodes.get_mut(&curr).map(|node| node.next = Some(price));
359 self.ask_price_nodes.insert(price, PriceNode {
361 prev: Some(curr),
362 next: None,
363 });
364 self.ask_price_tail = Some(price);
366 return Ok(());
367 }
368 else {
369 let next_val = next.unwrap();
371 if next_val < price {
372 current = Some(next_val);
374 }
375 else if next_val > price {
376 let curr = current.unwrap();
378 self.ask_price_nodes.get_mut(&curr).map(|node| node.next = Some(price));
380 self.ask_price_nodes.get_mut(&next_val).map(|node| node.prev = Some(price));
382 self.ask_price_nodes.insert(price, PriceNode {
384 prev: Some(curr),
385 next: Some(next_val),
386 });
387 return Ok(());
388 }
389 else {
390 break;
391 }
392 }
393 }
394 return Ok(());
395 }
396 }
397
398 pub fn remove_price(&mut self, is_bid: bool, price: u64) -> Result<(), L2Error> {
400 if is_bid {
401 self._remove_bid_price(price)?;
402 self.public_bid_level_map.remove(&price);
404 self.current_bid_level_map.remove(&price);
405 Ok(())
406 }
407 else {
408 self._remove_ask_price(price)?;
409 self.public_ask_level_map.remove(&price);
411 self.current_ask_level_map.remove(&price);
412 Ok(())
413 }
414 }
415 fn _remove_bid_price(&mut self, price: u64) -> Result<(), L2Error> {
417 let node = match self.bid_price_nodes.get(&price) {
419 Some(node) => node.clone(),
420 None => return Ok(()), };
422
423 if let Some(prev_price) = node.prev {
425 if let Some(prev_node) = self.bid_price_nodes.get_mut(&prev_price) {
426 prev_node.next = node.next;
427 }
428 } else {
429 self.bid_price_head = node.next;
431 }
432
433 if let Some(next_price) = node.next {
435 if let Some(next_node) = self.bid_price_nodes.get_mut(&next_price) {
436 next_node.prev = node.prev;
437 }
438 } else {
439 self.bid_price_tail = node.prev;
441 }
442
443 self.bid_price_nodes.remove(&price);
445
446 self.public_bid_level_map.remove(&price);
448 self.current_bid_level_map.remove(&price);
449
450 Ok(())
451 }
452
453 fn _remove_ask_price(&mut self, price: u64) -> Result<(), L2Error> {
455 let node = match self.ask_price_nodes.get(&price) {
457 Some(node) => node.clone(),
458 None => return Ok(()), };
460
461 if let Some(prev_price) = node.prev {
463 if let Some(prev_node) = self.ask_price_nodes.get_mut(&prev_price) {
464 prev_node.next = node.next;
465 }
466 } else {
467 self.ask_price_head = node.next;
469 }
470
471 if let Some(next_price) = node.next {
473 if let Some(next_node) = self.ask_price_nodes.get_mut(&next_price) {
474 next_node.prev = node.prev;
475 }
476 } else {
477 self.ask_price_tail = node.prev;
479 }
480
481 self.ask_price_nodes.remove(&price);
483
484 self.public_ask_level_map.remove(&price);
486 self.current_ask_level_map.remove(&price);
487
488 Ok(())
489 }
490
491 pub fn collect_bid_prices(&self) -> Vec<u64> {
493 let mut prices = Vec::new();
494 let mut current = self.bid_price_head;
495 while let Some(price) = current {
496 prices.push(price);
497 current = self.bid_price_nodes.get(&price).and_then(|node| node.next);
498 }
499 prices
500 }
501
502 pub fn collect_ask_prices(&self) -> Vec<u64> {
504 let mut prices = Vec::new();
505 let mut current = self.ask_price_head;
506 while let Some(price) = current {
507 prices.push(price);
508 current = self.ask_price_nodes.get(&price).and_then(|node| node.next);
509 }
510 prices
511 }
512
513 fn format_8_decimals(value: u64) -> String {
516 const DECIMAL_PLACES: u64 = 100_000_000; let integer_part = value / DECIMAL_PLACES;
519 let decimal_part = value % DECIMAL_PLACES;
520
521 format!("{}.{:08}", integer_part, decimal_part)
522 }
523
524 pub fn get_snapshot_raw(&self, is_bid: bool, scale: u64, step: u32) -> Result<Vec<Vec<u64>>, L2Error> {
528 let levels_map = if is_bid {
530 &self.bid_level_list
531 } else {
532 &self.ask_level_list
533 };
534
535 let levels = levels_map.get(&scale).cloned().unwrap_or_default();
537
538 let snapshot: Vec<Vec<u64>> = levels
540 .iter()
541 .take(step as usize)
542 .map(|level| {
543 vec![
544 level.price, level.pqty, level.cqty, ]
548 })
549 .collect();
550
551 Ok(snapshot)
552 }
553
554 pub fn get_snapshot(&self, is_bid: bool, scale: u64, step: u32) -> Result<Vec<Vec<String>>, L2Error> {
559 let raw_snapshot = self.get_snapshot_raw(is_bid, scale, step)?;
561
562 let snapshot: Vec<Vec<String>> = raw_snapshot
564 .iter()
565 .map(|level| {
566 vec![
567 Self::format_8_decimals(level[0]), Self::format_8_decimals(level[1]), Self::format_8_decimals(level[2]), ]
571 })
572 .collect();
573
574 Ok(snapshot)
575 }
576}