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