From 4e3ae3b378b6bd0f8f681d0614198333bece5bf9 Mon Sep 17 00:00:00 2001 From: boris Date: Sun, 5 Jul 2026 02:01:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B9=B3=E5=8F=B0=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E5=AE=89=E5=85=A8=E9=99=A4=E6=B3=95=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fidc-core/src/platform_expr_strategy.rs | 33 +++++++++++++++++++ .../fidc-core/src/platform_runtime_schema.rs | 2 ++ 2 files changed, 35 insertions(+) diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index 298f66d..c1de838 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -614,6 +614,13 @@ impl PlatformExprStrategy { lhs / rhs } }); + engine.register_fn("safe_div", |lhs: f64, rhs: f64| { + if rhs.abs() <= f64::EPSILON { + 0.0 + } else { + lhs / rhs + } + }); engine.register_fn( "iff", |condition: bool, when_true: Dynamic, when_false: Dynamic| { @@ -8432,6 +8439,32 @@ mod tests { assert!(!rewritten.contains('?')); } + #[test] + fn platform_expr_safe_div_supports_two_and_three_arg_forms() { + let strategy = PlatformExprStrategy::new(PlatformExprStrategyConfig::microcap_rotation()); + assert_eq!( + strategy + .engine + .eval::("safe_div(6.0, 3.0)") + .expect("two-arg safe_div should evaluate"), + 2.0 + ); + assert_eq!( + strategy + .engine + .eval::("safe_div(6.0, 0.0)") + .expect("two-arg safe_div should use zero fallback"), + 0.0 + ); + assert_eq!( + strategy + .engine + .eval::("safe_div(6.0, 0.0, -1.0)") + .expect("three-arg safe_div should preserve explicit fallback"), + -1.0 + ); + } + #[test] fn platform_expr_limit_flags_are_directional() { assert!(PlatformExprStrategy::price_is_at_or_above_upper_limit( diff --git a/crates/fidc-core/src/platform_runtime_schema.rs b/crates/fidc-core/src/platform_runtime_schema.rs index 6270125..cc9fda1 100644 --- a/crates/fidc-core/src/platform_runtime_schema.rs +++ b/crates/fidc-core/src/platform_runtime_schema.rs @@ -140,6 +140,7 @@ const RESERVED_SCOPE_NAMES: &[&str] = &[ "ask1_volume", "turnover_ratio", "effective_turnover_ratio", + "up_days_stock", "open", "high", "low", @@ -328,6 +329,7 @@ mod tests { "avg_cost", "current_price", "stock_ma_short", + "up_days_stock", ] { assert!( names.contains(required),