共享按日期市值排序索引
This commit is contained in:
@@ -1312,6 +1312,7 @@ pub struct DataSet {
|
||||
market_row_positions_by_date: Arc<Option<DenseRowPositionIndex>>,
|
||||
factor_by_date: Arc<BTreeMap<NaiveDate, Vec<DailyFactorSnapshot>>>,
|
||||
factor_symbol_ids_by_date: Arc<BTreeMap<NaiveDate, Vec<u32>>>,
|
||||
factor_market_cap_order_by_date: Arc<OnceLock<BTreeMap<NaiveDate, Vec<usize>>>>,
|
||||
factor_row_positions_by_date: Arc<Option<DenseRowPositionIndex>>,
|
||||
factor_text_by_date: Arc<BTreeMap<NaiveDate, Vec<FactorTextValue>>>,
|
||||
factor_text_symbol_indices_by_date:
|
||||
@@ -1794,6 +1795,7 @@ impl DataSet {
|
||||
market_row_positions_by_date: Arc::new(market_row_positions_by_date),
|
||||
factor_by_date: Arc::new(factor_by_date),
|
||||
factor_symbol_ids_by_date: Arc::new(factor_symbol_ids_by_date),
|
||||
factor_market_cap_order_by_date: Arc::new(OnceLock::new()),
|
||||
factor_row_positions_by_date: Arc::new(factor_row_positions_by_date),
|
||||
factor_text_by_date: Arc::new(factor_text_by_date),
|
||||
factor_text_symbol_indices_by_date: Arc::new(factor_text_symbol_indices_by_date),
|
||||
@@ -2899,6 +2901,15 @@ impl DataSet {
|
||||
.unwrap_or(&[])
|
||||
}
|
||||
|
||||
/// Returns the immutable factor-row order for ascending decision market cap.
|
||||
/// The index is built once per DataSet and shared by all cloned run views.
|
||||
pub fn factor_market_cap_order_on(&self, date: NaiveDate) -> Option<&[usize]> {
|
||||
self.factor_market_cap_order_by_date
|
||||
.get_or_init(|| build_factor_market_cap_order(&self.factor_by_date))
|
||||
.get(&date)
|
||||
.map(Vec::as_slice)
|
||||
}
|
||||
|
||||
pub fn factor_text_snapshots_on(&self, date: NaiveDate) -> Vec<&FactorTextValue> {
|
||||
self.factor_text_by_date
|
||||
.get(&date)
|
||||
@@ -4037,6 +4048,26 @@ where
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn build_factor_market_cap_order(
|
||||
factor_by_date: &BTreeMap<NaiveDate, Vec<DailyFactorSnapshot>>,
|
||||
) -> BTreeMap<NaiveDate, Vec<usize>> {
|
||||
factor_by_date
|
||||
.iter()
|
||||
.map(|(date, rows)| {
|
||||
let mut indices = (0..rows.len()).collect::<Vec<_>>();
|
||||
indices.sort_unstable_by(|left, right| {
|
||||
rows[*left]
|
||||
.market_cap_bn
|
||||
.partial_cmp(&rows[*right].market_cap_bn)
|
||||
.unwrap_or(std::cmp::Ordering::Equal)
|
||||
.then_with(|| rows[*left].symbol.cmp(&rows[*right].symbol))
|
||||
.then_with(|| left.cmp(right))
|
||||
});
|
||||
(*date, indices)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn build_dense_row_positions<T>(
|
||||
groups: &BTreeMap<NaiveDate, Vec<T>>,
|
||||
symbol_ids_by_date: &BTreeMap<NaiveDate, Vec<u32>>,
|
||||
|
||||
@@ -8991,7 +8991,23 @@ impl PlatformExprStrategy {
|
||||
};
|
||||
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()) {
|
||||
let market_cap_order = ctx.data.factor_market_cap_order_on(factor_date);
|
||||
let mut fallback_factor_rows =
|
||||
factor_rows.iter().zip(factor_symbol_ids.iter().copied());
|
||||
let mut ordered_factor_row_index = 0usize;
|
||||
let factor_rows = std::iter::from_fn(|| {
|
||||
if let Some(indices) = market_cap_order {
|
||||
let row_index = *indices.get(ordered_factor_row_index)?;
|
||||
ordered_factor_row_index += 1;
|
||||
Some((
|
||||
factor_rows.get(row_index)?,
|
||||
*factor_symbol_ids.get(row_index)?,
|
||||
))
|
||||
} else {
|
||||
fallback_factor_rows.next()
|
||||
}
|
||||
});
|
||||
for (factor, symbol_id) in factor_rows {
|
||||
if ctx.has_dynamic_universe() && !ctx.dynamic_universe_contains(&factor.symbol) {
|
||||
continue;
|
||||
}
|
||||
@@ -9059,12 +9075,14 @@ impl PlatformExprStrategy {
|
||||
free_float_cap_bn,
|
||||
});
|
||||
}
|
||||
rows.sort_unstable_by(|left, right| {
|
||||
left.market_cap_bn
|
||||
.partial_cmp(&right.market_cap_bn)
|
||||
.unwrap_or(std::cmp::Ordering::Equal)
|
||||
.then_with(|| left.symbol.cmp(&right.symbol))
|
||||
});
|
||||
if market_cap_order.is_none() {
|
||||
rows.sort_unstable_by(|left, right| {
|
||||
left.market_cap_bn
|
||||
.partial_cmp(&right.market_cap_bn)
|
||||
.unwrap_or(std::cmp::Ordering::Equal)
|
||||
.then_with(|| left.symbol.cmp(&right.symbol))
|
||||
});
|
||||
}
|
||||
(rows, decisions)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user