1use std::{collections::VecDeque, sync::Arc};
2
3use futures_util::{StreamExt as _, stream::LocalBoxStream};
4
5use crate::{
6 Candlestick, CandlestickItem, Error, Event, TimeFrame,
7 data_provider::InternalProviderError,
8 instance::{ExecuteMode, Instance},
9};
10
11enum Phase {
12 SendScriptInfo,
13 Running,
14 FinalConfirm,
15 Done,
16}
17
18pub struct RunHandle {
41 instance: Instance,
42 stream: Option<LocalBoxStream<'static, Result<CandlestickItem, InternalProviderError>>>,
43 pending: VecDeque<Event>,
44 pending_realtime: Option<Candlestick>,
45 last_confirmed: bool,
46 realtime_mode: bool,
50 phase: Phase,
51 initial_error: Option<Error>,
57}
58
59impl RunHandle {
60 pub(crate) fn new(
61 instance: Instance,
62 symbol: String,
63 from_time: i64,
64 timeframe: TimeFrame,
65 ) -> Self {
66 let (stream, initial_error) = match instance
67 .data_provider
68 .as_ref()
69 .map(|p| p.candlesticks(&symbol, timeframe, from_time, None))
70 {
71 None => (None, None),
72 Some(Ok(s)) => (Some(s), None),
73 Some(Err(e)) => (
74 None,
75 Some(Error::DataProvider {
76 message: e.to_string(),
77 }),
78 ),
79 };
80 let phase = if stream.is_some() {
81 Phase::SendScriptInfo
82 } else {
83 Phase::Done
84 };
85 Self {
86 instance,
87 stream,
88 pending: VecDeque::new(),
89 pending_realtime: None,
90 last_confirmed: true,
91 realtime_mode: false,
92 phase,
93 initial_error,
94 }
95 }
96
97 #[inline]
99 pub fn into_instance(self) -> Instance {
100 self.instance
101 }
102
103 fn drain_instance_events(&mut self) {
104 self.pending.extend(self.instance.events.drain(..));
105 }
106
107 fn should_split_realtime(&self, candlestick: &Candlestick) -> bool {
108 matches!(
109 self.instance.candlesticks.last(),
110 Some(last_candlestick)
111 if last_candlestick.time != candlestick.time && !self.instance.last_bar_confirmed
112 )
113 }
114
115 pub async fn next_event(&mut self) -> Option<Result<Event, Error>> {
118 if let Some(e) = self.initial_error.take() {
119 return Some(Err(e));
120 }
121 loop {
122 if let Some(event) = self.pending.pop_front() {
123 return Some(Ok(event));
124 }
125 if let Some(candlestick) = self.pending_realtime.take() {
126 if !self.instance.mtf_wait.is_zero()
127 && let Err(e) = self.instance.pre_drain_sub_streams().await
128 {
129 return Some(Err(Error::DataProvider {
130 message: e.to_string(),
131 }));
132 }
133 self.last_confirmed = false;
134 if let Err(e) = self
135 .instance
136 .execute(ExecuteMode::Realtime(candlestick))
137 .await
138 {
139 return Some(Err(e));
140 }
141 self.drain_instance_events();
142 continue;
143 }
144 match self.phase {
145 Phase::Done => return None,
146
147 Phase::SendScriptInfo => {
148 let event = Event::SessionInfo {
149 script_info: Arc::clone(&self.instance.script_info),
150 symbol_info: Box::new(self.instance.symbol_info.clone()),
151 };
152 let warnings = self.instance.warnings();
153 self.phase = Phase::Running;
154 if !warnings.is_empty() {
155 self.pending.push_back(Event::Warning(warnings));
156 }
157 return Some(Ok(event));
158 }
159
160 Phase::Running => {
161 let raw = match self.stream.as_mut() {
165 Some(s) => s.next().await,
166 None => None,
167 };
168 let Some(result) = raw else {
169 if !self.last_confirmed {
170 self.phase = Phase::FinalConfirm;
171 continue;
172 }
173 self.phase = Phase::Done;
174 return None;
175 };
176 let item = match result {
177 Ok(item) => item,
178 Err(e) => {
179 return Some(Err(Error::DataProvider {
180 message: e.to_string(),
181 }));
182 }
183 };
184 match item {
185 CandlestickItem::HistoryEnd => {
186 self.realtime_mode = true;
187 self.pending.push_back(Event::HistoryEnd);
188 }
189 CandlestickItem::Bar(c) if !self.realtime_mode => {
190 self.last_confirmed = true;
191 if let Err(e) = self.instance.execute(ExecuteMode::Confirmed(c)).await {
192 return Some(Err(e));
193 }
194 }
195 CandlestickItem::Bar(c) => {
196 if self.should_split_realtime(&c) {
197 if let Err(e) = self.instance.execute(ExecuteMode::Confirm).await {
198 return Some(Err(e));
199 }
200 self.last_confirmed = true;
201 self.pending_realtime = Some(c);
202 } else {
203 if !self.instance.mtf_wait.is_zero()
204 && let Err(e) = self.instance.pre_drain_sub_streams().await
205 {
206 return Some(Err(Error::DataProvider {
207 message: e.to_string(),
208 }));
209 }
210 self.last_confirmed = false;
211 if let Err(e) =
212 self.instance.execute(ExecuteMode::Realtime(c)).await
213 {
214 return Some(Err(e));
215 }
216 }
217 }
218 }
219 self.drain_instance_events();
220 }
221
222 Phase::FinalConfirm => {
223 if let Err(e) = self.instance.execute(ExecuteMode::Confirm).await {
224 return Some(Err(e));
225 }
226 self.drain_instance_events();
227 self.phase = Phase::Done;
228 }
229 }
230 }
231 }
232}
233
234impl std::ops::Deref for RunHandle {
235 type Target = Instance;
236
237 fn deref(&self) -> &Instance {
238 &self.instance
239 }
240}
241
242impl std::ops::DerefMut for RunHandle {
243 fn deref_mut(&mut self) -> &mut Instance {
244 &mut self.instance
245 }
246}