修正预计算市值决策口径
This commit is contained in:
@@ -478,7 +478,17 @@ pub fn decision_adjusted_cap_bn(
|
|||||||
raw_cap_bn * market.prev_close / market.close
|
raw_cap_bn * market.prev_close / market.close
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn factor_market_cap_is_decision_adjusted(factor: &DailyFactorSnapshot) -> bool {
|
||||||
|
factor
|
||||||
|
.extra_factors
|
||||||
|
.get("__market_cap_decision_adjusted")
|
||||||
|
.is_some_and(|value| value.is_finite() && *value > 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn decision_market_cap_bn(factor: &DailyFactorSnapshot, market: &DailyMarketSnapshot) -> f64 {
|
pub fn decision_market_cap_bn(factor: &DailyFactorSnapshot, market: &DailyMarketSnapshot) -> f64 {
|
||||||
|
if factor_market_cap_is_decision_adjusted(factor) {
|
||||||
|
return factor.market_cap_bn;
|
||||||
|
}
|
||||||
decision_adjusted_cap_bn(factor.date, factor.market_cap_bn, market)
|
decision_adjusted_cap_bn(factor.date, factor.market_cap_bn, market)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,6 +496,9 @@ pub fn decision_free_float_cap_bn(
|
|||||||
factor: &DailyFactorSnapshot,
|
factor: &DailyFactorSnapshot,
|
||||||
market: &DailyMarketSnapshot,
|
market: &DailyMarketSnapshot,
|
||||||
) -> f64 {
|
) -> f64 {
|
||||||
|
if factor_market_cap_is_decision_adjusted(factor) {
|
||||||
|
return factor.free_float_cap_bn;
|
||||||
|
}
|
||||||
decision_adjusted_cap_bn(factor.date, factor.free_float_cap_bn, market)
|
decision_adjusted_cap_bn(factor.date, factor.free_float_cap_bn, market)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3973,6 +3986,49 @@ mod tests {
|
|||||||
assert!((rows[1].market_cap_bn - 10.0).abs() < 1e-9);
|
assert!((rows[1].market_cap_bn - 10.0).abs() < 1e-9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn decision_market_cap_keeps_pre_adjusted_factor() {
|
||||||
|
let date = NaiveDate::parse_from_str("2025-01-06", "%Y-%m-%d").unwrap();
|
||||||
|
let market = DailyMarketSnapshot {
|
||||||
|
date,
|
||||||
|
symbol: "000001.SZ".to_string(),
|
||||||
|
timestamp: Some("2025-01-06 10:18:00".to_string()),
|
||||||
|
day_open: 10.0,
|
||||||
|
open: 10.0,
|
||||||
|
high: 20.0,
|
||||||
|
low: 10.0,
|
||||||
|
close: 20.0,
|
||||||
|
last_price: 10.0,
|
||||||
|
bid1: 10.0,
|
||||||
|
ask1: 10.0,
|
||||||
|
prev_close: 10.0,
|
||||||
|
volume: 100_000,
|
||||||
|
tick_volume: 1_000,
|
||||||
|
bid1_volume: 1_000,
|
||||||
|
ask1_volume: 1_000,
|
||||||
|
trading_phase: Some("continuous".to_string()),
|
||||||
|
paused: false,
|
||||||
|
upper_limit: 11.0,
|
||||||
|
lower_limit: 9.0,
|
||||||
|
price_tick: 0.01,
|
||||||
|
};
|
||||||
|
let mut extra_factors = BTreeMap::new();
|
||||||
|
extra_factors.insert("__market_cap_decision_adjusted".to_string(), 1.0);
|
||||||
|
let factor = DailyFactorSnapshot {
|
||||||
|
date,
|
||||||
|
symbol: "000001.SZ".to_string(),
|
||||||
|
market_cap_bn: 12.0,
|
||||||
|
free_float_cap_bn: 4.0,
|
||||||
|
pe_ttm: 10.0,
|
||||||
|
turnover_ratio: Some(1.0),
|
||||||
|
effective_turnover_ratio: Some(1.0),
|
||||||
|
extra_factors,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!((decision_market_cap_bn(&factor, &market) - 12.0).abs() < 1e-9);
|
||||||
|
assert!((decision_free_float_cap_bn(&factor, &market) - 4.0).abs() < 1e-9);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn benchmark_decision_close_windows_exclude_current_close() {
|
fn benchmark_decision_close_windows_exclude_current_close() {
|
||||||
let series = BenchmarkPriceSeries::new(&[
|
let series = BenchmarkPriceSeries::new(&[
|
||||||
|
|||||||
Reference in New Issue
Block a user