fix: preserve missing numeric factors and reject nonfinite truthiness
This commit is contained in:
@@ -4687,7 +4687,7 @@ impl PlatformExprStrategy {
|
||||
} else if intraday_same_day_factor {
|
||||
f64::NAN
|
||||
} else {
|
||||
factor.extra_factors.get("amount").copied().unwrap_or(0.0)
|
||||
factor.extra_factors.get("amount").copied().unwrap_or(f64::NAN)
|
||||
};
|
||||
let market_cap_bn = decision_market_cap_bn(factor);
|
||||
let free_float_cap_bn = decision_free_float_cap_bn(factor);
|
||||
@@ -4769,8 +4769,8 @@ impl PlatformExprStrategy {
|
||||
minute_volume: market.minute_volume as i64,
|
||||
bid1_volume: market.bid1_volume as i64,
|
||||
ask1_volume: market.ask1_volume as i64,
|
||||
turnover_ratio: factor.turnover_ratio.unwrap_or(0.0),
|
||||
effective_turnover_ratio: factor.effective_turnover_ratio.unwrap_or(0.0),
|
||||
turnover_ratio: factor.turnover_ratio.unwrap_or(f64::NAN),
|
||||
effective_turnover_ratio: factor.effective_turnover_ratio.unwrap_or(f64::NAN),
|
||||
open: feature_market.day_open,
|
||||
high: expression_high,
|
||||
low: expression_low,
|
||||
@@ -8359,7 +8359,7 @@ impl PlatformExprStrategy {
|
||||
if let Some(value) = self.eval_numeric_vm(ctx, expr, day, stock, position)? {
|
||||
return match value {
|
||||
NumericVmValue::Boolean(boolean) => Ok(boolean),
|
||||
NumericVmValue::Number(number) => Ok(number != 0.0),
|
||||
NumericVmValue::Number(number) => Ok(number.is_finite() && number != 0.0),
|
||||
};
|
||||
}
|
||||
let value = self.eval_dynamic(ctx, expr, day, stock, position)?;
|
||||
@@ -8367,7 +8367,7 @@ impl PlatformExprStrategy {
|
||||
return Ok(boolean);
|
||||
}
|
||||
if let Some(number) = value.clone().try_cast::<f64>() {
|
||||
return Ok(number != 0.0);
|
||||
return Ok(number.is_finite() && number != 0.0);
|
||||
}
|
||||
if let Some(number) = value.try_cast::<i64>() {
|
||||
return Ok(number != 0);
|
||||
@@ -16524,8 +16524,8 @@ mod tests {
|
||||
market_cap_bn: 12.0,
|
||||
free_float_cap_bn: 10.0,
|
||||
pe_ttm: 8.0,
|
||||
turnover_ratio: Some(1.0),
|
||||
effective_turnover_ratio: Some(1.0),
|
||||
turnover_ratio: None,
|
||||
effective_turnover_ratio: None,
|
||||
adjustment_factor_backward1: None,
|
||||
extra_factors: BTreeMap::new(),
|
||||
},
|
||||
@@ -16535,8 +16535,8 @@ mod tests {
|
||||
market_cap_bn: 12.0,
|
||||
free_float_cap_bn: 10.0,
|
||||
pe_ttm: 8.0,
|
||||
turnover_ratio: Some(1.0),
|
||||
effective_turnover_ratio: Some(1.0),
|
||||
turnover_ratio: Some(0.0),
|
||||
effective_turnover_ratio: Some(0.0),
|
||||
adjustment_factor_backward1: None,
|
||||
extra_factors: BTreeMap::from([
|
||||
("model_score".into(), 2.0),
|
||||
@@ -16601,6 +16601,16 @@ mod tests {
|
||||
.expect("present stock state");
|
||||
|
||||
assert!(day.available_factor_names.contains("model_score"));
|
||||
assert!(missing_stock.turnover_ratio.is_nan());
|
||||
assert!(missing_stock.effective_turnover_ratio.is_nan());
|
||||
assert_eq!(present_stock.turnover_ratio, 0.0);
|
||||
assert!(!strategy.eval_bool(&ctx, "model_score", &day, Some(&missing_stock), None).unwrap());
|
||||
assert!(strategy.eval_bool(&ctx, "model_score", &day, Some(&present_stock), None).unwrap());
|
||||
for field in ["turnover_ratio", "effective_turnover_ratio"] {
|
||||
let predicate = format!("{field} < 1.0");
|
||||
assert!(!strategy.eval_bool(&ctx, &predicate, &day, Some(&missing_stock), None).unwrap());
|
||||
assert!(strategy.eval_bool(&ctx, &predicate, &day, Some(&present_stock), None).unwrap());
|
||||
}
|
||||
assert!(
|
||||
!strategy
|
||||
.stock_passes_expr(&ctx, &day, &missing_stock)
|
||||
|
||||
Reference in New Issue
Block a user