1use std::{
19 fmt::Display,
20 hash::{Hash, Hasher},
21};
22
23use nautilus_core::{
24 UnixNanos,
25 correctness::{FAILED, check_predicate_true},
26 serialization::Serializable,
27};
28use serde::{Deserialize, Serialize};
29
30use super::{HasTsInit, OrderBookDelta};
31use crate::identifiers::InstrumentId;
32
33#[derive(Clone, Debug, Serialize, Deserialize)]
37#[cfg_attr(
38 feature = "python",
39 pyo3::pyclass(module = "nautilus_trader.model", from_py_object)
40)]
41#[cfg_attr(
42 feature = "python",
43 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.model")
44)]
45pub struct OrderBookDeltas {
46 pub instrument_id: InstrumentId,
48 pub deltas: Vec<OrderBookDelta>,
50 pub flags: u8,
52 pub sequence: u64,
54 pub ts_event: UnixNanos,
56 pub ts_init: UnixNanos,
58}
59
60impl OrderBookDeltas {
61 #[must_use]
68 pub fn new(instrument_id: InstrumentId, deltas: Vec<OrderBookDelta>) -> Self {
69 Self::new_checked(instrument_id, deltas).expect(FAILED)
70 }
71
72 #[expect(
83 clippy::missing_panics_doc,
84 reason = "the unwrapped last element is guarded by the non-empty check"
85 )]
86 pub fn new_checked(
87 instrument_id: InstrumentId,
88 deltas: Vec<OrderBookDelta>,
89 ) -> anyhow::Result<Self> {
90 check_predicate_true(!deltas.is_empty(), "`deltas` cannot be empty")?;
91
92 let mismatch = deltas.iter().enumerate().find(|(_, delta)| {
93 instrument_id != delta.instrument_id
94 && (instrument_id.symbol.as_str() != delta.instrument_id.symbol.as_str()
95 || instrument_id.venue.as_str() != delta.instrument_id.venue.as_str())
96 });
97
98 if let Some((index, delta)) = mismatch {
99 check_predicate_true(
100 false,
101 &format!(
102 "`deltas` instrument IDs must match `instrument_id` {instrument_id}, but \
103 delta at index {index} of {} has {}",
104 deltas.len(),
105 delta.instrument_id,
106 ),
107 )?;
108 }
109 let last = deltas.last().expect("deltas not empty");
110 let flags = last.flags;
111 let sequence = last.sequence;
112 let ts_event = last.ts_event;
113 let ts_init = last.ts_init;
114 Ok(Self {
115 instrument_id,
116 deltas,
117 flags,
118 sequence,
119 ts_event,
120 ts_init,
121 })
122 }
123}
124
125impl PartialEq<Self> for OrderBookDeltas {
126 fn eq(&self, other: &Self) -> bool {
127 self.instrument_id == other.instrument_id && self.sequence == other.sequence
128 }
129}
130
131impl Eq for OrderBookDeltas {}
132
133impl Hash for OrderBookDeltas {
134 fn hash<H: Hasher>(&self, state: &mut H) {
135 self.instrument_id.hash(state);
136 self.sequence.hash(state);
137 }
138}
139
140impl Display for OrderBookDeltas {
141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142 write!(
143 f,
144 "{},len={},flags={},sequence={},ts_event={},ts_init={}",
145 self.instrument_id,
146 self.deltas.len(),
147 self.flags,
148 self.sequence,
149 self.ts_event,
150 self.ts_init
151 )
152 }
153}
154
155impl Serializable for OrderBookDeltas {}
156
157impl HasTsInit for OrderBookDeltas {
158 fn ts_init(&self) -> UnixNanos {
159 self.ts_init
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use std::{
166 collections::hash_map::DefaultHasher,
167 hash::{Hash, Hasher},
168 };
169
170 use nautilus_core::serialization::{
171 Serializable,
172 msgpack::{FromMsgPack, ToMsgPack},
173 };
174 use rstest::rstest;
175 use serde_json;
176
177 use super::*;
178 use crate::{
179 data::{order::BookOrder, stubs::stub_deltas},
180 enums::{BookAction, OrderSide},
181 types::{Price, Quantity},
182 };
183
184 fn create_test_delta() -> OrderBookDelta {
185 let instrument_id = InstrumentId::from("EURUSD.SIM");
186 OrderBookDelta::new(
187 instrument_id,
188 BookAction::Add,
189 BookOrder::new(
190 OrderSide::Buy,
191 Price::from("1.0500"),
192 Quantity::from("100000"),
193 1,
194 ),
195 0,
196 123,
197 UnixNanos::from(1_000_000_000),
198 UnixNanos::from(2_000_000_000),
199 )
200 }
201
202 fn create_test_deltas() -> OrderBookDeltas {
203 let instrument_id = InstrumentId::from("EURUSD.SIM");
204 let flags = 32;
205 let sequence = 123;
206 let ts_event = UnixNanos::from(1_000_000_000);
207 let ts_init = UnixNanos::from(2_000_000_000);
208
209 let delta1 = OrderBookDelta::new(
210 instrument_id,
211 BookAction::Add,
212 BookOrder::new(
213 OrderSide::Sell,
214 Price::from("1.0520"),
215 Quantity::from("50000"),
216 1,
217 ),
218 flags,
219 sequence,
220 ts_event,
221 ts_init,
222 );
223 let delta2 = OrderBookDelta::new(
224 instrument_id,
225 BookAction::Add,
226 BookOrder::new(
227 OrderSide::Buy,
228 Price::from("1.0500"),
229 Quantity::from("75000"),
230 2,
231 ),
232 flags,
233 sequence,
234 ts_event,
235 ts_init,
236 );
237
238 OrderBookDeltas::new(instrument_id, vec![delta1, delta2])
239 }
240
241 fn create_test_deltas_multiple() -> OrderBookDeltas {
242 let instrument_id = InstrumentId::from("GBPUSD.SIM");
243 let flags = 16;
244 let sequence = 456;
245 let ts_event = UnixNanos::from(3_000_000_000);
246 let ts_init = UnixNanos::from(4_000_000_000);
247
248 let deltas = vec![
249 OrderBookDelta::clear(instrument_id, sequence, ts_event, ts_init),
250 OrderBookDelta::new(
251 instrument_id,
252 BookAction::Add,
253 BookOrder::new(
254 OrderSide::Sell,
255 Price::from("1.2550"),
256 Quantity::from("100000"),
257 1,
258 ),
259 flags,
260 sequence,
261 ts_event,
262 ts_init,
263 ),
264 OrderBookDelta::new(
265 instrument_id,
266 BookAction::Update,
267 BookOrder::new(
268 OrderSide::Buy,
269 Price::from("1.2530"),
270 Quantity::from("200000"),
271 2,
272 ),
273 flags,
274 sequence,
275 ts_event,
276 ts_init,
277 ),
278 OrderBookDelta::new(
279 instrument_id,
280 BookAction::Delete,
281 BookOrder::new(
282 OrderSide::Sell,
283 Price::from("1.2560"),
284 Quantity::from("0"),
285 3,
286 ),
287 flags,
288 sequence,
289 ts_event,
290 ts_init,
291 ),
292 ];
293
294 OrderBookDeltas::new(instrument_id, deltas)
295 }
296
297 fn assert_book_order_fields(expected: &BookOrder, actual: &BookOrder) {
300 assert_eq!(expected.side, actual.side);
301 assert_eq!(expected.price, actual.price);
302 assert_eq!(expected.size, actual.size);
303 assert_eq!(expected.order_id, actual.order_id);
304 }
305
306 fn assert_order_book_delta_fields(expected: &OrderBookDelta, actual: &OrderBookDelta) {
307 assert_eq!(expected.instrument_id, actual.instrument_id);
308 assert_eq!(expected.action, actual.action);
309 assert_book_order_fields(&expected.order, &actual.order);
310 assert_eq!(expected.flags, actual.flags);
311 assert_eq!(expected.sequence, actual.sequence);
312 assert_eq!(expected.ts_event, actual.ts_event);
313 assert_eq!(expected.ts_init, actual.ts_init);
314 }
315
316 fn assert_order_book_deltas_fields(expected: &OrderBookDeltas, actual: &OrderBookDeltas) {
317 assert_eq!(expected.instrument_id, actual.instrument_id);
318 assert_eq!(expected.flags, actual.flags);
319 assert_eq!(expected.sequence, actual.sequence);
320 assert_eq!(expected.ts_event, actual.ts_event);
321 assert_eq!(expected.ts_init, actual.ts_init);
322 assert_eq!(expected.deltas.len(), actual.deltas.len());
323
324 for (expected_delta, actual_delta) in expected.deltas.iter().zip(&actual.deltas) {
325 assert_order_book_delta_fields(expected_delta, actual_delta);
326 }
327 }
328
329 #[rstest]
330 fn test_order_book_deltas_new() {
331 let deltas = create_test_deltas();
332
333 assert_eq!(deltas.instrument_id, InstrumentId::from("EURUSD.SIM"));
334 assert_eq!(deltas.deltas.len(), 2);
335 assert_eq!(deltas.flags, 32);
336 assert_eq!(deltas.sequence, 123);
337 assert_eq!(deltas.ts_event, UnixNanos::from(1_000_000_000));
338 assert_eq!(deltas.ts_init, UnixNanos::from(2_000_000_000));
339 }
340
341 #[rstest]
342 fn test_order_book_deltas_new_checked_valid() {
343 let instrument_id = InstrumentId::from("EURUSD.SIM");
344 let delta = create_test_delta();
345
346 let result = OrderBookDeltas::new_checked(instrument_id, vec![delta]);
347
348 assert!(result.is_ok());
349 let deltas = result.unwrap();
350 assert_eq!(deltas.instrument_id, instrument_id);
351 assert_eq!(deltas.deltas.len(), 1);
352 }
353
354 #[rstest]
355 fn test_order_book_deltas_new_checked_accepts_homogeneous_deltas() {
356 let instrument_id = InstrumentId::from("EURUSD.SIM");
357 let delta1 = create_test_delta();
358 let mut delta2 = create_test_delta();
359 delta2.sequence = 124;
360
361 let result = OrderBookDeltas::new_checked(instrument_id, vec![delta1, delta2]);
362
363 assert!(result.is_ok());
364 assert_eq!(result.unwrap().deltas.len(), 2);
365 }
366
367 #[rstest]
368 #[case::first(0)]
369 #[case::later(1)]
370 fn test_order_book_deltas_new_checked_rejects_mismatched_instrument(
371 #[case] mismatch_index: usize,
372 ) {
373 let instrument_id = InstrumentId::from("EURUSD.SIM");
374 let mut deltas = vec![create_test_delta(), create_test_delta()];
375 deltas[mismatch_index].instrument_id = InstrumentId::from("GBPUSD.SIM");
376
377 let result = OrderBookDeltas::new_checked(instrument_id, deltas);
378
379 assert_eq!(
380 result.unwrap_err().to_string(),
381 format!(
382 "`deltas` instrument IDs must match `instrument_id` EURUSD.SIM, but delta at \
383 index {mismatch_index} of 2 has GBPUSD.SIM"
384 )
385 );
386 }
387
388 #[rstest]
389 fn test_order_book_deltas_new_checked_empty_deltas() {
390 let instrument_id = InstrumentId::from("EURUSD.SIM");
391
392 let result = OrderBookDeltas::new_checked(instrument_id, vec![]);
393
394 assert!(result.is_err());
395 assert!(
396 result
397 .unwrap_err()
398 .to_string()
399 .contains("`deltas` cannot be empty")
400 );
401 }
402
403 #[rstest]
404 #[should_panic(expected = "Condition failed")]
405 fn test_order_book_deltas_new_empty_deltas_panics() {
406 let instrument_id = InstrumentId::from("EURUSD.SIM");
407 let _ = OrderBookDeltas::new(instrument_id, vec![]);
408 }
409
410 #[rstest]
411 fn test_order_book_deltas_uses_last_delta_properties() {
412 let instrument_id = InstrumentId::from("EURUSD.SIM");
413
414 let delta1 = OrderBookDelta::new(
415 instrument_id,
416 BookAction::Add,
417 BookOrder::new(
418 OrderSide::Buy,
419 Price::from("1.0500"),
420 Quantity::from("100000"),
421 1,
422 ),
423 16, 100, UnixNanos::from(500_000_000), UnixNanos::from(1_000_000_000), );
428
429 let delta2 = OrderBookDelta::new(
430 instrument_id,
431 BookAction::Add,
432 BookOrder::new(
433 OrderSide::Sell,
434 Price::from("1.0520"),
435 Quantity::from("50000"),
436 2,
437 ),
438 32, 200, UnixNanos::from(1_500_000_000), UnixNanos::from(2_000_000_000), );
443
444 let deltas = OrderBookDeltas::new(instrument_id, vec![delta1, delta2]);
445
446 assert_eq!(deltas.flags, 32);
448 assert_eq!(deltas.sequence, 200);
449 assert_eq!(deltas.ts_event, UnixNanos::from(1_500_000_000));
450 assert_eq!(deltas.ts_init, UnixNanos::from(2_000_000_000));
451 }
452
453 #[rstest]
454 fn test_order_book_deltas_hash_different_objects() {
455 let deltas1 = create_test_deltas();
456 let deltas2 = create_test_deltas_multiple();
457
458 let mut hasher1 = DefaultHasher::new();
459 let mut hasher2 = DefaultHasher::new();
460
461 deltas1.hash(&mut hasher1);
462 deltas2.hash(&mut hasher2);
463
464 assert_ne!(hasher1.finish(), hasher2.finish()); }
466
467 #[rstest]
468 fn test_order_book_deltas_hash_uses_instrument_id_and_sequence() {
469 let instrument_id = InstrumentId::from("EURUSD.SIM");
470 let sequence = 123u64;
471
472 let mut expected_hasher = DefaultHasher::new();
474 instrument_id.hash(&mut expected_hasher);
475 sequence.hash(&mut expected_hasher);
476 let expected_hash = expected_hasher.finish();
477
478 let delta = OrderBookDelta::new(
479 instrument_id,
480 BookAction::Add,
481 BookOrder::new(
482 OrderSide::Buy,
483 Price::from("1.0500"),
484 Quantity::from("100000"),
485 1,
486 ),
487 0,
488 sequence,
489 UnixNanos::from(1_000_000_000),
490 UnixNanos::from(2_000_000_000),
491 );
492
493 let deltas = OrderBookDeltas::new(instrument_id, vec![delta]);
494
495 let mut deltas_hasher = DefaultHasher::new();
496 deltas.hash(&mut deltas_hasher);
497
498 assert_eq!(deltas_hasher.finish(), expected_hash);
499 }
500
501 #[rstest]
502 fn test_order_book_deltas_display() {
503 let deltas = create_test_deltas();
504 let display_str = format!("{deltas}");
505
506 assert!(display_str.contains("EURUSD.SIM"));
507 assert!(display_str.contains("len=2"));
508 assert!(display_str.contains("flags=32"));
509 assert!(display_str.contains("sequence=123"));
510 assert!(display_str.contains("ts_event=1000000000"));
511 assert!(display_str.contains("ts_init=2000000000"));
512 }
513
514 #[rstest]
515 fn test_order_book_deltas_display_format() {
516 let deltas = create_test_deltas();
517 let expected =
518 "EURUSD.SIM,len=2,flags=32,sequence=123,ts_event=1000000000,ts_init=2000000000";
519
520 assert_eq!(format!("{deltas}"), expected);
521 }
522
523 #[rstest]
524 fn test_order_book_deltas_has_ts_init() {
525 let deltas = create_test_deltas();
526
527 assert_eq!(deltas.ts_init(), UnixNanos::from(2_000_000_000));
528 }
529
530 #[rstest]
531 fn test_order_book_deltas_clone() {
532 let deltas1 = create_test_deltas();
533 let deltas2 = deltas1.clone();
534
535 assert_eq!(deltas1.instrument_id, deltas2.instrument_id);
536 assert_eq!(deltas1.deltas.len(), deltas2.deltas.len());
537 assert_eq!(deltas1.flags, deltas2.flags);
538 assert_eq!(deltas1.sequence, deltas2.sequence);
539 assert_eq!(deltas1.ts_event, deltas2.ts_event);
540 assert_eq!(deltas1.ts_init, deltas2.ts_init);
541 assert_eq!(deltas1, deltas2);
542 }
543
544 #[rstest]
545 fn test_order_book_deltas_debug() {
546 let deltas = create_test_deltas();
547 let debug_str = format!("{deltas:?}");
548
549 assert!(debug_str.contains("OrderBookDeltas"));
550 assert!(debug_str.contains("EURUSD.SIM"));
551 assert!(debug_str.contains("flags: 32"));
552 assert!(debug_str.contains("sequence: 123"));
553 }
554
555 #[rstest]
556 fn test_order_book_deltas_serialization() {
557 let deltas = create_test_deltas();
558
559 let json = serde_json::to_string(&deltas).unwrap();
561 let deserialized: OrderBookDeltas = serde_json::from_str(&json).unwrap();
562
563 assert_eq!(deltas.instrument_id, deserialized.instrument_id);
564 assert_eq!(deltas.deltas.len(), deserialized.deltas.len());
565 assert_eq!(deltas.flags, deserialized.flags);
566 assert_eq!(deltas.sequence, deserialized.sequence);
567 assert_eq!(deltas.ts_event, deserialized.ts_event);
568 assert_eq!(deltas.ts_init, deserialized.ts_init);
569 }
570
571 #[rstest]
572 fn test_json_serialization(stub_deltas: OrderBookDeltas) {
573 let deltas = stub_deltas;
574 let serialized = deltas.to_json_bytes().unwrap();
575 let deserialized = OrderBookDeltas::from_json_bytes(serialized.as_ref()).unwrap();
576
577 assert_order_book_deltas_fields(&deltas, &deserialized);
578 }
579
580 #[rstest]
581 fn test_msgpack_serialization() {
582 let deltas = create_test_deltas_multiple();
583 let serialized = deltas.to_msgpack_bytes().unwrap();
584 let deserialized = OrderBookDeltas::from_msgpack_bytes(serialized.as_ref()).unwrap();
585
586 assert_order_book_deltas_fields(&deltas, &deserialized);
587 }
588
589 #[rstest]
590 fn test_order_book_deltas_single_delta() {
591 let delta = create_test_delta();
592 let instrument_id = delta.instrument_id;
593
594 let deltas = OrderBookDeltas::new(instrument_id, vec![delta]);
595
596 assert_eq!(deltas.instrument_id, instrument_id);
597 assert_eq!(deltas.deltas.len(), 1);
598 assert_eq!(deltas.flags, delta.flags);
599 assert_eq!(deltas.sequence, delta.sequence);
600 assert_eq!(deltas.ts_event, delta.ts_event);
601 assert_eq!(deltas.ts_init, delta.ts_init);
602 }
603
604 #[rstest]
605 fn test_order_book_deltas_large_number_of_deltas() {
606 let instrument_id = InstrumentId::from("ETHUSD.CRYPTO");
607 let mut delta_vec = Vec::new();
608
609 for i in 0..100 {
611 let delta = OrderBookDelta::new(
612 instrument_id,
613 BookAction::Add,
614 BookOrder::new(
615 OrderSide::Buy,
616 Price::from(&format!("1000.{i:02}")),
617 Quantity::from("1000"),
618 i as u64,
619 ),
620 0,
621 i as u64,
622 UnixNanos::from(1_000_000_000 + i as u64),
623 UnixNanos::from(2_000_000_000 + i as u64),
624 );
625 delta_vec.push(delta);
626 }
627
628 let deltas = OrderBookDeltas::new(instrument_id, delta_vec);
629
630 assert_eq!(deltas.deltas.len(), 100);
631 assert_eq!(deltas.sequence, 99); assert_eq!(deltas.ts_event, UnixNanos::from(1_000_000_000 + 99));
633 assert_eq!(deltas.ts_init, UnixNanos::from(2_000_000_000 + 99));
634 }
635
636 #[rstest]
637 fn test_order_book_deltas_different_action_types() {
638 let deltas = create_test_deltas_multiple();
639
640 assert_eq!(deltas.deltas.len(), 4);
641
642 assert_eq!(deltas.deltas[0].action, BookAction::Clear);
644 assert_eq!(deltas.deltas[1].action, BookAction::Add);
645 assert_eq!(deltas.deltas[2].action, BookAction::Update);
646 assert_eq!(deltas.deltas[3].action, BookAction::Delete);
647 }
648
649 #[rstest]
650 fn test_order_book_deltas_with_stub(stub_deltas: OrderBookDeltas) {
651 let deltas = stub_deltas;
652
653 assert_eq!(deltas.instrument_id, InstrumentId::from("AAPL.XNAS"));
654 assert_eq!(deltas.deltas.len(), 7);
655 assert_eq!(deltas.flags, 32);
656 assert_eq!(deltas.sequence, 0);
657 assert_eq!(deltas.ts_event, UnixNanos::from(1));
658 assert_eq!(deltas.ts_init, UnixNanos::from(2));
659 }
660
661 #[rstest]
662 fn test_display_with_stub(stub_deltas: OrderBookDeltas) {
663 let deltas = stub_deltas;
664 assert_eq!(
665 format!("{deltas}"),
666 "AAPL.XNAS,len=7,flags=32,sequence=0,ts_event=1,ts_init=2".to_string()
667 );
668 }
669
670 #[rstest]
671 fn test_order_book_deltas_zero_sequence() {
672 let instrument_id = InstrumentId::from("ZERO.TEST");
673 let delta = OrderBookDelta::new(
674 instrument_id,
675 BookAction::Add,
676 BookOrder::new(
677 OrderSide::Buy,
678 Price::from("100.0"),
679 Quantity::from("1000"),
680 1,
681 ),
682 0,
683 0, UnixNanos::from(0), UnixNanos::from(0),
686 );
687
688 let deltas = OrderBookDeltas::new(instrument_id, vec![delta]);
689
690 assert_eq!(deltas.sequence, 0);
691 assert_eq!(deltas.ts_event, UnixNanos::from(0));
692 assert_eq!(deltas.ts_init, UnixNanos::from(0));
693 }
694
695 #[rstest]
696 fn test_order_book_deltas_max_values() {
697 let instrument_id = InstrumentId::from("MAX.TEST");
698 let delta = OrderBookDelta::new(
699 instrument_id,
700 BookAction::Add,
701 BookOrder::new(
702 OrderSide::Buy,
703 Price::from("999999.99"),
704 Quantity::from("999999999"),
705 u64::MAX,
706 ),
707 u8::MAX,
708 u64::MAX,
709 UnixNanos::from(u64::MAX),
710 UnixNanos::from(u64::MAX),
711 );
712
713 let deltas = OrderBookDeltas::new(instrument_id, vec![delta]);
714
715 assert_eq!(deltas.flags, u8::MAX);
716 assert_eq!(deltas.sequence, u64::MAX);
717 assert_eq!(deltas.ts_event, UnixNanos::from(u64::MAX));
718 assert_eq!(deltas.ts_init, UnixNanos::from(u64::MAX));
719 }
720
721 #[rstest]
722 fn test_new() {
723 let instrument_id = InstrumentId::from("AAPL.XNAS");
724 let flags = 32; let sequence = 0;
726 let ts_event = 1;
727 let ts_init = 2;
728
729 let delta0 =
730 OrderBookDelta::clear(instrument_id, sequence, ts_event.into(), ts_init.into());
731 let delta1 = OrderBookDelta::new(
732 instrument_id,
733 BookAction::Add,
734 BookOrder::new(
735 OrderSide::Sell,
736 Price::from("102.00"),
737 Quantity::from("300"),
738 1,
739 ),
740 flags,
741 sequence,
742 ts_event.into(),
743 ts_init.into(),
744 );
745 let delta2 = OrderBookDelta::new(
746 instrument_id,
747 BookAction::Add,
748 BookOrder::new(
749 OrderSide::Sell,
750 Price::from("101.00"),
751 Quantity::from("200"),
752 2,
753 ),
754 flags,
755 sequence,
756 ts_event.into(),
757 ts_init.into(),
758 );
759 let delta3 = OrderBookDelta::new(
760 instrument_id,
761 BookAction::Add,
762 BookOrder::new(
763 OrderSide::Sell,
764 Price::from("100.00"),
765 Quantity::from("100"),
766 3,
767 ),
768 flags,
769 sequence,
770 ts_event.into(),
771 ts_init.into(),
772 );
773 let delta4 = OrderBookDelta::new(
774 instrument_id,
775 BookAction::Add,
776 BookOrder::new(
777 OrderSide::Buy,
778 Price::from("99.00"),
779 Quantity::from("100"),
780 4,
781 ),
782 flags,
783 sequence,
784 ts_event.into(),
785 ts_init.into(),
786 );
787 let delta5 = OrderBookDelta::new(
788 instrument_id,
789 BookAction::Add,
790 BookOrder::new(
791 OrderSide::Buy,
792 Price::from("98.00"),
793 Quantity::from("200"),
794 5,
795 ),
796 flags,
797 sequence,
798 ts_event.into(),
799 ts_init.into(),
800 );
801 let delta6 = OrderBookDelta::new(
802 instrument_id,
803 BookAction::Add,
804 BookOrder::new(
805 OrderSide::Buy,
806 Price::from("97.00"),
807 Quantity::from("300"),
808 6,
809 ),
810 flags,
811 sequence,
812 ts_event.into(),
813 ts_init.into(),
814 );
815
816 let deltas = OrderBookDeltas::new(
817 instrument_id,
818 vec![delta0, delta1, delta2, delta3, delta4, delta5, delta6],
819 );
820
821 assert_eq!(deltas.instrument_id, instrument_id);
822 assert_eq!(deltas.deltas.len(), 7);
823 assert_eq!(deltas.flags, flags);
824 assert_eq!(deltas.sequence, sequence);
825 assert_eq!(deltas.ts_event, ts_event);
826 assert_eq!(deltas.ts_init, ts_init);
827 }
828}