From 1703a7aa5eecaded231ce9adbf8a5b6abf59b1b1 Mon Sep 17 00:00:00 2001 From: boris Date: Wed, 9 Sep 2026 05:49:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=9D=E7=95=99=E5=B7=B2=E6=9C=89=E8=A1=8C?= =?UTF-8?q?=E6=83=85=E5=92=8C=E7=AD=96=E7=95=A5=E4=BB=A3=E7=A0=81=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/fidc-core/src/data.rs | 63 +++++++++---------- crates/fidc-core/src/engine.rs | 8 +-- .../fidc-core/src/platform_expr_strategy.rs | 49 +++++++-------- 3 files changed, 54 insertions(+), 66 deletions(-) diff --git a/crates/fidc-core/src/data.rs b/crates/fidc-core/src/data.rs index de3a361..3d766bb 100644 --- a/crates/fidc-core/src/data.rs +++ b/crates/fidc-core/src/data.rs @@ -1850,9 +1850,9 @@ impl DataSet { .iter() .enumerate() .filter_map(|(symbol_id, series)| { - series.as_ref().map(|series| { - (symbol_by_id[symbol_id].to_string(), Arc::clone(series)) - }) + series + .as_ref() + .map(|series| (symbol_by_id[symbol_id].to_string(), Arc::clone(series))) }) .collect::>(); @@ -1876,9 +1876,9 @@ impl DataSet { .iter() .enumerate() .filter_map(|(symbol_id, series)| { - series.as_ref().map(|series| { - (symbol_by_id[symbol_id].to_string(), Arc::clone(series)) - }) + series + .as_ref() + .map(|series| (symbol_by_id[symbol_id].to_string(), Arc::clone(series))) }) .collect::>(); let factor_texts = factor_texts @@ -1900,16 +1900,10 @@ impl DataSet { let factor_market_cap_order_by_date = build_factor_market_cap_order(&factor_by_date, &factor_symbol_ids_by_date); - let market_row_positions_by_date = build_dense_row_positions( - &market_by_date, - &market_symbol_ids_by_date, - symbol_count, - ); - let factor_row_positions_by_date = build_dense_row_positions( - &factor_by_date, - &factor_symbol_ids_by_date, - symbol_count, - ); + let market_row_positions_by_date = + build_dense_row_positions(&market_by_date, &market_symbol_ids_by_date, symbol_count); + let factor_row_positions_by_date = + build_dense_row_positions(&factor_by_date, &factor_symbol_ids_by_date, symbol_count); let candidate_row_positions_by_date = build_dense_row_positions( &candidate_by_date, &candidate_symbol_ids_by_date, @@ -2321,7 +2315,10 @@ impl DataSet { } for (component, strong_count) in [ - ("daily market panel", Arc::strong_count(&self.market_by_date)), + ( + "daily market panel", + Arc::strong_count(&self.market_by_date), + ), ( "market series by symbol", Arc::strong_count(&self.market_series_by_symbol), @@ -2456,7 +2453,8 @@ impl DataSet { .flat_map(|rows_by_symbol| rows_by_symbol.values()) .map(Vec::len) .sum(); - let mut execution_quote_dates = execution_quotes_by_date.keys().copied().collect::>(); + let mut execution_quote_dates = + execution_quotes_by_date.keys().copied().collect::>(); execution_quote_dates.sort_unstable(); self.execution_quotes_by_date = Arc::new(execution_quotes_by_date); self.execution_quote_dates = Arc::new(execution_quote_dates); @@ -5221,10 +5219,7 @@ mod tests { [data.symbol_id("000001.SZ").unwrap() as usize] .as_ref() .unwrap(); - assert!(!Arc::ptr_eq( - &market_series_before, - market_series_after - )); + assert!(!Arc::ptr_eq(&market_series_before, market_series_after)); assert!(Arc::ptr_eq(&daily_base_before, &market_series_after.base)); assert_eq!( serde_json::to_value(market_series_after.snapshot_at(0)).unwrap(), @@ -6178,11 +6173,8 @@ mod tests { let date = NaiveDate::parse_from_str("2025-01-02", "%Y-%m-%d").unwrap(); let quote = IntradayExecutionQuote { date, - timestamp: NaiveDateTime::parse_from_str( - "2025-01-02 10:18:00", - "%Y-%m-%d %H:%M:%S", - ) - .unwrap(), + 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.0, bid1: 10.0, @@ -6365,13 +6357,16 @@ mod tests { "'adjustment_factor_backward1'", ] { for typed_value in [None, Some(1.0)] { - assert!(matches!( - normalize_factor_snapshots(vec![snapshot( - typed_value, - BTreeMap::from([(Cow::Borrowed(field), 2.0)]), - )]), - Err(DataSetError::ReservedTypedFactorInExtraMap { .. }) - ), "reserved alias accepted: {field}"); + assert!( + matches!( + normalize_factor_snapshots(vec![snapshot( + typed_value, + BTreeMap::from([(Cow::Borrowed(field), 2.0)]), + )]), + Err(DataSetError::ReservedTypedFactorInExtraMap { .. }) + ), + "reserved alias accepted: {field}" + ); } } } diff --git a/crates/fidc-core/src/engine.rs b/crates/fidc-core/src/engine.rs index 5cd3cd1..3ec4ce3 100644 --- a/crates/fidc-core/src/engine.rs +++ b/crates/fidc-core/src/engine.rs @@ -454,8 +454,7 @@ pub struct BacktestEngine { futures_cost_model: FuturesTransactionCostModel, futures_validation_config: FuturesValidationConfig, execution_quote_loader: Option, - preplanned_decision_quote_symbols_by_date: - Option>>>, + preplanned_decision_quote_symbols_by_date: Option>>>, execution_quote_request_cache: BTreeSet<(NaiveDate, String, Option, Option)>, risk_free_rate_contract: Option, @@ -2538,9 +2537,8 @@ where .map(Arc::clone) { let empty_symbols = BTreeSet::new(); - let decision_quote_symbols = preplanned - .get(&execution_date) - .unwrap_or(&empty_symbols); + let decision_quote_symbols = + preplanned.get(&execution_date).unwrap_or(&empty_symbols); self.ensure_execution_quotes_for_symbols_at_times( execution_date, decision_quote_symbols, diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index 2b389c2..e803d5b 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -4191,13 +4191,10 @@ impl PlatformExprStrategy { .factor_snapshot_rows_on(date) .iter() .flat_map(|row| { - row.extra_factors - .keys() - .map(|key| key.to_string()) - .chain( - row.adjustment_factor_backward1 - .map(|_| BACKWARD_ADJUSTMENT_FACTOR_FIELD.to_string()), - ) + row.extra_factors.keys().map(|key| key.to_string()).chain( + row.adjustment_factor_backward1 + .map(|_| BACKWARD_ADJUSTMENT_FACTOR_FIELD.to_string()), + ) }) .collect() } else { @@ -10397,10 +10394,7 @@ impl PlatformExprStrategy { ) -> std::ops::Range { if !matches!( self.config.market_cap_field.as_str(), - "market_cap" - | "market_cap_bn" - | "candidate_market_cap" - | "candidate_market_cap_bn" + "market_cap" | "market_cap_bn" | "candidate_market_cap" | "candidate_market_cap_bn" ) || !band_low.is_finite() || !band_high.is_finite() { @@ -10418,8 +10412,7 @@ impl PlatformExprStrategy { }; let start = symbol_ids.partition_point(|symbol_id| market_cap(*symbol_id) < band_low); let end = start - + symbol_ids[start..] - .partition_point(|symbol_id| market_cap(*symbol_id) <= band_high); + + symbol_ids[start..].partition_point(|symbol_id| market_cap(*symbol_id) <= band_high); start..end } @@ -11553,11 +11546,8 @@ impl PlatformExprStrategy { &execution_day, &factor_day, )?; - let field_value = self.selection_field_value_from_caps( - market_cap_bn, - free_float_cap_bn, - &stock, - ); + let field_value = + self.selection_field_value_from_caps(market_cap_bn, free_float_cap_bn, &stock); if !field_value.is_finite() { if diagnostics.len() < 12 { diagnostics.push(format!( @@ -16128,15 +16118,16 @@ mod tests { cfg.market_cap_field = "market_cap".to_string(); let strategy = PlatformExprStrategy::new(cfg.clone()); - let range = strategy.market_cap_ordered_selection_range( - &factor_day, - symbol_ids, - 10.0, - 20.0, - ); + let range = + strategy.market_cap_ordered_selection_range(&factor_day, symbol_ids, 10.0, 20.0); let selected_caps = symbol_ids[range] .iter() - .map(|symbol_id| factor_day.factor(*symbol_id).expect("factor row").market_cap_bn) + .map(|symbol_id| { + factor_day + .factor(*symbol_id) + .expect("factor row") + .market_cap_bn + }) .collect::>(); assert_eq!(selected_caps, vec![10.0, 20.0]); @@ -16147,8 +16138,12 @@ mod tests { ); cfg.market_cap_field = "free_float_cap".to_string(); assert_eq!( - PlatformExprStrategy::new(cfg) - .market_cap_ordered_selection_range(&factor_day, symbol_ids, 10.0, 20.0), + PlatformExprStrategy::new(cfg).market_cap_ordered_selection_range( + &factor_day, + symbol_ids, + 10.0, + 20.0 + ), 0..symbol_ids.len() ); }