压缩类型化因子并减少运行分配

This commit is contained in:
boris
2026-08-24 03:55:03 +08:00
parent ea79fdae46
commit 8254ebbb47
2 changed files with 27 additions and 11 deletions
+5
View File
@@ -2888,6 +2888,11 @@ fn factor_numeric_value(snapshot: &DailyFactorSnapshot, field: &str) -> Option<f
"free_float_cap" | "free_float_market_cap" | "free_float_cap_bn" => { "free_float_cap" | "free_float_market_cap" | "free_float_cap_bn" => {
Some(snapshot.free_float_cap_bn) Some(snapshot.free_float_cap_bn)
} }
"free_float_cap_or_market_cap" => Some(
(snapshot.free_float_cap_bn.is_finite() && snapshot.free_float_cap_bn > 0.0)
.then_some(snapshot.free_float_cap_bn)
.unwrap_or(snapshot.market_cap_bn),
),
"pe_ttm" => Some(snapshot.pe_ttm), "pe_ttm" => Some(snapshot.pe_ttm),
"turnover_ratio" => snapshot.turnover_ratio, "turnover_ratio" => snapshot.turnover_ratio,
"effective_turnover_ratio" => snapshot.effective_turnover_ratio, "effective_turnover_ratio" => snapshot.effective_turnover_ratio,
+22 -11
View File
@@ -3837,12 +3837,10 @@ impl PlatformExprStrategy {
allow_sell: candidate.allow_sell, allow_sell: candidate.allow_sell,
touched_upper_limit, touched_upper_limit,
touched_lower_limit, touched_lower_limit,
listed_days: factor listed_days: instrument
.extra_factors .and_then(|item| item.listed_at)
.get("listed_days") .map(|listed_at| factor_date.signed_duration_since(listed_at).num_days())
.copied() .filter(|days| *days >= 0)
.filter(|value| value.is_finite() && *value >= 0.0)
.map(|value| value.floor() as i64)
.unwrap_or(-1), .unwrap_or(-1),
stock_ma_short, stock_ma_short,
stock_ma_mid, stock_ma_mid,
@@ -4242,6 +4240,11 @@ impl PlatformExprStrategy {
scope.push_required("day_factors", day_factors); scope.push_required("day_factors", day_factors);
} }
if let Some(stock) = stock { if let Some(stock) = stock {
let free_float_cap_or_market_cap = if stock.free_float_cap > 0.0 {
stock.free_float_cap
} else {
stock.market_cap
};
let at_upper_limit = Self::price_is_at_or_above_upper_limit( let at_upper_limit = Self::price_is_at_or_above_upper_limit(
stock.last, stock.last,
stock.upper_limit, stock.upper_limit,
@@ -4258,6 +4261,7 @@ impl PlatformExprStrategy {
scope.push("free_float_cap", stock.free_float_cap); scope.push("free_float_cap", stock.free_float_cap);
scope.push("free_float_cap_bn", stock.free_float_cap_bn); scope.push("free_float_cap_bn", stock.free_float_cap_bn);
scope.push("free_float_market_cap", stock.free_float_cap); scope.push("free_float_market_cap", stock.free_float_cap);
scope.push("free_float_cap_or_market_cap", free_float_cap_or_market_cap);
scope.push("pe_ttm", stock.pe_ttm); scope.push("pe_ttm", stock.pe_ttm);
scope.push("volume", stock.volume); scope.push("volume", stock.volume);
scope.push("minute_volume", stock.minute_volume); scope.push("minute_volume", stock.minute_volume);
@@ -4362,6 +4366,10 @@ impl PlatformExprStrategy {
"free_float_market_cap".into(), "free_float_market_cap".into(),
Dynamic::from(stock.free_float_cap), Dynamic::from(stock.free_float_cap),
); );
factors.insert(
"free_float_cap_or_market_cap".into(),
Dynamic::from(free_float_cap_or_market_cap),
);
factors.insert("pe_ttm".into(), Dynamic::from(stock.pe_ttm)); factors.insert("pe_ttm".into(), Dynamic::from(stock.pe_ttm));
factors.insert("volume".into(), Dynamic::from(stock.volume)); factors.insert("volume".into(), Dynamic::from(stock.volume));
factors.insert("minute_volume".into(), Dynamic::from(stock.minute_volume)); factors.insert("minute_volume".into(), Dynamic::from(stock.minute_volume));
@@ -7941,6 +7949,11 @@ impl PlatformExprStrategy {
"market_cap_bn" => Some(stock.market_cap_bn), "market_cap_bn" => Some(stock.market_cap_bn),
"free_float_cap" | "free_float_market_cap" => Some(stock.free_float_cap), "free_float_cap" | "free_float_market_cap" => Some(stock.free_float_cap),
"free_float_cap_bn" => Some(stock.free_float_cap_bn), "free_float_cap_bn" => Some(stock.free_float_cap_bn),
"free_float_cap_or_market_cap" => Some(if stock.free_float_cap > 0.0 {
stock.free_float_cap
} else {
stock.market_cap
}),
"pe_ttm" => Some(stock.pe_ttm), "pe_ttm" => Some(stock.pe_ttm),
"volume" => Some(stock.volume), "volume" => Some(stock.volume),
"minute_volume" | "intraday_volume" => Some(stock.minute_volume as f64), "minute_volume" | "intraday_volume" => Some(stock.minute_volume as f64),
@@ -8584,6 +8597,7 @@ impl PlatformExprStrategy {
| "free_float_cap" | "free_float_cap"
| "free_float_market_cap" | "free_float_market_cap"
| "free_float_cap_bn" | "free_float_cap_bn"
| "free_float_cap_or_market_cap"
| "pe_ttm" | "pe_ttm"
| "volume" | "volume"
| "minute_volume" | "minute_volume"
@@ -16187,7 +16201,7 @@ mod tests {
name: symbol.to_string(), name: symbol.to_string(),
board: "SZ".to_string(), board: "SZ".to_string(),
round_lot: 100, round_lot: 100,
listed_at: Some(d(2020, 1, 1)), listed_at: Some(date - chrono::Duration::days(263)),
delisted_at: None, delisted_at: None,
status: "active".to_string(), status: "active".to_string(),
}], }],
@@ -16222,10 +16236,7 @@ mod tests {
pe_ttm: 8.0, pe_ttm: 8.0,
turnover_ratio: Some(1.0), turnover_ratio: Some(1.0),
effective_turnover_ratio: Some(1.0), effective_turnover_ratio: Some(1.0),
extra_factors: BTreeMap::from([ extra_factors: BTreeMap::from([("touched_upper_limit".to_string(), 1.0)]),
("listed_days".to_string(), 263.0),
("touched_upper_limit".to_string(), 1.0),
]),
}], }],
vec![CandidateEligibility { vec![CandidateEligibility {
date, date,