nautilus_backtest/
accumulator.rs1use nautilus_common::{clock::TestClock, timer::TimeEventHandlerV2};
17use nautilus_core::UnixNanos;
18
19#[derive(Debug)]
21pub struct TimeEventAccumulator {
22 event_handlers: Vec<TimeEventHandlerV2>,
23}
24
25impl TimeEventAccumulator {
26 #[must_use]
28 pub const fn new() -> Self {
29 Self {
30 event_handlers: Vec::new(),
31 }
32 }
33
34 pub fn advance_clock(&mut self, clock: &mut TestClock, to_time_ns: UnixNanos, set_time: bool) {
36 let events = clock.advance_time(to_time_ns, set_time);
37 let handlers = clock.match_handlers(events);
38 self.event_handlers.extend(handlers);
39 }
40
41 pub fn drain(&mut self) -> Vec<TimeEventHandlerV2> {
43 self.event_handlers
46 .sort_unstable_by_key(|v| v.event.ts_event);
47 self.event_handlers.drain(..).collect()
48 }
49}
50
51impl Default for TimeEventAccumulator {
52 fn default() -> Self {
54 Self::new()
55 }
56}
57
58#[cfg(all(test, feature = "python"))]
59mod tests {
60 use nautilus_common::timer::{TimeEvent, TimeEventCallback};
61 use nautilus_core::UUID4;
62 use pyo3::{Py, Python, prelude::*, types::PyList};
63 use rstest::*;
64 use ustr::Ustr;
65
66 use super::*;
67
68 #[rstest]
69 fn test_accumulator_drain_sorted() {
70 Python::initialize();
71 Python::attach(|py| {
72 let py_list = PyList::empty(py);
73 let py_append = Py::from(py_list.getattr("append").unwrap());
74
75 let mut accumulator = TimeEventAccumulator::new();
76
77 let time_event1 = TimeEvent::new(
78 Ustr::from("TEST_EVENT_1"),
79 UUID4::new(),
80 100.into(),
81 100.into(),
82 );
83 let time_event2 = TimeEvent::new(
84 Ustr::from("TEST_EVENT_2"),
85 UUID4::new(),
86 300.into(),
87 300.into(),
88 );
89 let time_event3 = TimeEvent::new(
90 Ustr::from("TEST_EVENT_3"),
91 UUID4::new(),
92 200.into(),
93 200.into(),
94 );
95
96 let callback = TimeEventCallback::from(py_append.into_any());
100
101 let handler1 = TimeEventHandlerV2::new(time_event1.clone(), callback.clone());
102 let handler2 = TimeEventHandlerV2::new(time_event2.clone(), callback.clone());
103 let handler3 = TimeEventHandlerV2::new(time_event3.clone(), callback);
104
105 accumulator.event_handlers.push(handler1);
106 accumulator.event_handlers.push(handler2);
107 accumulator.event_handlers.push(handler3);
108
109 let drained_handlers = accumulator.drain();
110
111 assert_eq!(drained_handlers.len(), 3);
112 assert_eq!(drained_handlers[0].event.ts_event, time_event1.ts_event);
113 assert_eq!(drained_handlers[1].event.ts_event, time_event3.ts_event);
114 assert_eq!(drained_handlers[2].event.ts_event, time_event2.ts_event);
115 });
116 }
117}