nautilus_model/orderbook/
display.rs1use tabled::{settings::Style, Table, Tabled};
19
20use super::{BookLevel, BookPrice};
21use crate::orderbook::ladder::BookLadder;
22
23#[derive(Tabled)]
24struct BookLevelDisplay {
25 bids: String,
26 price: String,
27 asks: String,
28}
29
30#[must_use]
32pub(crate) fn pprint_book(bids: &BookLadder, asks: &BookLadder, num_levels: usize) -> String {
33 let ask_levels: Vec<(&BookPrice, &BookLevel)> =
34 asks.levels.iter().take(num_levels).rev().collect();
35 let bid_levels: Vec<(&BookPrice, &BookLevel)> = bids.levels.iter().take(num_levels).collect();
36 let levels: Vec<(&BookPrice, &BookLevel)> = ask_levels.into_iter().chain(bid_levels).collect();
37
38 let data: Vec<BookLevelDisplay> = levels
39 .iter()
40 .map(|(book_price, level)| {
41 let is_bid_level = bids.levels.contains_key(book_price);
42 let is_ask_level = asks.levels.contains_key(book_price);
43
44 let bid_sizes: Vec<String> = level
45 .orders
46 .iter()
47 .filter(|_| is_bid_level)
48 .map(|order| format!("{}", order.1.size))
49 .collect();
50
51 let ask_sizes: Vec<String> = level
52 .orders
53 .iter()
54 .filter(|_| is_ask_level)
55 .map(|order| format!("{}", order.1.size))
56 .collect();
57
58 BookLevelDisplay {
59 bids: if bid_sizes.is_empty() {
60 String::new()
61 } else {
62 format!("[{}]", bid_sizes.join(", "))
63 },
64 price: format!("{}", level.price),
65 asks: if ask_sizes.is_empty() {
66 String::new()
67 } else {
68 format!("[{}]", ask_sizes.join(", "))
69 },
70 }
71 })
72 .collect();
73
74 Table::new(data).with(Style::rounded()).to_string()
75}