diff --git a/crates/fidc-core/src/data.rs b/crates/fidc-core/src/data.rs index c4f3e94..92e9995 100644 --- a/crates/fidc-core/src/data.rs +++ b/crates/fidc-core/src/data.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; use std::cmp::Reverse; -use std::collections::{BTreeMap, BinaryHeap, HashMap, HashSet}; +use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet}; use std::sync::{Arc, OnceLock}; use ahash::AHashMap; @@ -1692,11 +1692,24 @@ impl DataSet { } pub fn execution_quotes_on_date(&self, date: NaiveDate) -> Vec { + self.execution_quotes_on_date_for_symbols(date, None) + } + + pub fn execution_quotes_on_date_for_symbols( + &self, + date: NaiveDate, + symbols: Option<&BTreeSet>, + ) -> Vec { let Some(rows_by_symbol) = self.execution_quotes_by_date.get(&date) else { return Vec::new(); }; let mut streams = rows_by_symbol .iter() + .filter(|(symbol, _)| { + symbols + .map(|allowed_symbols| allowed_symbols.contains(*symbol)) + .unwrap_or(true) + }) .map(|(symbol, rows)| (symbol.as_str(), rows.as_slice())) .collect::>(); streams.sort_by_key(|(symbol, _)| *symbol); @@ -3929,6 +3942,19 @@ mod tests { ] ); assert_eq!(merged[2].last_price, 10.0); + let allowed_symbols = BTreeSet::from(["000001.SZ".to_string()]); + let filtered = run_data.execution_quotes_on_date_for_symbols(date, Some(&allowed_symbols)); + assert_eq!( + filtered + .iter() + .map(|row| (row.timestamp.time().to_string(), row.symbol.clone())) + .collect::>(), + vec![ + ("09:30:00".to_string(), "000001.SZ".to_string()), + ("09:31:00".to_string(), "000001.SZ".to_string()), + ("09:32:00".to_string(), "000001.SZ".to_string()), + ] + ); assert_eq!(run_data.remove_execution_quotes_on_date(date), 5); assert_eq!(run_data.execution_quote_count(), 0); } diff --git a/crates/fidc-core/src/engine.rs b/crates/fidc-core/src/engine.rs index 255834c..090090a 100644 --- a/crates/fidc-core/src/engine.rs +++ b/crates/fidc-core/src/engine.rs @@ -2529,15 +2529,10 @@ where &mut minute_symbols, )?; } - let filter_by_subscription = !self.subscriptions.is_empty(); - let minute_quotes = self - .data - .execution_quotes_on_date(execution_date) - .into_iter() - .filter(|quote| { - !filter_by_subscription || self.subscriptions.contains("e.symbol) - }) - .collect::>(); + let minute_quotes = self.data.execution_quotes_on_date_for_symbols( + execution_date, + (!self.subscriptions.is_empty()).then_some(&self.subscriptions), + ); let requires_minute_callbacks = self.strategy.requires_minute_callbacks(); let has_minute_process_listeners = self.process_event_bus.has_listeners_for(&[ ProcessEventKind::PreMinute,