跳过干净因子映射重复规范化
This commit is contained in:
@@ -3311,6 +3311,16 @@ fn normalize_factor_snapshots(factors: Vec<DailyFactorSnapshot>) -> Vec<DailyFac
|
|||||||
factors
|
factors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|mut snapshot| {
|
.map(|mut snapshot| {
|
||||||
|
let already_normalized = snapshot.extra_factors.iter().all(|(field, value)| {
|
||||||
|
let trimmed = field.as_ref().trim().trim_matches('"').trim_matches('\'');
|
||||||
|
!trimmed.is_empty()
|
||||||
|
&& trimmed == field.as_ref()
|
||||||
|
&& trimmed.bytes().all(|byte| !byte.is_ascii_uppercase())
|
||||||
|
&& value.is_finite()
|
||||||
|
});
|
||||||
|
if already_normalized {
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
snapshot.extra_factors = snapshot
|
snapshot.extra_factors = snapshot
|
||||||
.extra_factors
|
.extra_factors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -3970,6 +3980,41 @@ mod tests {
|
|||||||
assert_eq!(factor_numeric_value(&snapshot, "CUSTOM_FACTOR"), Some(3.5));
|
assert_eq!(factor_numeric_value(&snapshot, "CUSTOM_FACTOR"), Some(3.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn factor_snapshot_normalization_moves_clean_maps_and_repairs_dirty_maps() {
|
||||||
|
let date = NaiveDate::parse_from_str("2025-01-02", "%Y-%m-%d").unwrap();
|
||||||
|
let clean = normalize_factor_snapshots(vec![DailyFactorSnapshot {
|
||||||
|
date,
|
||||||
|
symbol: "000001.SZ".to_string(),
|
||||||
|
market_cap_bn: 1.0,
|
||||||
|
free_float_cap_bn: 1.0,
|
||||||
|
pe_ttm: 1.0,
|
||||||
|
turnover_ratio: None,
|
||||||
|
effective_turnover_ratio: None,
|
||||||
|
extra_factors: BTreeMap::from([(Cow::Borrowed("amount"), 10.0)]),
|
||||||
|
}]);
|
||||||
|
assert!(matches!(
|
||||||
|
clean[0].extra_factors.keys().next(),
|
||||||
|
Some(Cow::Borrowed("amount"))
|
||||||
|
));
|
||||||
|
|
||||||
|
let dirty = normalize_factor_snapshots(vec![DailyFactorSnapshot {
|
||||||
|
date,
|
||||||
|
symbol: "000001.SZ".to_string(),
|
||||||
|
market_cap_bn: 1.0,
|
||||||
|
free_float_cap_bn: 1.0,
|
||||||
|
pe_ttm: 1.0,
|
||||||
|
turnover_ratio: None,
|
||||||
|
effective_turnover_ratio: None,
|
||||||
|
extra_factors: BTreeMap::from([
|
||||||
|
(Cow::Owned(" CUSTOM_FACTOR ".to_string()), 2.0),
|
||||||
|
(Cow::Borrowed("bad_nan"), f64::NAN),
|
||||||
|
]),
|
||||||
|
}]);
|
||||||
|
assert_eq!(dirty[0].extra_factors.get("custom_factor"), Some(&2.0));
|
||||||
|
assert!(!dirty[0].extra_factors.contains_key("bad_nan"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn symbol_price_series_test_constructor_sorts_unsorted_rows() {
|
fn symbol_price_series_test_constructor_sorts_unsorted_rows() {
|
||||||
let series = SymbolPriceSeries::new(
|
let series = SymbolPriceSeries::new(
|
||||||
|
|||||||
Reference in New Issue
Block a user