1use super::QueueEntry;
2use crate::{OrderId, Quantity, RestingLimitOrder, SequenceNumber};
3
4use std::collections::{HashMap, VecDeque};
5
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[derive(Debug, Clone)]
10pub struct PriceLevel {
11 pub(crate) visible_quantity: Quantity,
13 pub(crate) hidden_quantity: Quantity,
15 order_count: u64,
17 queue: VecDeque<QueueEntry>,
19}
20
21impl Default for PriceLevel {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl PriceLevel {
28 pub fn new() -> Self {
30 Self {
31 visible_quantity: Quantity(0),
32 hidden_quantity: Quantity(0),
33 order_count: 0,
34 queue: VecDeque::new(),
35 }
36 }
37
38 pub fn visible_quantity(&self) -> Quantity {
40 self.visible_quantity
41 }
42
43 pub fn hidden_quantity(&self) -> Quantity {
45 self.hidden_quantity
46 }
47
48 pub fn total_quantity(&self) -> Quantity {
50 self.visible_quantity + self.hidden_quantity
51 }
52
53 pub fn order_count(&self) -> u64 {
55 self.order_count
56 }
57
58 pub fn queue(&self) -> &VecDeque<QueueEntry> {
60 &self.queue
61 }
62
63 pub(crate) fn increment_order_count(&mut self) {
65 self.order_count += 1;
66 }
67
68 pub(crate) fn decrement_order_count(&mut self) {
70 self.order_count -= 1;
71 }
72
73 pub(crate) fn is_empty(&self) -> bool {
75 self.order_count == 0
76 }
77}
78
79impl PriceLevel {
80 pub(crate) fn push(&mut self, queue_entry: QueueEntry) {
82 self.queue.push_back(queue_entry);
83 }
84
85 pub(crate) fn peek(&self) -> Option<QueueEntry> {
87 self.queue.front().copied()
88 }
89
90 pub(crate) fn pop(&mut self) -> Option<QueueEntry> {
92 self.queue.pop_front()
93 }
94
95 pub(crate) fn add_order_entry(
97 &mut self,
98 queue_entry: QueueEntry,
99 visible: Quantity,
100 hidden: Quantity,
101 ) {
102 self.visible_quantity += visible;
103 self.hidden_quantity += hidden;
104
105 self.push(queue_entry);
106 self.increment_order_count();
107 }
108
109 pub(crate) fn mark_order_removed(&mut self, visible: Quantity, hidden: Quantity) {
113 self.visible_quantity -= visible;
114 self.hidden_quantity -= hidden;
115 self.decrement_order_count();
116 }
117
118 pub(crate) fn remove_head_order(
122 &mut self,
123 limit_orders: &mut HashMap<OrderId, RestingLimitOrder>,
124 ) {
125 let Some(queue_entry) = self.pop() else {
126 return;
127 };
128 limit_orders.remove(&queue_entry.order_id());
129 self.decrement_order_count();
130 }
131
132 pub(crate) fn apply_replenishment(&mut self, replenished: Quantity) {
134 self.visible_quantity += replenished;
135 self.hidden_quantity -= replenished;
136 }
137
138 pub(crate) fn reprioritize_front(&mut self, time_priority: SequenceNumber) {
143 let queue_entry = self.pop().unwrap();
144 self.push(queue_entry.reprioritize(time_priority));
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use crate::*;
151 use crate::{LimitOrder, OrderFlags, Price, Quantity, QuantityPolicy, Side, TimeInForce};
152
153 use std::collections::HashMap;
154
155 #[test]
156 fn test_total_quantity() {
157 let mut price_level = PriceLevel::new();
158 assert_eq!(price_level.total_quantity(), Quantity(0));
159
160 price_level.visible_quantity = Quantity(10);
161 price_level.hidden_quantity = Quantity(20);
162 assert_eq!(price_level.total_quantity(), Quantity(30));
163 }
164
165 #[test]
166 fn test_order_count() {
167 let mut price_level = PriceLevel::new();
168 assert_eq!(price_level.order_count(), 0);
169 assert!(price_level.is_empty());
170
171 price_level.increment_order_count();
172 assert_eq!(price_level.order_count(), 1);
173 assert!(!price_level.is_empty());
174
175 price_level.decrement_order_count();
176 assert_eq!(price_level.order_count(), 0);
177 assert!(price_level.is_empty());
178 }
179
180 #[test]
181 fn test_add_order_entry_and_mark_order_removed() {
182 let mut price_level = PriceLevel::new();
183 assert_eq!(price_level.visible_quantity, Quantity(0));
184 assert_eq!(price_level.hidden_quantity, Quantity(0));
185 assert_eq!(price_level.order_count(), 0);
186
187 price_level.add_order_entry(
188 QueueEntry::new(SequenceNumber(0), OrderId(0)),
189 Quantity(10),
190 Quantity(0),
191 );
192 assert_eq!(price_level.visible_quantity, Quantity(10));
193 assert_eq!(price_level.hidden_quantity, Quantity(0));
194 assert_eq!(price_level.order_count(), 1);
195
196 price_level.add_order_entry(
197 QueueEntry::new(SequenceNumber(1), OrderId(1)),
198 Quantity(20),
199 Quantity(0),
200 );
201 assert_eq!(price_level.visible_quantity, Quantity(30));
202 assert_eq!(price_level.hidden_quantity, Quantity(0));
203 assert_eq!(price_level.order_count(), 2);
204
205 price_level.add_order_entry(
206 QueueEntry::new(SequenceNumber(2), OrderId(2)),
207 Quantity(30),
208 Quantity(0),
209 );
210 assert_eq!(price_level.visible_quantity, Quantity(60));
211 assert_eq!(price_level.hidden_quantity, Quantity(0));
212 assert_eq!(price_level.order_count(), 3);
213
214 price_level.add_order_entry(
215 QueueEntry::new(SequenceNumber(3), OrderId(3)),
216 Quantity(40),
217 Quantity(0),
218 );
219 assert_eq!(price_level.visible_quantity, Quantity(100));
220 assert_eq!(price_level.hidden_quantity, Quantity(0));
221 assert_eq!(price_level.order_count(), 4);
222
223 price_level.add_order_entry(
224 QueueEntry::new(SequenceNumber(4), OrderId(4)),
225 Quantity(50),
226 Quantity(50),
227 );
228 assert_eq!(price_level.visible_quantity, Quantity(150));
229 assert_eq!(price_level.hidden_quantity, Quantity(50));
230 assert_eq!(price_level.order_count(), 5);
231
232 price_level.mark_order_removed(Quantity(10), Quantity(0));
233 assert_eq!(price_level.visible_quantity, Quantity(140));
234 assert_eq!(price_level.hidden_quantity, Quantity(50));
235 assert_eq!(price_level.order_count(), 4);
236
237 price_level.mark_order_removed(Quantity(20), Quantity(0));
238 assert_eq!(price_level.visible_quantity, Quantity(120));
239 assert_eq!(price_level.hidden_quantity, Quantity(50));
240 assert_eq!(price_level.order_count(), 3);
241
242 price_level.mark_order_removed(Quantity(30), Quantity(0));
243 assert_eq!(price_level.visible_quantity, Quantity(90));
244 assert_eq!(price_level.hidden_quantity, Quantity(50));
245 assert_eq!(price_level.order_count(), 2);
246
247 price_level.mark_order_removed(Quantity(40), Quantity(0));
248 assert_eq!(price_level.visible_quantity, Quantity(50));
249 assert_eq!(price_level.hidden_quantity, Quantity(50));
250 assert_eq!(price_level.order_count(), 1);
251
252 price_level.mark_order_removed(Quantity(50), Quantity(50));
253 assert_eq!(price_level.visible_quantity, Quantity(0));
254 assert_eq!(price_level.hidden_quantity, Quantity(0));
255 assert_eq!(price_level.order_count(), 0);
256 }
257
258 #[test]
259 fn test_remove_head_order() {
260 let mut limit_orders = HashMap::new();
261
262 let mut price_level = PriceLevel::new();
263 assert!(price_level.peek().is_none());
264
265 limit_orders.insert(
266 OrderId(0),
267 RestingLimitOrder::new(
268 SequenceNumber(0),
269 0,
270 LimitOrder::new(
271 Price(100),
272 QuantityPolicy::Standard {
273 quantity: Quantity(10),
274 },
275 OrderFlags::new(Side::Buy, true, TimeInForce::Gtc),
276 ),
277 ),
278 );
279 price_level.add_order_entry(
280 QueueEntry::new(SequenceNumber(0), OrderId(0)),
281 Quantity(10),
282 Quantity(0),
283 );
284 assert_eq!(
285 price_level.peek(),
286 Some(QueueEntry::new(SequenceNumber(0), OrderId(0)))
287 );
288
289 price_level.remove_head_order(&mut limit_orders);
290 assert!(price_level.peek().is_none());
291
292 limit_orders.insert(
293 OrderId(1),
294 RestingLimitOrder::new(
295 SequenceNumber(1),
296 0,
297 LimitOrder::new(
298 Price(100),
299 QuantityPolicy::Standard {
300 quantity: Quantity(20),
301 },
302 OrderFlags::new(Side::Buy, true, TimeInForce::Gtc),
303 ),
304 ),
305 );
306 price_level.add_order_entry(
307 QueueEntry::new(SequenceNumber(1), OrderId(1)),
308 Quantity(20),
309 Quantity(0),
310 );
311 assert_eq!(
312 price_level.peek(),
313 Some(QueueEntry::new(SequenceNumber(1), OrderId(1)))
314 );
315
316 limit_orders.insert(
317 OrderId(2),
318 RestingLimitOrder::new(
319 SequenceNumber(2),
320 0,
321 LimitOrder::new(
322 Price(100),
323 QuantityPolicy::Standard {
324 quantity: Quantity(30),
325 },
326 OrderFlags::new(Side::Buy, true, TimeInForce::Gtc),
327 ),
328 ),
329 );
330 price_level.add_order_entry(
331 QueueEntry::new(SequenceNumber(2), OrderId(2)),
332 Quantity(30),
333 Quantity(0),
334 );
335 assert_eq!(
336 price_level.peek(),
337 Some(QueueEntry::new(SequenceNumber(1), OrderId(1)))
338 );
339
340 price_level.remove_head_order(&mut limit_orders);
341 assert_eq!(
342 price_level.peek(),
343 Some(QueueEntry::new(SequenceNumber(2), OrderId(2)))
344 );
345
346 price_level.remove_head_order(&mut limit_orders);
347 assert!(price_level.peek().is_none());
348 }
349
350 #[test]
351 fn test_reprioritize_front() {
352 let mut price_level = PriceLevel::new();
353 assert_eq!(price_level.peek(), None);
354
355 price_level.push(QueueEntry::new(SequenceNumber(0), OrderId(0)));
356 assert_eq!(
357 price_level.peek(),
358 Some(QueueEntry::new(SequenceNumber(0), OrderId(0)))
359 );
360
361 price_level.reprioritize_front(SequenceNumber(1));
362 assert_eq!(
363 price_level.peek(),
364 Some(QueueEntry::new(SequenceNumber(1), OrderId(0)))
365 );
366
367 price_level.push(QueueEntry::new(SequenceNumber(2), OrderId(2)));
368 assert_eq!(
369 price_level.peek(),
370 Some(QueueEntry::new(SequenceNumber(1), OrderId(0)))
371 );
372
373 price_level.reprioritize_front(SequenceNumber(3));
374 assert_eq!(
375 price_level.peek(),
376 Some(QueueEntry::new(SequenceNumber(2), OrderId(2)))
377 );
378
379 price_level.reprioritize_front(SequenceNumber(4));
380 assert_eq!(
381 price_level.peek(),
382 Some(QueueEntry::new(SequenceNumber(3), OrderId(0)))
383 );
384 }
385
386 #[test]
387 fn test_apply_replenishment() {
388 let mut price_level = PriceLevel::new();
389 assert_eq!(price_level.visible_quantity, Quantity(0));
390 assert_eq!(price_level.hidden_quantity, Quantity(0));
391
392 price_level.visible_quantity = Quantity(10);
393 price_level.hidden_quantity = Quantity(100);
394
395 price_level.apply_replenishment(Quantity(10));
396 assert_eq!(price_level.visible_quantity, Quantity(20));
397 assert_eq!(price_level.hidden_quantity, Quantity(90));
398
399 price_level.apply_replenishment(Quantity(10));
400 assert_eq!(price_level.visible_quantity, Quantity(30));
401 assert_eq!(price_level.hidden_quantity, Quantity(80));
402
403 price_level.apply_replenishment(Quantity(10));
404 assert_eq!(price_level.visible_quantity, Quantity(40));
405 assert_eq!(price_level.hidden_quantity, Quantity(70));
406
407 price_level.apply_replenishment(Quantity(10));
408 assert_eq!(price_level.visible_quantity, Quantity(50));
409 assert_eq!(price_level.hidden_quantity, Quantity(60));
410
411 price_level.apply_replenishment(Quantity(10));
412 assert_eq!(price_level.visible_quantity, Quantity(60));
413 assert_eq!(price_level.hidden_quantity, Quantity(50));
414
415 price_level.apply_replenishment(Quantity(10));
416 assert_eq!(price_level.visible_quantity, Quantity(70));
417 assert_eq!(price_level.hidden_quantity, Quantity(40));
418
419 price_level.apply_replenishment(Quantity(10));
420 assert_eq!(price_level.visible_quantity, Quantity(80));
421 assert_eq!(price_level.hidden_quantity, Quantity(30));
422
423 price_level.apply_replenishment(Quantity(10));
424 assert_eq!(price_level.visible_quantity, Quantity(90));
425 assert_eq!(price_level.hidden_quantity, Quantity(20));
426
427 price_level.apply_replenishment(Quantity(10));
428 assert_eq!(price_level.visible_quantity, Quantity(100));
429 assert_eq!(price_level.hidden_quantity, Quantity(10));
430
431 price_level.apply_replenishment(Quantity(10));
432 assert_eq!(price_level.visible_quantity, Quantity(110));
433 assert_eq!(price_level.hidden_quantity, Quantity(0));
434 }
435}