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"))]
62mod tests {
63 use nautilus_common::timer::{TimeEvent, TimeEventCallback};
64 use nautilus_core::UUID4;
65 use pyo3::{Py, Python, prelude::*, types::PyList};
66 use rstest::*;
67 use ustr::Ustr;
68
69 use super::*;
70
71 #[rstest]
72 fn test_accumulator_drain_sorted() {
73 pyo3::prepare_freethreaded_python();
74
75 Python::with_gil(|py| {
76 let py_list = PyList::empty(py);
77 let py_append = Py::from(py_list.getattr("append").unwrap());
78
79 let mut accumulator = TimeEventAccumulator::new();
80
81 let time_event1 = TimeEvent::new(
82 Ustr::from("TEST_EVENT_1"),
83 UUID4::new(),
84 100.into(),
85 100.into(),
86 );
87 let time_event2 = TimeEvent::new(
88 Ustr::from("TEST_EVENT_2"),
89 UUID4::new(),
90 300.into(),
91 300.into(),
92 );
93 let time_event3 = TimeEvent::new(
94 Ustr::from("TEST_EVENT_3"),
95 UUID4::new(),
96 200.into(),
97 200.into(),
98 );
99
100 let callback = TimeEventCallback::from(py_append.into_any());
104
105 let handler1 = TimeEventHandlerV2::new(time_event1.clone(), callback.clone());
106 let handler2 = TimeEventHandlerV2::new(time_event2.clone(), callback.clone());
107 let handler3 = TimeEventHandlerV2::new(time_event3.clone(), callback);
108
109 accumulator.event_handlers.push(handler1);
110 accumulator.event_handlers.push(handler2);
111 accumulator.event_handlers.push(handler3);
112
113 let drained_handlers = accumulator.drain();
114
115 assert_eq!(drained_handlers.len(), 3);
116 assert_eq!(drained_handlers[0].event.ts_event, time_event1.ts_event);
117 assert_eq!(drained_handlers[1].event.ts_event, time_event3.ts_event);
118 assert_eq!(drained_handlers[2].event.ts_event, time_event2.ts_event);
119 });
120 }
121}