Add dynamic universe and subscription controls

This commit is contained in:
boris
2026-04-23 07:12:56 -07:00
parent 5265f82fef
commit 152b5c3141
12 changed files with 963 additions and 24 deletions
+21 -6
View File
@@ -1,3 +1,5 @@
use std::collections::BTreeSet;
use chrono::NaiveDate;
use serde::Serialize;
@@ -44,6 +46,21 @@ pub struct SelectionContext<'a> {
pub benchmark: &'a BenchmarkSnapshot,
pub reference_level: f64,
pub data: &'a DataSet,
pub dynamic_universe: Option<&'a BTreeSet<String>>,
}
impl SelectionContext<'_> {
fn eligible_universe(&self) -> Vec<EligibleUniverseSnapshot> {
let eligible = self.data.eligible_universe_on(self.decision_date);
match self.dynamic_universe {
Some(symbols) if !symbols.is_empty() => eligible
.iter()
.filter(|row| symbols.contains(&row.symbol))
.cloned()
.collect(),
_ => eligible.to_vec(),
}
}
}
pub trait UniverseSelector {
@@ -132,12 +149,10 @@ impl UniverseSelector for DynamicMarketCapBandSelector {
};
diagnostics.factor_total = ctx.data.factor_snapshots_on(ctx.decision_date).len();
diagnostics.market_cap_missing_count = diagnostics
.factor_total
.saturating_sub(ctx.data.eligible_universe_on(ctx.decision_date).len());
let eligible = ctx.data.eligible_universe_on(ctx.decision_date);
let start_idx = lower_bound_by_market_cap(eligible, min_cap);
let eligible = ctx.eligible_universe();
diagnostics.market_cap_missing_count =
diagnostics.factor_total.saturating_sub(eligible.len());
let start_idx = lower_bound_by_market_cap(&eligible, min_cap);
let mut selected = Vec::new();
for factor in eligible.iter().skip(start_idx) {