1use std::{collections::HashMap, fmt::Display};
19
20use indexmap::IndexMap;
21use nautilus_core::{UnixNanos, serialization::Serializable};
22use serde::{Deserialize, Serialize};
23
24use super::{HasTsInit, order::BookOrder};
25use crate::{identifiers::InstrumentId, types::fixed::FIXED_SIZE_BINARY};
26
27pub const DEPTH10_LEN: usize = 10;
28
29#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
42#[cfg_attr(
43 feature = "python",
44 pyo3::pyclass(module = "nautilus_trader.model", from_py_object)
45)]
46#[cfg_attr(
47 feature = "python",
48 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.model")
49)]
50pub struct OrderBookDepth10 {
51 pub instrument_id: InstrumentId,
53 pub bids: [BookOrder; DEPTH10_LEN],
55 pub asks: [BookOrder; DEPTH10_LEN],
57 pub bid_counts: [u32; DEPTH10_LEN],
59 pub ask_counts: [u32; DEPTH10_LEN],
61 pub flags: u8,
63 pub sequence: u64,
65 pub ts_event: UnixNanos,
67 pub ts_init: UnixNanos,
69}
70
71impl OrderBookDepth10 {
72 #[expect(clippy::too_many_arguments)]
74 #[must_use]
75 pub fn new(
76 instrument_id: InstrumentId,
77 bids: [BookOrder; DEPTH10_LEN],
78 asks: [BookOrder; DEPTH10_LEN],
79 bid_counts: [u32; DEPTH10_LEN],
80 ask_counts: [u32; DEPTH10_LEN],
81 flags: u8,
82 sequence: u64,
83 ts_event: UnixNanos,
84 ts_init: UnixNanos,
85 ) -> Self {
86 Self {
87 instrument_id,
88 bids,
89 asks,
90 bid_counts,
91 ask_counts,
92 flags,
93 sequence,
94 ts_event,
95 ts_init,
96 }
97 }
98
99 #[must_use]
101 pub fn get_metadata(
102 instrument_id: &InstrumentId,
103 price_precision: u8,
104 size_precision: u8,
105 ) -> HashMap<String, String> {
106 let mut metadata = HashMap::new();
107 metadata.insert("instrument_id".to_string(), instrument_id.to_string());
108 metadata.insert("price_precision".to_string(), price_precision.to_string());
109 metadata.insert("size_precision".to_string(), size_precision.to_string());
110 metadata
111 }
112
113 #[must_use]
115 pub fn get_fields() -> IndexMap<String, String> {
116 let mut metadata = IndexMap::new();
117
118 for name in ["bid_price", "ask_price", "bid_size", "ask_size"] {
119 for level in 0..DEPTH10_LEN {
120 metadata.insert(format!("{name}_{level}"), FIXED_SIZE_BINARY.to_string());
121 }
122 }
123
124 for name in ["bid_count", "ask_count"] {
125 for level in 0..DEPTH10_LEN {
126 metadata.insert(format!("{name}_{level}"), "UInt32".to_string());
127 }
128 }
129
130 metadata.insert("flags".to_string(), "UInt8".to_string());
131 metadata.insert("sequence".to_string(), "UInt64".to_string());
132 metadata.insert("ts_event".to_string(), "UInt64".to_string());
133 metadata.insert("ts_init".to_string(), "UInt64".to_string());
134 metadata
135 }
136}
137
138impl Display for OrderBookDepth10 {
140 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
141 write!(
142 f,
143 "{},flags={},sequence={},ts_event={},ts_init={}",
144 self.instrument_id, self.flags, self.sequence, self.ts_event, self.ts_init
145 )
146 }
147}
148
149impl Serializable for OrderBookDepth10 {}
150
151impl HasTsInit for OrderBookDepth10 {
152 fn ts_init(&self) -> UnixNanos {
153 self.ts_init
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use std::{
160 collections::hash_map::DefaultHasher,
161 hash::{Hash, Hasher},
162 };
163
164 use rstest::rstest;
165 use serde_json;
166
167 use super::*;
168 use crate::{
169 data::{order::BookOrder, stubs::*},
170 enums::OrderSide,
171 types::{Price, Quantity},
172 };
173
174 fn create_test_book_order(
175 side: OrderSide,
176 price: &str,
177 size: &str,
178 order_id: u64,
179 ) -> BookOrder {
180 BookOrder::new(side, Price::from(price), Quantity::from(size), order_id)
181 }
182
183 fn create_test_depth10() -> OrderBookDepth10 {
184 let instrument_id = InstrumentId::from("EURUSD.SIM");
185
186 let bids = [
188 create_test_book_order(OrderSide::Buy, "1.0500", "100000", 1),
189 create_test_book_order(OrderSide::Buy, "1.0499", "150000", 2),
190 create_test_book_order(OrderSide::Buy, "1.0498", "200000", 3),
191 create_test_book_order(OrderSide::Buy, "1.0497", "125000", 4),
192 create_test_book_order(OrderSide::Buy, "1.0496", "175000", 5),
193 create_test_book_order(OrderSide::Buy, "1.0495", "100000", 6),
194 create_test_book_order(OrderSide::Buy, "1.0494", "225000", 7),
195 create_test_book_order(OrderSide::Buy, "1.0493", "150000", 8),
196 create_test_book_order(OrderSide::Buy, "1.0492", "300000", 9),
197 create_test_book_order(OrderSide::Buy, "1.0491", "175000", 10),
198 ];
199
200 let asks = [
202 create_test_book_order(OrderSide::Sell, "1.0501", "100000", 11),
203 create_test_book_order(OrderSide::Sell, "1.0502", "125000", 12),
204 create_test_book_order(OrderSide::Sell, "1.0503", "150000", 13),
205 create_test_book_order(OrderSide::Sell, "1.0504", "175000", 14),
206 create_test_book_order(OrderSide::Sell, "1.0505", "200000", 15),
207 create_test_book_order(OrderSide::Sell, "1.0506", "100000", 16),
208 create_test_book_order(OrderSide::Sell, "1.0507", "250000", 17),
209 create_test_book_order(OrderSide::Sell, "1.0508", "125000", 18),
210 create_test_book_order(OrderSide::Sell, "1.0509", "300000", 19),
211 create_test_book_order(OrderSide::Sell, "1.0510", "175000", 20),
212 ];
213
214 let bid_counts = [1, 2, 1, 3, 1, 2, 1, 4, 1, 2];
215 let ask_counts = [2, 1, 3, 1, 2, 1, 4, 1, 2, 3];
216
217 OrderBookDepth10::new(
218 instrument_id,
219 bids,
220 asks,
221 bid_counts,
222 ask_counts,
223 32, 12345, UnixNanos::from(1_000_000_000), UnixNanos::from(2_000_000_000), )
228 }
229
230 fn create_empty_depth10() -> OrderBookDepth10 {
231 let instrument_id = InstrumentId::from("EMPTY.TEST");
232
233 let empty_bid = create_test_book_order(OrderSide::Buy, "0.0", "0", 0);
235 let empty_ask = create_test_book_order(OrderSide::Sell, "0.0", "0", 0);
236
237 OrderBookDepth10::new(
238 instrument_id,
239 [empty_bid; DEPTH10_LEN],
240 [empty_ask; DEPTH10_LEN],
241 [0; DEPTH10_LEN],
242 [0; DEPTH10_LEN],
243 0,
244 0,
245 UnixNanos::from(0),
246 UnixNanos::from(0),
247 )
248 }
249
250 #[rstest]
251 fn test_order_book_depth10_new() {
252 let depth = create_test_depth10();
253
254 assert_eq!(depth.instrument_id, InstrumentId::from("EURUSD.SIM"));
255 assert_eq!(depth.bids.len(), DEPTH10_LEN);
256 assert_eq!(depth.asks.len(), DEPTH10_LEN);
257 assert_eq!(depth.bid_counts.len(), DEPTH10_LEN);
258 assert_eq!(depth.ask_counts.len(), DEPTH10_LEN);
259 assert_eq!(depth.flags, 32);
260 assert_eq!(depth.sequence, 12345);
261 assert_eq!(depth.ts_event, UnixNanos::from(1_000_000_000));
262 assert_eq!(depth.ts_init, UnixNanos::from(2_000_000_000));
263 }
264
265 #[rstest]
266 fn test_order_book_depth10_new_with_all_parameters() {
267 let instrument_id = InstrumentId::from("GBPUSD.SIM");
268 let bid = create_test_book_order(OrderSide::Buy, "1.2500", "50000", 1);
269 let ask = create_test_book_order(OrderSide::Sell, "1.2501", "75000", 2);
270 let flags = 64u8;
271 let sequence = 999u64;
272 let ts_event = UnixNanos::from(5_000_000_000);
273 let ts_init = UnixNanos::from(6_000_000_000);
274
275 let depth = OrderBookDepth10::new(
276 instrument_id,
277 [bid; DEPTH10_LEN],
278 [ask; DEPTH10_LEN],
279 [5; DEPTH10_LEN],
280 [3; DEPTH10_LEN],
281 flags,
282 sequence,
283 ts_event,
284 ts_init,
285 );
286
287 assert_eq!(depth.instrument_id, instrument_id);
288 assert_eq!(depth.bids[0], bid);
289 assert_eq!(depth.asks[0], ask);
290 assert_eq!(depth.bid_counts[0], 5);
291 assert_eq!(depth.ask_counts[0], 3);
292 assert_eq!(depth.flags, flags);
293 assert_eq!(depth.sequence, sequence);
294 assert_eq!(depth.ts_event, ts_event);
295 assert_eq!(depth.ts_init, ts_init);
296 }
297
298 #[rstest]
299 fn test_order_book_depth10_fixed_array_sizes() {
300 let depth = create_test_depth10();
301
302 assert_eq!(depth.bids.len(), 10);
304 assert_eq!(depth.asks.len(), 10);
305 assert_eq!(depth.bid_counts.len(), 10);
306 assert_eq!(depth.ask_counts.len(), 10);
307
308 assert_eq!(DEPTH10_LEN, 10);
310 }
311
312 #[rstest]
313 fn test_order_book_depth10_array_indexing() {
314 let depth = create_test_depth10();
315
316 assert_eq!(depth.bids[0].price, Price::from("1.0500"));
318 assert_eq!(depth.bids[9].price, Price::from("1.0491"));
319 assert_eq!(depth.asks[0].price, Price::from("1.0501"));
320 assert_eq!(depth.asks[9].price, Price::from("1.0510"));
321 assert_eq!(depth.bid_counts[0], 1);
322 assert_eq!(depth.bid_counts[9], 2);
323 assert_eq!(depth.ask_counts[0], 2);
324 assert_eq!(depth.ask_counts[9], 3);
325 }
326
327 #[rstest]
328 fn test_order_book_depth10_bid_ask_ordering() {
329 let depth = create_test_depth10();
330
331 for i in 0..9 {
333 assert!(
334 depth.bids[i].price >= depth.bids[i + 1].price,
335 "Bid prices should be in descending order: {} >= {}",
336 depth.bids[i].price,
337 depth.bids[i + 1].price
338 );
339 }
340
341 for i in 0..9 {
343 assert!(
344 depth.asks[i].price <= depth.asks[i + 1].price,
345 "Ask prices should be in ascending order: {} <= {}",
346 depth.asks[i].price,
347 depth.asks[i + 1].price
348 );
349 }
350
351 assert!(
353 depth.bids[0].price < depth.asks[0].price,
354 "Best bid {} should be less than best ask {}",
355 depth.bids[0].price,
356 depth.asks[0].price
357 );
358 }
359
360 #[rstest]
361 fn test_order_book_depth10_clone() {
362 let depth1 = create_test_depth10();
363 let depth2 = depth1;
364
365 assert_eq!(depth1.instrument_id, depth2.instrument_id);
366 assert_eq!(depth1.bids, depth2.bids);
367 assert_eq!(depth1.asks, depth2.asks);
368 assert_eq!(depth1.bid_counts, depth2.bid_counts);
369 assert_eq!(depth1.ask_counts, depth2.ask_counts);
370 assert_eq!(depth1.flags, depth2.flags);
371 assert_eq!(depth1.sequence, depth2.sequence);
372 assert_eq!(depth1.ts_event, depth2.ts_event);
373 assert_eq!(depth1.ts_init, depth2.ts_init);
374 }
375
376 #[rstest]
377 fn test_order_book_depth10_copy() {
378 let depth1 = create_test_depth10();
379 let depth2 = depth1;
380
381 assert_eq!(depth1, depth2);
384 }
385
386 #[rstest]
387 fn test_order_book_depth10_debug() {
388 let depth = create_test_depth10();
389 let debug_str = format!("{depth:?}");
390
391 assert!(debug_str.contains("OrderBookDepth10"));
392 assert!(debug_str.contains("EURUSD.SIM"));
393 assert!(debug_str.contains("flags: 32"));
394 assert!(debug_str.contains("sequence: 12345"));
395 }
396
397 #[rstest]
398 fn test_order_book_depth10_partial_eq() {
399 let depth1 = create_test_depth10();
400 let depth2 = create_test_depth10();
401 let depth3 = create_empty_depth10();
402
403 assert_eq!(depth1, depth2); assert_ne!(depth1, depth3); assert_ne!(depth2, depth3); }
407
408 #[rstest]
409 fn test_order_book_depth10_eq_consistency() {
410 let depth1 = create_test_depth10();
411 let depth2 = create_test_depth10();
412
413 assert_eq!(depth1, depth2);
414 assert_eq!(depth2, depth1); assert_eq!(depth1, depth1); }
417
418 #[rstest]
419 fn test_order_book_depth10_hash() {
420 let depth1 = create_test_depth10();
421 let depth2 = create_test_depth10();
422
423 let mut hasher1 = DefaultHasher::new();
424 let mut hasher2 = DefaultHasher::new();
425
426 depth1.hash(&mut hasher1);
427 depth2.hash(&mut hasher2);
428
429 assert_eq!(hasher1.finish(), hasher2.finish()); }
431
432 #[rstest]
433 fn test_order_book_depth10_hash_different_objects() {
434 let depth1 = create_test_depth10();
435 let depth2 = create_empty_depth10();
436
437 let mut hasher1 = DefaultHasher::new();
438 let mut hasher2 = DefaultHasher::new();
439
440 depth1.hash(&mut hasher1);
441 depth2.hash(&mut hasher2);
442
443 assert_ne!(hasher1.finish(), hasher2.finish()); }
445
446 #[rstest]
447 fn test_order_book_depth10_display() {
448 let depth = create_test_depth10();
449 let display_str = format!("{depth}");
450
451 assert!(display_str.contains("EURUSD.SIM"));
452 assert!(display_str.contains("flags=32"));
453 assert!(display_str.contains("sequence=12345"));
454 assert!(display_str.contains("ts_event=1000000000"));
455 assert!(display_str.contains("ts_init=2000000000"));
456 }
457
458 #[rstest]
459 fn test_order_book_depth10_display_format() {
460 let depth = create_test_depth10();
461 let expected = "EURUSD.SIM,flags=32,sequence=12345,ts_event=1000000000,ts_init=2000000000";
462
463 assert_eq!(format!("{depth}"), expected);
464 }
465
466 #[rstest]
467 fn test_order_book_depth10_serialization() {
468 let depth = create_test_depth10();
469
470 let json = serde_json::to_string(&depth).unwrap();
472 let deserialized: OrderBookDepth10 = serde_json::from_str(&json).unwrap();
473
474 assert_eq!(depth, deserialized);
475 }
476
477 #[rstest]
478 fn test_order_book_depth10_serializable_trait() {
479 fn assert_serializable<T: Serializable>(_: &T) {}
480
481 let depth = create_test_depth10();
482
483 assert_serializable(&depth);
485 }
486
487 #[rstest]
488 fn test_order_book_depth10_has_ts_init() {
489 let depth = create_test_depth10();
490
491 assert_eq!(depth.ts_init(), UnixNanos::from(2_000_000_000));
492 }
493
494 #[rstest]
495 fn test_order_book_depth10_get_metadata() {
496 let instrument_id = InstrumentId::from("EURUSD.SIM");
497 let price_precision = 5u8;
498 let size_precision = 0u8;
499
500 let metadata =
501 OrderBookDepth10::get_metadata(&instrument_id, price_precision, size_precision);
502
503 assert_eq!(
504 metadata.get("instrument_id"),
505 Some(&"EURUSD.SIM".to_string())
506 );
507 assert_eq!(metadata.get("price_precision"), Some(&"5".to_string()));
508 assert_eq!(metadata.get("size_precision"), Some(&"0".to_string()));
509 assert_eq!(metadata.len(), 3);
510 }
511
512 #[rstest]
513 fn test_order_book_depth10_get_fields() {
514 let fields = OrderBookDepth10::get_fields();
515
516 for i in 0..10 {
518 assert_eq!(
519 fields.get(&format!("bid_price_{i}")),
520 Some(&FIXED_SIZE_BINARY.to_string())
521 );
522 assert_eq!(
523 fields.get(&format!("ask_price_{i}")),
524 Some(&FIXED_SIZE_BINARY.to_string())
525 );
526 }
527
528 for i in 0..10 {
530 assert_eq!(
531 fields.get(&format!("bid_size_{i}")),
532 Some(&FIXED_SIZE_BINARY.to_string())
533 );
534 assert_eq!(
535 fields.get(&format!("ask_size_{i}")),
536 Some(&FIXED_SIZE_BINARY.to_string())
537 );
538 }
539
540 for i in 0..10 {
542 assert_eq!(
543 fields.get(&format!("bid_count_{i}")),
544 Some(&"UInt32".to_string())
545 );
546 assert_eq!(
547 fields.get(&format!("ask_count_{i}")),
548 Some(&"UInt32".to_string())
549 );
550 }
551
552 assert_eq!(fields.get("flags"), Some(&"UInt8".to_string()));
554 assert_eq!(fields.get("sequence"), Some(&"UInt64".to_string()));
555 assert_eq!(fields.get("ts_event"), Some(&"UInt64".to_string()));
556 assert_eq!(fields.get("ts_init"), Some(&"UInt64".to_string()));
557
558 assert_eq!(fields.len(), 64);
561 }
562
563 #[rstest]
564 fn test_order_book_depth10_get_fields_order() {
565 let fields = OrderBookDepth10::get_fields();
566 let keys: Vec<&String> = fields.keys().collect();
567
568 assert_eq!(keys[0], "bid_price_0");
570 assert_eq!(keys[9], "bid_price_9");
571 assert_eq!(keys[10], "ask_price_0");
572 assert_eq!(keys[19], "ask_price_9");
573 assert_eq!(keys[20], "bid_size_0");
574 assert_eq!(keys[29], "bid_size_9");
575 assert_eq!(keys[30], "ask_size_0");
576 assert_eq!(keys[39], "ask_size_9");
577 assert_eq!(keys[40], "bid_count_0");
578 assert_eq!(keys[41], "bid_count_1");
579 }
580
581 #[rstest]
582 fn test_order_book_depth10_empty_values() {
583 let depth = create_empty_depth10();
584
585 assert_eq!(depth.instrument_id, InstrumentId::from("EMPTY.TEST"));
586 assert_eq!(depth.flags, 0);
587 assert_eq!(depth.sequence, 0);
588 assert_eq!(depth.ts_event, UnixNanos::from(0));
589 assert_eq!(depth.ts_init, UnixNanos::from(0));
590
591 for bid in &depth.bids {
593 assert_eq!(bid.price, Price::from("0.0"));
594 assert_eq!(bid.size, Quantity::from("0"));
595 assert_eq!(bid.order_id, 0);
596 }
597
598 for ask in &depth.asks {
599 assert_eq!(ask.price, Price::from("0.0"));
600 assert_eq!(ask.size, Quantity::from("0"));
601 assert_eq!(ask.order_id, 0);
602 }
603
604 for &count in &depth.bid_counts {
606 assert_eq!(count, 0);
607 }
608
609 for &count in &depth.ask_counts {
610 assert_eq!(count, 0);
611 }
612 }
613
614 #[rstest]
615 fn test_order_book_depth10_max_values() {
616 let instrument_id = InstrumentId::from("MAX.TEST");
617 let max_bid = create_test_book_order(OrderSide::Buy, "999999.99", "999999999", u64::MAX);
618 let max_ask = create_test_book_order(OrderSide::Sell, "1000000.00", "999999999", u64::MAX);
619
620 let depth = OrderBookDepth10::new(
621 instrument_id,
622 [max_bid; DEPTH10_LEN],
623 [max_ask; DEPTH10_LEN],
624 [u32::MAX; DEPTH10_LEN],
625 [u32::MAX; DEPTH10_LEN],
626 u8::MAX,
627 u64::MAX,
628 UnixNanos::from(u64::MAX),
629 UnixNanos::from(u64::MAX),
630 );
631
632 assert_eq!(depth.flags, u8::MAX);
633 assert_eq!(depth.sequence, u64::MAX);
634 assert_eq!(depth.ts_event, UnixNanos::from(u64::MAX));
635 assert_eq!(depth.ts_init, UnixNanos::from(u64::MAX));
636
637 for &count in &depth.bid_counts {
638 assert_eq!(count, u32::MAX);
639 }
640
641 for &count in &depth.ask_counts {
642 assert_eq!(count, u32::MAX);
643 }
644 }
645
646 #[rstest]
647 fn test_order_book_depth10_different_instruments() {
648 let instruments = [
649 "EURUSD.SIM",
650 "GBPUSD.SIM",
651 "USDJPY.SIM",
652 "AUDUSD.SIM",
653 "USDCHF.SIM",
654 ];
655
656 for instrument_str in &instruments {
657 let instrument_id = InstrumentId::from(*instrument_str);
658 let bid = create_test_book_order(OrderSide::Buy, "1.0000", "100000", 1);
659 let ask = create_test_book_order(OrderSide::Sell, "1.0001", "100000", 2);
660
661 let depth = OrderBookDepth10::new(
662 instrument_id,
663 [bid; DEPTH10_LEN],
664 [ask; DEPTH10_LEN],
665 [1; DEPTH10_LEN],
666 [1; DEPTH10_LEN],
667 0,
668 1,
669 UnixNanos::from(1_000_000_000),
670 UnixNanos::from(2_000_000_000),
671 );
672
673 assert_eq!(depth.instrument_id, instrument_id);
674 assert!(format!("{depth}").contains(instrument_str));
675 }
676 }
677
678 #[rstest]
679 fn test_order_book_depth10_realistic_forex_spread() {
680 let instrument_id = InstrumentId::from("EURUSD.SIM");
681
682 let best_bid = create_test_book_order(OrderSide::Buy, "1.08500", "1000000", 1);
684 let best_ask = create_test_book_order(OrderSide::Sell, "1.08501", "1000000", 2);
685
686 let depth = OrderBookDepth10::new(
687 instrument_id,
688 [best_bid; DEPTH10_LEN],
689 [best_ask; DEPTH10_LEN],
690 [5; DEPTH10_LEN], [3; DEPTH10_LEN],
692 16, 123_456, UnixNanos::from(1_672_531_200_000_000_000), UnixNanos::from(1_672_531_200_000_100_000),
696 );
697
698 assert_eq!(depth.bids[0].price, Price::from("1.08500"));
699 assert_eq!(depth.asks[0].price, Price::from("1.08501"));
700 assert!(depth.bids[0].price < depth.asks[0].price); assert_eq!(depth.bids[0].size, Quantity::from("1000000"));
704 assert_eq!(depth.bid_counts[0], 5);
705 assert_eq!(depth.ask_counts[0], 3);
706 }
707
708 #[rstest]
709 fn test_order_book_depth10_with_stub(stub_depth10: OrderBookDepth10) {
710 let depth = stub_depth10;
711
712 assert_eq!(depth.instrument_id, InstrumentId::from("AAPL.XNAS"));
713 assert_eq!(depth.bids.len(), 10);
714 assert_eq!(depth.asks.len(), 10);
715 assert_eq!(depth.asks[9].price, Price::from("109.0"));
716 assert_eq!(depth.asks[0].price, Price::from("100.0"));
717 assert_eq!(depth.bids[0].price, Price::from("99.0"));
718 assert_eq!(depth.bids[9].price, Price::from("90.0"));
719 assert_eq!(depth.bid_counts.len(), 10);
720 assert_eq!(depth.ask_counts.len(), 10);
721 assert_eq!(depth.bid_counts[0], 1);
722 assert_eq!(depth.ask_counts[0], 1);
723 assert_eq!(depth.flags, 0);
724 assert_eq!(depth.sequence, 0);
725 assert_eq!(depth.ts_event, UnixNanos::from(1));
726 assert_eq!(depth.ts_init, UnixNanos::from(2));
727 }
728
729 #[rstest]
730 fn test_new(stub_depth10: OrderBookDepth10) {
731 let depth = stub_depth10;
732 let instrument_id = InstrumentId::from("AAPL.XNAS");
733 let flags = 0;
734 let sequence = 0;
735 let ts_event = 1;
736 let ts_init = 2;
737
738 assert_eq!(depth.instrument_id, instrument_id);
739 assert_eq!(depth.bids.len(), 10);
740 assert_eq!(depth.asks.len(), 10);
741 assert_eq!(depth.asks[9].price, Price::from("109.0"));
742 assert_eq!(depth.asks[0].price, Price::from("100.0"));
743 assert_eq!(depth.bids[0].price, Price::from("99.0"));
744 assert_eq!(depth.bids[9].price, Price::from("90.0"));
745 assert_eq!(depth.bid_counts.len(), 10);
746 assert_eq!(depth.ask_counts.len(), 10);
747 assert_eq!(depth.bid_counts[0], 1);
748 assert_eq!(depth.ask_counts[0], 1);
749 assert_eq!(depth.flags, flags);
750 assert_eq!(depth.sequence, sequence);
751 assert_eq!(depth.ts_event, ts_event);
752 assert_eq!(depth.ts_init, ts_init);
753 }
754
755 #[rstest]
756 fn test_display(stub_depth10: OrderBookDepth10) {
757 let depth = stub_depth10;
758 assert_eq!(
759 format!("{depth}"),
760 "AAPL.XNAS,flags=0,sequence=0,ts_event=1,ts_init=2".to_string()
761 );
762 }
763}