优化日线候选和成交量窗口索引
This commit is contained in:
@@ -487,6 +487,7 @@ struct SymbolPriceSeries {
|
|||||||
last_prefix: Vec<f64>,
|
last_prefix: Vec<f64>,
|
||||||
valid_volume_sum_prefix: Vec<f64>,
|
valid_volume_sum_prefix: Vec<f64>,
|
||||||
valid_volume_count_prefix: Vec<usize>,
|
valid_volume_count_prefix: Vec<usize>,
|
||||||
|
valid_volume_start_by_count: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -706,6 +707,14 @@ impl SymbolPriceSeries {
|
|||||||
+ usize::from(valid),
|
+ usize::from(valid),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
let valid_volume_count = valid_volume_count_prefix
|
||||||
|
.last()
|
||||||
|
.copied()
|
||||||
|
.unwrap_or_default();
|
||||||
|
let mut valid_volume_start_by_count = vec![0usize; valid_volume_count + 1];
|
||||||
|
for (index, count) in valid_volume_count_prefix.iter().copied().enumerate() {
|
||||||
|
valid_volume_start_by_count[count] = index;
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
symbol,
|
symbol,
|
||||||
@@ -735,6 +744,7 @@ impl SymbolPriceSeries {
|
|||||||
last_prefix,
|
last_prefix,
|
||||||
valid_volume_sum_prefix,
|
valid_volume_sum_prefix,
|
||||||
valid_volume_count_prefix,
|
valid_volume_count_prefix,
|
||||||
|
valid_volume_start_by_count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,9 +893,8 @@ impl SymbolPriceSeries {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let target_count = valid_count - lookback;
|
let target_count = valid_count - lookback;
|
||||||
let start = self.valid_volume_count_prefix[..=end]
|
let start = *self.valid_volume_start_by_count.get(target_count)?;
|
||||||
.partition_point(|count| *count <= target_count)
|
debug_assert!(start <= end);
|
||||||
.saturating_sub(1);
|
|
||||||
Some((start, end))
|
Some((start, end))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2326,6 +2335,20 @@ impl DataSet {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn factor_snapshot_rows_on(&self, date: NaiveDate) -> &[Arc<DailyFactorSnapshot>] {
|
||||||
|
self.factor_by_date
|
||||||
|
.get(&date)
|
||||||
|
.map(Vec::as_slice)
|
||||||
|
.unwrap_or(&[])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn factor_symbol_ids_on(&self, date: NaiveDate) -> &[u32] {
|
||||||
|
self.factor_symbol_ids_by_date
|
||||||
|
.get(&date)
|
||||||
|
.map(Vec::as_slice)
|
||||||
|
.unwrap_or(&[])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn factor_text_snapshots_on(&self, date: NaiveDate) -> Vec<&FactorTextValue> {
|
pub fn factor_text_snapshots_on(&self, date: NaiveDate) -> Vec<&FactorTextValue> {
|
||||||
self.factor_text_by_date
|
self.factor_text_by_date
|
||||||
.get(&date)
|
.get(&date)
|
||||||
|
|||||||
@@ -7951,7 +7951,10 @@ impl PlatformExprStrategy {
|
|||||||
selection_risk_deferral: SelectionRiskDeferral,
|
selection_risk_deferral: SelectionRiskDeferral,
|
||||||
) -> Vec<EligibleUniverseSnapshot> {
|
) -> Vec<EligibleUniverseSnapshot> {
|
||||||
let mut rows = Vec::new();
|
let mut rows = Vec::new();
|
||||||
for factor in ctx.data.factor_snapshots_on(factor_date) {
|
let factor_rows = ctx.data.factor_snapshot_rows_on(factor_date);
|
||||||
|
let factor_symbol_ids = ctx.data.factor_symbol_ids_on(factor_date);
|
||||||
|
debug_assert_eq!(factor_rows.len(), factor_symbol_ids.len());
|
||||||
|
for (factor, symbol_id) in factor_rows.iter().zip(factor_symbol_ids.iter().copied()) {
|
||||||
if factor.market_cap_bn <= 0.0 || !factor.market_cap_bn.is_finite() {
|
if factor.market_cap_bn <= 0.0 || !factor.market_cap_bn.is_finite() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -7959,14 +7962,15 @@ impl PlatformExprStrategy {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let synthetic_candidate;
|
let synthetic_candidate;
|
||||||
let candidate = if let Some(candidate) = ctx.data.candidate(date, &factor.symbol) {
|
let candidate =
|
||||||
candidate
|
if let Some(candidate) = ctx.data.candidate_by_symbol_id(date, symbol_id) {
|
||||||
} else {
|
candidate
|
||||||
synthetic_candidate =
|
} else {
|
||||||
crate::data::missing_candidate_risk_state(date, &factor.symbol);
|
synthetic_candidate =
|
||||||
&synthetic_candidate
|
crate::data::missing_candidate_risk_state(date, &factor.symbol);
|
||||||
};
|
&synthetic_candidate
|
||||||
let Some(market) = ctx.data.market(date, &factor.symbol) else {
|
};
|
||||||
|
let Some(market) = ctx.data.market_by_symbol_id(date, symbol_id) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if let Some(_reason) =
|
if let Some(_reason) =
|
||||||
@@ -8021,19 +8025,23 @@ impl PlatformExprStrategy {
|
|||||||
selection_risk_deferral: SelectionRiskDeferral,
|
selection_risk_deferral: SelectionRiskDeferral,
|
||||||
) -> Vec<FidcRiskDecisionAudit> {
|
) -> Vec<FidcRiskDecisionAudit> {
|
||||||
let mut decisions = Vec::new();
|
let mut decisions = Vec::new();
|
||||||
for factor in ctx.data.factor_snapshots_on(factor_date) {
|
let factor_rows = ctx.data.factor_snapshot_rows_on(factor_date);
|
||||||
|
let factor_symbol_ids = ctx.data.factor_symbol_ids_on(factor_date);
|
||||||
|
debug_assert_eq!(factor_rows.len(), factor_symbol_ids.len());
|
||||||
|
for (factor, symbol_id) in factor_rows.iter().zip(factor_symbol_ids.iter().copied()) {
|
||||||
if ctx.has_dynamic_universe() && !ctx.dynamic_universe_contains(&factor.symbol) {
|
if ctx.has_dynamic_universe() && !ctx.dynamic_universe_contains(&factor.symbol) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let synthetic_candidate;
|
let synthetic_candidate;
|
||||||
let candidate = if let Some(candidate) = ctx.data.candidate(date, &factor.symbol) {
|
let candidate =
|
||||||
candidate
|
if let Some(candidate) = ctx.data.candidate_by_symbol_id(date, symbol_id) {
|
||||||
} else {
|
candidate
|
||||||
synthetic_candidate =
|
} else {
|
||||||
crate::data::missing_candidate_risk_state(date, &factor.symbol);
|
synthetic_candidate =
|
||||||
&synthetic_candidate
|
crate::data::missing_candidate_risk_state(date, &factor.symbol);
|
||||||
};
|
&synthetic_candidate
|
||||||
let Some(market) = ctx.data.market(date, &factor.symbol) else {
|
};
|
||||||
|
let Some(market) = ctx.data.market_by_symbol_id(date, symbol_id) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if let Some(decision) = ChinaAShareRiskControl::selection_rejection_decision_with_config(
|
if let Some(decision) = ChinaAShareRiskControl::selection_rejection_decision_with_config(
|
||||||
|
|||||||
Reference in New Issue
Block a user