优化分钟历史窗口读取并移除滚动双口径
This commit is contained in:
@@ -1174,6 +1174,7 @@ pub struct DataSet {
|
||||
candidate_symbol_ids_by_date: Arc<BTreeMap<NaiveDate, Vec<u32>>>,
|
||||
corporate_actions_by_date: Arc<BTreeMap<NaiveDate, Vec<CorporateAction>>>,
|
||||
execution_quotes_by_date: Arc<HashMap<NaiveDate, HashMap<String, Vec<IntradayExecutionQuote>>>>,
|
||||
execution_quote_dates: Arc<Vec<NaiveDate>>,
|
||||
order_book_depth_index: Arc<HashMap<(NaiveDate, String), Vec<IntradayOrderBookDepthLevel>>>,
|
||||
benchmark_by_date: Arc<BTreeMap<NaiveDate, BenchmarkSnapshot>>,
|
||||
market_series_by_symbol: Arc<AHashMap<String, Arc<SymbolPriceSeries>>>,
|
||||
@@ -1441,6 +1442,8 @@ impl DataSet {
|
||||
}
|
||||
let corporate_actions_by_date = group_by_date(corporate_actions, |item| item.date);
|
||||
let execution_quotes_by_date = build_execution_quote_index(execution_quotes);
|
||||
let mut execution_quote_dates = execution_quotes_by_date.keys().copied().collect::<Vec<_>>();
|
||||
execution_quote_dates.sort_unstable();
|
||||
let order_book_depth_index = build_order_book_depth_index(order_book_depth);
|
||||
|
||||
let benchmark_by_date = benchmarks
|
||||
@@ -1464,6 +1467,7 @@ impl DataSet {
|
||||
candidate_symbol_ids_by_date: Arc::new(candidate_symbol_ids_by_date),
|
||||
corporate_actions_by_date: Arc::new(corporate_actions_by_date),
|
||||
execution_quotes_by_date: Arc::new(execution_quotes_by_date),
|
||||
execution_quote_dates: Arc::new(execution_quote_dates),
|
||||
order_book_depth_index: Arc::new(order_book_depth_index),
|
||||
benchmark_by_date: Arc::new(benchmark_by_date),
|
||||
market_series_by_symbol: Arc::new(market_series_by_symbol),
|
||||
@@ -1648,9 +1652,14 @@ impl DataSet {
|
||||
.push(quote);
|
||||
}
|
||||
let mut added = 0usize;
|
||||
let mut new_dates = Vec::new();
|
||||
let execution_quotes_by_date = Arc::make_mut(&mut self.execution_quotes_by_date);
|
||||
for (date, rows_by_symbol) in grouped {
|
||||
let date_is_new = !execution_quotes_by_date.contains_key(&date);
|
||||
let target_by_symbol = execution_quotes_by_date.entry(date).or_default();
|
||||
if date_is_new {
|
||||
new_dates.push(date);
|
||||
}
|
||||
for (symbol, mut incoming) in rows_by_symbol {
|
||||
incoming.sort_by_key(|quote| quote.timestamp);
|
||||
incoming.dedup_by(|left, right| left.timestamp == right.timestamp);
|
||||
@@ -1688,6 +1697,14 @@ impl DataSet {
|
||||
*target = merged;
|
||||
}
|
||||
}
|
||||
if !new_dates.is_empty() {
|
||||
let dates = Arc::make_mut(&mut self.execution_quote_dates);
|
||||
for date in new_dates {
|
||||
if let Err(index) = dates.binary_search(&date) {
|
||||
dates.insert(index, date);
|
||||
}
|
||||
}
|
||||
}
|
||||
added
|
||||
}
|
||||
|
||||
@@ -1744,10 +1761,18 @@ impl DataSet {
|
||||
}
|
||||
|
||||
pub fn remove_execution_quotes_on_date(&mut self, date: NaiveDate) -> usize {
|
||||
Arc::make_mut(&mut self.execution_quotes_by_date)
|
||||
.remove(&date)
|
||||
.map(|rows_by_symbol| rows_by_symbol.into_values().map(|rows| rows.len()).sum())
|
||||
.unwrap_or_default()
|
||||
let removed = Arc::make_mut(&mut self.execution_quotes_by_date).remove(&date);
|
||||
let Some(rows_by_symbol) = removed else {
|
||||
return 0;
|
||||
};
|
||||
let dates = Arc::make_mut(&mut self.execution_quote_dates);
|
||||
if let Ok(index) = dates.binary_search(&date) {
|
||||
dates.remove(index);
|
||||
}
|
||||
rows_by_symbol
|
||||
.into_values()
|
||||
.map(|rows| rows.len())
|
||||
.sum()
|
||||
}
|
||||
|
||||
pub fn snapshot_components(&self) -> DataSetSnapshotComponents {
|
||||
@@ -1901,16 +1926,29 @@ impl DataSet {
|
||||
if bar_count == 0 {
|
||||
return Vec::new();
|
||||
}
|
||||
let mut quotes = self
|
||||
.execution_quotes_by_date
|
||||
.values()
|
||||
.filter_map(|rows_by_symbol| rows_by_symbol.get(symbol))
|
||||
.flat_map(|rows| rows.iter())
|
||||
.filter(|quote| intraday_quote_visible(quote, date, active_datetime, include_now))
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
quotes.sort_by_key(|quote| quote.timestamp);
|
||||
take_last(quotes, bar_count)
|
||||
let end = self
|
||||
.execution_quote_dates
|
||||
.partition_point(|quote_date| *quote_date <= date);
|
||||
let mut quotes = Vec::with_capacity(bar_count);
|
||||
'dates: for quote_date in self.execution_quote_dates[..end].iter().rev() {
|
||||
let Some(rows) = self
|
||||
.execution_quotes_by_date
|
||||
.get(quote_date)
|
||||
.and_then(|rows_by_symbol| rows_by_symbol.get(symbol))
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
for quote in rows.iter().rev() {
|
||||
if intraday_quote_visible(quote, date, active_datetime, include_now) {
|
||||
quotes.push(quote.clone());
|
||||
if quotes.len() == bar_count {
|
||||
break 'dates;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
quotes.reverse();
|
||||
quotes
|
||||
}
|
||||
|
||||
pub fn trading_dates(&self, start: NaiveDate, end: NaiveDate) -> Vec<NaiveDate> {
|
||||
@@ -3396,13 +3434,6 @@ fn normalize_history_frequency(frequency: &str) -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn take_last<T>(mut rows: Vec<T>, count: usize) -> Vec<T> {
|
||||
if rows.len() <= count {
|
||||
return rows;
|
||||
}
|
||||
rows.split_off(rows.len() - count)
|
||||
}
|
||||
|
||||
fn group_by_date<T, F>(rows: Vec<T>, mut date_of: F) -> BTreeMap<NaiveDate, Vec<T>>
|
||||
where
|
||||
F: FnMut(&T) -> NaiveDate,
|
||||
@@ -3864,6 +3895,10 @@ mod tests {
|
||||
&data.execution_quotes_by_date,
|
||||
&run_data.execution_quotes_by_date
|
||||
));
|
||||
assert!(Arc::ptr_eq(
|
||||
&data.execution_quote_dates,
|
||||
&run_data.execution_quote_dates
|
||||
));
|
||||
|
||||
run_data.add_execution_quotes(vec![IntradayExecutionQuote {
|
||||
date,
|
||||
@@ -3886,6 +3921,10 @@ mod tests {
|
||||
&data.execution_quotes_by_date,
|
||||
&run_data.execution_quotes_by_date
|
||||
));
|
||||
assert!(!Arc::ptr_eq(
|
||||
&data.execution_quote_dates,
|
||||
&run_data.execution_quote_dates
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user