From e17c5ad3b0623851740ee97330bf018e9f9f53dd Mon Sep 17 00:00:00 2001 From: boris Date: Mon, 13 Jul 2026 15:51:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BF=A1=E5=8F=B7=E6=97=A5?= =?UTF-8?q?=E5=9F=BA=E5=87=86=E6=94=B6=E7=9B=98=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/fidc-core/src/platform_expr_strategy.rs | 10 ++++++++++ crates/fidc-core/src/platform_runtime_schema.rs | 2 ++ crates/fidc-core/src/strategy_ai.rs | 1 + 3 files changed, 13 insertions(+) diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index 58a7152..5349898 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -400,6 +400,7 @@ struct DayExpressionState { signal_close: f64, benchmark_open: f64, benchmark_close: f64, + benchmark_signal_close: f64, benchmark_ma_short: f64, benchmark_ma_long: f64, benchmark_ma5: f64, @@ -965,6 +966,7 @@ impl PlatformExprStrategy { name, "signal_close" | "benchmark_close" + | "benchmark_signal_close" | "signal_ma5" | "signal_ma10" | "signal_ma20" @@ -2792,6 +2794,7 @@ impl PlatformExprStrategy { .benchmark(date) .ok_or(BacktestError::MissingBenchmark { date })?; let benchmark_open = benchmark.open; + let benchmark_signal_close = benchmark.close; let benchmark_close = ctx .data .benchmark_decision_close(date) @@ -2874,6 +2877,7 @@ impl PlatformExprStrategy { signal_close, benchmark_open, benchmark_close, + benchmark_signal_close, benchmark_ma_short, benchmark_ma_long, benchmark_ma5, @@ -3304,6 +3308,7 @@ impl PlatformExprStrategy { scope.push("signal_close", day.signal_close); scope.push("benchmark_open", day.benchmark_open); scope.push("benchmark_close", day.benchmark_close); + scope.push("benchmark_signal_close", day.benchmark_signal_close); for field in [ "day_open", "open", @@ -3467,6 +3472,10 @@ impl PlatformExprStrategy { day_factors.insert("signal_close".into(), Dynamic::from(day.signal_close)); day_factors.insert("benchmark_open".into(), Dynamic::from(day.benchmark_open)); day_factors.insert("benchmark_close".into(), Dynamic::from(day.benchmark_close)); + day_factors.insert( + "benchmark_signal_close".into(), + Dynamic::from(day.benchmark_signal_close), + ); day_factors.insert("signal_ma5".into(), Dynamic::from(day.signal_ma5)); day_factors.insert("signal_ma10".into(), Dynamic::from(day.signal_ma10)); day_factors.insert("signal_ma20".into(), Dynamic::from(day.signal_ma20)); @@ -11555,6 +11564,7 @@ mod tests { assert_eq!(day.signal_close, 10.0); assert_eq!(day.benchmark_open, 150.0); assert_eq!(day.benchmark_close, 100.0); + assert_eq!(day.benchmark_signal_close, 9_999.0); assert_eq!(day.benchmark_ma_short, 100.0); assert_eq!(day.benchmark_ma_long, 100.0); } diff --git a/crates/fidc-core/src/platform_runtime_schema.rs b/crates/fidc-core/src/platform_runtime_schema.rs index 48d3d42..9cc3428 100644 --- a/crates/fidc-core/src/platform_runtime_schema.rs +++ b/crates/fidc-core/src/platform_runtime_schema.rs @@ -67,6 +67,7 @@ const RESERVED_SCOPE_NAMES: &[&str] = &[ // day-level "signal_close", "benchmark_close", + "benchmark_signal_close", "signal_ma5", "signal_ma10", "signal_ma20", @@ -326,6 +327,7 @@ mod tests { for required in [ "signal_close", "benchmark_close", + "benchmark_signal_close", "close", "avg_cost", "current_price", diff --git a/crates/fidc-core/src/strategy_ai.rs b/crates/fidc-core/src/strategy_ai.rs index 62de9ea..96729fa 100644 --- a/crates/fidc-core/src/strategy_ai.rs +++ b/crates/fidc-core/src/strategy_ai.rs @@ -280,6 +280,7 @@ pub fn built_in_strategy_manual() -> StrategyAiManual { fields: vec![ ManualField { name: "signal_open/signal_close".to_string(), field_type: "float".to_string(), detail: "信号指数当日开盘价与前一日收盘价。".to_string() }, ManualField { name: "benchmark_open/benchmark_close".to_string(), field_type: "float".to_string(), detail: "基准当日开盘价与前一日收盘价。".to_string() }, + ManualField { name: "benchmark_signal_close".to_string(), field_type: "float".to_string(), detail: "信号日收盘后可见的基准当日收盘价;用于 T 日生成信号、T+1 开盘成交的条件,不能在盘中或 T 日开盘决策中使用。".to_string() }, ManualField { name: "signal_ma5/signal_ma10/signal_ma20/signal_ma30".to_string(), field_type: "float".to_string(), detail: "信号指数滚动均线。".to_string() }, ManualField { name: "benchmark_ma5/benchmark_ma10/benchmark_ma20/benchmark_ma30".to_string(), field_type: "float".to_string(), detail: "基准指数滚动均线。".to_string() }, ManualField { name: "cash/available_cash/frozen_cash/market_value/total_equity".to_string(), field_type: "float".to_string(), detail: "账户可用资金、挂单冻结资金、市值与总权益;available_cash 会扣减当前买入挂单冻结估算。".to_string() },