Support dynamic source factors in platform runtime

This commit is contained in:
boris
2026-04-22 00:00:43 -07:00
parent 5815379da2
commit e838629c58
5 changed files with 26 additions and 10 deletions

View File

@@ -176,6 +176,8 @@ pub struct DailyFactorSnapshot {
pub pe_ttm: f64,
pub turnover_ratio: Option<f64>,
pub effective_turnover_ratio: Option<f64>,
#[serde(default)]
pub extra_factors: BTreeMap<String, f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -938,6 +940,12 @@ fn read_factors(path: &Path) -> Result<Vec<DailyFactorSnapshot>, DataSetError> {
pe_ttm: row.parse_f64(4)?,
turnover_ratio: row.parse_optional_f64(5),
effective_turnover_ratio: row.parse_optional_f64(6),
extra_factors: row
.fields
.get(7)
.filter(|value| !value.trim().is_empty())
.and_then(|value| serde_json::from_str::<BTreeMap<String, f64>>(value).ok())
.unwrap_or_default(),
});
}
Ok(snapshots)

View File

@@ -168,6 +168,7 @@ struct StockExpressionState {
stock_ma10: f64,
stock_ma20: f64,
stock_ma30: f64,
extra_factors: BTreeMap<String, f64>,
}
#[derive(Debug, Clone)]
@@ -690,6 +691,7 @@ impl PlatformExprStrategy {
stock_ma10,
stock_ma20,
stock_ma30,
extra_factors: factor.extra_factors.clone(),
})
}
@@ -828,6 +830,9 @@ impl PlatformExprStrategy {
factors.insert("ma10".into(), Dynamic::from(stock.stock_ma10));
factors.insert("ma20".into(), Dynamic::from(stock.stock_ma20));
factors.insert("ma30".into(), Dynamic::from(stock.stock_ma30));
for (key, value) in &stock.extra_factors {
factors.insert(key.clone().into(), Dynamic::from(*value));
}
scope.push("factors", factors);
}
if let Some(position) = position {
@@ -1050,7 +1055,7 @@ impl PlatformExprStrategy {
"is_new_listing" => Some(if stock.is_new_listing { 1.0 } else { 0.0 }),
"candidate_market_cap" => Some(candidate.market_cap_bn),
"candidate_free_float_cap" => Some(candidate.free_float_cap_bn),
_ => None,
other => stock.extra_factors.get(other).copied(),
}
}