nautilus_model/orderbook/
display.rs
1use tabled::{Table, Tabled, settings::Style};
19
20use super::{
21 BookLevel, BookPrice,
22 own::{OwnBookLadder, OwnBookLevel},
23};
24use crate::orderbook::ladder::BookLadder;
25
26#[derive(Tabled)]
27struct BookLevelDisplay {
28 bids: String,
29 price: String,
30 asks: String,
31}
32
33#[must_use]
35pub(crate) fn pprint_book(bids: &BookLadder, asks: &BookLadder, num_levels: usize) -> String {
36 let ask_levels: Vec<(&BookPrice, &BookLevel)> =
37 asks.levels.iter().take(num_levels).rev().collect();
38 let bid_levels: Vec<(&BookPrice, &BookLevel)> = bids.levels.iter().take(num_levels).collect();
39 let levels: Vec<(&BookPrice, &BookLevel)> = ask_levels.into_iter().chain(bid_levels).collect();
40
41 let data: Vec<BookLevelDisplay> = levels
42 .iter()
43 .map(|(book_price, level)| {
44 let is_bid_level = bids.levels.contains_key(book_price);
45 let is_ask_level = asks.levels.contains_key(book_price);
46
47 let bid_sizes: Vec<String> = level
48 .orders
49 .iter()
50 .filter(|_| is_bid_level)
51 .map(|order| format!("{}", order.1.size))
52 .collect();
53
54 let ask_sizes: Vec<String> = level
55 .orders
56 .iter()
57 .filter(|_| is_ask_level)
58 .map(|order| format!("{}", order.1.size))
59 .collect();
60
61 BookLevelDisplay {
62 bids: if bid_sizes.is_empty() {
63 String::new()
64 } else {
65 format!("[{}]", bid_sizes.join(", "))
66 },
67 price: format!("{}", level.price),
68 asks: if ask_sizes.is_empty() {
69 String::new()
70 } else {
71 format!("[{}]", ask_sizes.join(", "))
72 },
73 }
74 })
75 .collect();
76
77 Table::new(data).with(Style::rounded()).to_string()
78}
79
80#[must_use]
83pub(crate) fn pprint_own_book(
84 bids: &OwnBookLadder,
85 asks: &OwnBookLadder,
86 num_levels: usize,
87) -> String {
88 let ask_levels: Vec<(&BookPrice, &OwnBookLevel)> =
89 asks.levels.iter().take(num_levels).rev().collect();
90 let bid_levels: Vec<(&BookPrice, &OwnBookLevel)> =
91 bids.levels.iter().take(num_levels).collect();
92 let levels: Vec<(&BookPrice, &OwnBookLevel)> =
93 ask_levels.into_iter().chain(bid_levels).collect();
94
95 let data: Vec<BookLevelDisplay> = levels
96 .iter()
97 .map(|(book_price, level)| {
98 let is_bid_level = bids.levels.contains_key(book_price);
99 let is_ask_level = asks.levels.contains_key(book_price);
100
101 let bid_sizes: Vec<String> = level
102 .orders
103 .iter()
104 .filter(|_| is_bid_level)
105 .map(|order| format!("{}", order.1.size))
106 .collect();
107
108 let ask_sizes: Vec<String> = level
109 .orders
110 .iter()
111 .filter(|_| is_ask_level)
112 .map(|order| format!("{}", order.1.size))
113 .collect();
114
115 BookLevelDisplay {
116 bids: if bid_sizes.is_empty() {
117 String::new()
118 } else {
119 format!("[{}]", bid_sizes.join(", "))
120 },
121 price: format!("{}", level.price),
122 asks: if ask_sizes.is_empty() {
123 String::new()
124 } else {
125 format!("[{}]", ask_sizes.join(", "))
126 },
127 }
128 })
129 .collect();
130
131 Table::new(data).with(Style::rounded()).to_string()
132}