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