perf: isolate ordered selection hot path
This commit is contained in:
@@ -10122,46 +10122,18 @@ impl PlatformExprStrategy {
|
|||||||
// complete ranking for replacement limiting, select directly from the
|
// complete ranking for replacement limiting, select directly from the
|
||||||
// ordered stream instead of materializing a second candidate vector.
|
// ordered stream instead of materializing a second candidate vector.
|
||||||
if self.rank_reuses_market_cap_order() && self.config.daily_replacement_limit == 0 {
|
if self.rank_reuses_market_cap_order() && self.config.daily_replacement_limit == 0 {
|
||||||
let execution_day = ctx.data.daily_snapshot_view(date);
|
let selected = self.select_market_cap_ordered_symbols(
|
||||||
let universe_factor_day = ctx.data.daily_snapshot_view(universe_factor_date);
|
ctx,
|
||||||
let factor_day = ctx.data.daily_snapshot_view(stock_factor_date);
|
date,
|
||||||
let mut selected = Vec::with_capacity(limit.min(universe_symbol_ids.len()));
|
universe_factor_date,
|
||||||
for symbol_id in universe_symbol_ids {
|
stock_factor_date,
|
||||||
let factor = universe_factor_day
|
day,
|
||||||
.factor(symbol_id)
|
band_low,
|
||||||
.expect("market-cap order references missing factor row");
|
band_high,
|
||||||
let symbol = factor.symbol.as_str();
|
limit,
|
||||||
let stock = self.uncached_selection_stock_state_from_views_by_symbol_id(
|
universe_symbol_ids,
|
||||||
ctx,
|
&mut diagnostics,
|
||||||
date,
|
)?;
|
||||||
stock_factor_date,
|
|
||||||
symbol_id,
|
|
||||||
symbol,
|
|
||||||
&execution_day,
|
|
||||||
&factor_day,
|
|
||||||
)?;
|
|
||||||
let field_value = self.selection_field_value_from_caps(
|
|
||||||
decision_market_cap_bn(factor),
|
|
||||||
decision_free_float_cap_bn(factor),
|
|
||||||
&stock,
|
|
||||||
);
|
|
||||||
if !field_value.is_finite() || field_value < band_low || field_value > band_high {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if self.selection_candidate_passes_filters(
|
|
||||||
ctx,
|
|
||||||
date,
|
|
||||||
day,
|
|
||||||
symbol,
|
|
||||||
&stock,
|
|
||||||
&mut diagnostics,
|
|
||||||
)? {
|
|
||||||
selected.push(factor.symbol.clone());
|
|
||||||
if selected.len() >= limit {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Ok((selected, diagnostics, risk_decisions));
|
return Ok((selected, diagnostics, risk_decisions));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10180,6 +10152,64 @@ impl PlatformExprStrategy {
|
|||||||
Ok((selected, diagnostics, risk_decisions))
|
Ok((selected, diagnostics, risk_decisions))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
fn select_market_cap_ordered_symbols(
|
||||||
|
&self,
|
||||||
|
ctx: &StrategyContext<'_>,
|
||||||
|
date: NaiveDate,
|
||||||
|
universe_factor_date: NaiveDate,
|
||||||
|
stock_factor_date: NaiveDate,
|
||||||
|
day: &DayExpressionState,
|
||||||
|
band_low: f64,
|
||||||
|
band_high: f64,
|
||||||
|
limit: usize,
|
||||||
|
universe_symbol_ids: Vec<u32>,
|
||||||
|
diagnostics: &mut Vec<String>,
|
||||||
|
) -> Result<Vec<String>, BacktestError> {
|
||||||
|
let execution_day = ctx.data.daily_snapshot_view(date);
|
||||||
|
let universe_factor_day = ctx.data.daily_snapshot_view(universe_factor_date);
|
||||||
|
let factor_day = ctx.data.daily_snapshot_view(stock_factor_date);
|
||||||
|
let mut selected = Vec::with_capacity(limit.min(universe_symbol_ids.len()));
|
||||||
|
for symbol_id in universe_symbol_ids {
|
||||||
|
let factor = universe_factor_day
|
||||||
|
.factor(symbol_id)
|
||||||
|
.expect("market-cap order references missing factor row");
|
||||||
|
let symbol = factor.symbol.as_str();
|
||||||
|
let stock = self.uncached_selection_stock_state_from_views_by_symbol_id(
|
||||||
|
ctx,
|
||||||
|
date,
|
||||||
|
stock_factor_date,
|
||||||
|
symbol_id,
|
||||||
|
symbol,
|
||||||
|
&execution_day,
|
||||||
|
&factor_day,
|
||||||
|
)?;
|
||||||
|
let field_value = self.selection_field_value_from_caps(
|
||||||
|
decision_market_cap_bn(factor),
|
||||||
|
decision_free_float_cap_bn(factor),
|
||||||
|
&stock,
|
||||||
|
);
|
||||||
|
if !field_value.is_finite() || field_value < band_low || field_value > band_high {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if self.selection_candidate_passes_filters(
|
||||||
|
ctx,
|
||||||
|
date,
|
||||||
|
day,
|
||||||
|
symbol,
|
||||||
|
&stock,
|
||||||
|
diagnostics,
|
||||||
|
)? {
|
||||||
|
selected.push(factor.symbol.clone());
|
||||||
|
if selected.len() >= limit {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(selected)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn select_ranked_symbols(
|
fn select_ranked_symbols(
|
||||||
|
|||||||
Reference in New Issue
Block a user