From 7503dc8517b106fe571e477cb23da39e486e010b Mon Sep 17 00:00:00 2001 From: boris Date: Mon, 24 Aug 2026 19:48:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=B1=E4=BA=AB=E5=9B=9E=E6=B5=8B=E5=8F=AA?= =?UTF-8?q?=E8=AF=BB=E6=95=B0=E6=8D=AE=E7=B4=A2=E5=BC=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/fidc-core/src/data.rs | 100 ++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 24 deletions(-) diff --git a/crates/fidc-core/src/data.rs b/crates/fidc-core/src/data.rs index b52ecf5..fb6d9f7 100644 --- a/crates/fidc-core/src/data.rs +++ b/crates/fidc-core/src/data.rs @@ -1123,29 +1123,29 @@ impl BenchmarkPriceSeries { #[derive(Debug, Clone)] pub struct DataSet { - instruments: HashMap, - calendar: TradingCalendar, - market_by_date: BTreeMap>>, + instruments: Arc>, + calendar: Arc, + market_by_date: Arc>>>, market_symbol_ids_by_date: Arc>>, - factor_by_date: BTreeMap>>, + factor_by_date: Arc>>>, factor_symbol_ids_by_date: Arc>>, - factor_text_by_date: BTreeMap>, - factor_text_index: HashMap<(NaiveDate, String, String), FactorTextValue>, - candidate_by_date: BTreeMap>>, + factor_text_by_date: Arc>>, + factor_text_index: Arc>, + candidate_by_date: Arc>>>, candidate_symbol_ids_by_date: Arc>>, - corporate_actions_by_date: BTreeMap>, + corporate_actions_by_date: Arc>>, execution_quotes_by_date: HashMap>>, - order_book_depth_index: HashMap<(NaiveDate, String), Vec>, - benchmark_by_date: BTreeMap, + order_book_depth_index: Arc>>, + benchmark_by_date: Arc>, market_series_by_symbol: Arc>>, adjusted_close_series_by_symbol: Arc>>, market_series_by_symbol_id: Arc>>>, adjusted_close_series_by_symbol_id: Arc>>>, - benchmark_series_cache: BenchmarkPriceSeries, + benchmark_series_cache: Arc, symbol_id_by_code: Arc>, eligible_universe_by_date: Arc>>>, benchmark_code: String, - futures_params_by_symbol: HashMap>, + futures_params_by_symbol: Arc>>, } impl DataSet { @@ -1394,29 +1394,29 @@ impl DataSet { let futures_params_by_symbol = build_futures_params_index(futures_params); Ok(Self { - instruments, - calendar, - market_by_date, + instruments: Arc::new(instruments), + calendar: Arc::new(calendar), + market_by_date: Arc::new(market_by_date), market_symbol_ids_by_date: Arc::new(market_symbol_ids_by_date), - factor_by_date, + factor_by_date: Arc::new(factor_by_date), factor_symbol_ids_by_date: Arc::new(factor_symbol_ids_by_date), - factor_text_by_date, - factor_text_index, - candidate_by_date, + factor_text_by_date: Arc::new(factor_text_by_date), + factor_text_index: Arc::new(factor_text_index), + candidate_by_date: Arc::new(candidate_by_date), candidate_symbol_ids_by_date: Arc::new(candidate_symbol_ids_by_date), - corporate_actions_by_date, + corporate_actions_by_date: Arc::new(corporate_actions_by_date), execution_quotes_by_date, - order_book_depth_index, - benchmark_by_date, + 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), adjusted_close_series_by_symbol: Arc::new(adjusted_close_series_by_symbol), market_series_by_symbol_id: Arc::new(market_series_by_symbol_id), adjusted_close_series_by_symbol_id: Arc::new(adjusted_close_series_by_symbol_id), - benchmark_series_cache, + benchmark_series_cache: Arc::new(benchmark_series_cache), symbol_id_by_code: Arc::new(symbol_id_by_code), eligible_universe_by_date: Arc::new(OnceLock::new()), benchmark_code, - futures_params_by_symbol, + futures_params_by_symbol: Arc::new(futures_params_by_symbol), }) } @@ -3709,6 +3709,58 @@ mod tests { } } + #[test] + fn dataset_clone_shares_immutable_base_and_isolates_execution_quotes() { + let date = NaiveDate::parse_from_str("2025-01-02", "%Y-%m-%d").unwrap(); + let data = DataSet::from_components( + vec![Instrument { + symbol: "000001.SZ".to_string(), + name: "平安银行".to_string(), + board: "SZ".to_string(), + round_lot: 100, + listed_at: None, + delisted_at: None, + status: "active".to_string(), + }], + vec![market_row("2025-01-02", 10.0, 1_000_000)], + Vec::new(), + Vec::new(), + vec![benchmark_row("2025-01-02", 12.0)], + ) + .unwrap(); + let mut run_data = data.clone(); + + assert!(Arc::ptr_eq(&data.instruments, &run_data.instruments)); + assert!(Arc::ptr_eq(&data.market_by_date, &run_data.market_by_date)); + assert!(Arc::ptr_eq(&data.factor_by_date, &run_data.factor_by_date)); + assert!(Arc::ptr_eq( + &data.candidate_by_date, + &run_data.candidate_by_date + )); + assert!(Arc::ptr_eq( + &data.benchmark_by_date, + &run_data.benchmark_by_date + )); + + run_data.add_execution_quotes(vec![IntradayExecutionQuote { + date, + timestamp: NaiveDateTime::parse_from_str("2025-01-02 10:18:00", "%Y-%m-%d %H:%M:%S") + .unwrap(), + symbol: "000001.SZ".to_string(), + last_price: 10.01, + bid1: 10.0, + ask1: 10.01, + bid1_volume: 10_000, + ask1_volume: 10_000, + volume_delta: 10_000, + amount_delta: 100_100.0, + trading_phase: Some("continuous".to_string()), + }]); + + assert_eq!(data.execution_quote_count(), 0); + assert_eq!(run_data.execution_quote_count(), 1); + } + #[test] fn baseline_selection_uses_structured_instrument_dates_and_status_only() { let date = NaiveDate::parse_from_str("2025-01-02", "%Y-%m-%d").unwrap();