From 652531ac63b8c1318c204e742556d284f46e48f0 Mon Sep 17 00:00:00 2001 From: boris Date: Sat, 4 Jul 2026 19:15:13 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E9=BD=90=E7=AD=96=E7=95=A5AI=E6=8C=81?= =?UTF-8?q?=E4=BB=93=E5=90=88=E5=90=8C=E8=AF=B7=E6=B1=82=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/fidc-core/src/lib.rs | 7 ++++--- crates/fidc-core/src/strategy_ai.rs | 31 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/crates/fidc-core/src/lib.rs b/crates/fidc-core/src/lib.rs index a0d87b9..4f76163 100644 --- a/crates/fidc-core/src/lib.rs +++ b/crates/fidc-core/src/lib.rs @@ -84,9 +84,10 @@ pub use strategy::{ }; pub use strategy_ai::{ ManualExample, ManualFactorSource, ManualField, ManualFieldGroup, ManualFunction, - ManualSection, StrategyAiCatalog, StrategyAiGenerateRequest, StrategyAiManual, - StrategyAiOptimizeRequest, build_generation_prompt, build_optimization_prompt, - built_in_strategy_manual, merge_catalog_into_manual, render_manual_markdown, + ManualSection, StrategyAiCatalog, StrategyAiGenerateRequest, StrategyAiHoldingCountContract, + StrategyAiManual, StrategyAiOptimizeRequest, build_generation_prompt, + build_optimization_prompt, built_in_strategy_manual, merge_catalog_into_manual, + render_manual_markdown, }; pub use universe::{ BandRegime, DynamicMarketCapBandSelector, SelectionContext, SelectionDiagnostics, diff --git a/crates/fidc-core/src/strategy_ai.rs b/crates/fidc-core/src/strategy_ai.rs index 4a7dbc6..015903e 100644 --- a/crates/fidc-core/src/strategy_ai.rs +++ b/crates/fidc-core/src/strategy_ai.rs @@ -72,6 +72,29 @@ pub struct StrategyAiCatalog { pub data_lake_fields: Vec, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct StrategyAiHoldingCountContract { + #[serde( + default, + alias = "holdingCount", + alias = "holding_count", + alias = "targetHoldingCount", + alias = "target_holding_count" + )] + #[serde(skip_serializing_if = "Option::is_none")] + pub count: Option, + #[serde( + default, + alias = "kind", + alias = "holdingCountMode", + alias = "holding_count_mode", + alias = "targetHoldingCountMode", + alias = "target_holding_count_mode" + )] + #[serde(skip_serializing_if = "Option::is_none")] + pub mode: Option, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct StrategyAiGenerateRequest { pub user_goal: String, @@ -79,6 +102,9 @@ pub struct StrategyAiGenerateRequest { pub market: String, pub benchmark_symbol: String, pub signal_symbol: String, + #[serde(default, alias = "holdingCountContract")] + #[serde(skip_serializing_if = "Option::is_none")] + pub holding_count_contract: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -87,6 +113,9 @@ pub struct StrategyAiOptimizeRequest { pub objective: String, pub result_summary: serde_json::Value, pub diagnostics: Vec, + #[serde(default, alias = "holdingCountContract")] + #[serde(skip_serializing_if = "Option::is_none")] + pub holding_count_contract: Option, } const DEFAULT_THREE_YEAR_RETURN_TARGET_PROMPT: &str = "默认收益目标:用户没有明确指定更高收益阈值时,三年回测区间策略总收益 >= 150% 即视为满足收益目标;达到该阈值后可以继续优化夏普、回撤、换手和稳定性,但不得把已达标策略判为失败或为了追更高收益破坏无未来数据、持仓数量和同条件对账合同。"; @@ -602,6 +631,7 @@ mod tests { market: "CN_A".to_string(), benchmark_symbol: "000852.SH".to_string(), signal_symbol: "000001.SH".to_string(), + holding_count_contract: None, }, ); @@ -624,6 +654,7 @@ mod tests { objective: "优化收益".to_string(), result_summary: json!({ "total_return": 1.49 }), diagnostics: Vec::new(), + holding_count_contract: None, }, );