@@ -97,10 +97,11 @@ pub fn built_in_strategy_manual() -> StrategyAiManual {
" 平台策略脚本采用声明式 DSL + 表达式执行模型。 " . to_string ( ) ,
" 支持 let 变量、fn 自定义函数、when/unless/else 条件块、可用指标/因子字段映射。 " . to_string ( ) ,
" 支持数值型和字符串型因子,字符串字段可用于行业、概念、标签、板块等分类过滤。 " . to_string ( ) ,
" 当前默认回测数据已支持 OHLCV、市值、流通市值、换手率、有效换手率、上市天数、停牌/ST/板块、涨跌停价格、tick 触达涨跌停、常用价格/成交量均线;复杂技术指标和财务报表字段必须来自预计算因子或后续扩展函数 。 " . to_string ( ) ,
" 当前默认回测数据已支持 OHLCV、市值、流通市值、换手率、有效换手率、上市天数、停牌/ST/板块、涨跌停价格、tick 触达涨跌停、常用价格/成交量均线,以及 stock_indicator_factors_v1 中已入库的通用指标因子 。 " . to_string ( ) ,
" AI 生成策略时只能输出完整 engine-script 代码,不输出 Markdown、解释、推理过程、JSON 包装或手册复述。 " . to_string ( ) ,
" 表达式字段以运行时字段为准:市值使用 market_cap,流通市值使用 free_float_cap;不要在策略表达式中使用数据库原始字段 float_market_cap。 " . to_string ( ) ,
" 60日 价格均线使用 rolling_mean(\" close \" , 60),不要使用 ma60、stock_ma60、signal_ma60 或 benchmark_ma60。 " . to_string ( ) ,
" 任意窗口 价格均线使用 rolling_mean(\" close \" , n) 或 ma( \" close \" , n),任意窗口均量使用 rolling_mean( \" volume \" , n) 或 vma(n);不要使用未列出的 ma60、stock_ma60、signal_ma60 或 benchmark_ma60 变量 。" . to_string ( ) ,
" next_bar_open 会用决策日信号生成订单,并在下一可交易开盘撮合;不得把执行日 open/high/low/close 当成下单前已知信息。 " . to_string ( ) ,
" 自定义 fn 必须通过参数传入运行时字段;不要用 fn score() 这类零参数函数直接引用 market_cap、close、ma5 等股票字段。 " . to_string ( ) ,
" 禁止自由 Python/JavaScript 命令式语句,最终必须输出平台 DSL。 " . to_string ( ) ,
] ,
@@ -165,6 +166,10 @@ pub fn built_in_strategy_manual() -> StrategyAiManual {
title : " 诊断解释 " . to_string ( ) ,
detail : " 结果为空或收益异常时优先展示 diagnostics、选股数量、过滤原因、缺失字段、窗口不足、涨跌停/停牌拒单、快照缓存命中情况。不要只返回 JSON;要给用户自然语言结论和下一步优化建议。 " . to_string ( ) ,
} ,
ManualSection {
title : " 收益合理性复核 " . to_string ( ) ,
detail : " 展示或用于优化前,应按 finalEquity / initialCash - 1 复算总收益。若小资金回测出现极端收益、指标与资金不一致、或历史 run 来自旧引擎,应检查交易明细并用当前编译后的回测引擎重新回测,不要把异常 run 当成成功样本。 " . to_string ( ) ,
} ,
] ,
optimization_playbook : vec ! [
ManualSection {
@@ -215,7 +220,7 @@ pub fn built_in_strategy_manual() -> StrategyAiManual {
} ,
ManualSection {
title : " execution.matching_type / execution.slippage " . to_string ( ) ,
detail : " 设置撮合模式和滑点。支持 execution.matching_type( \" next_tick_last \" | \" next_tick_best_own \" | \" next_tick_best_counterparty \" | \" counterparty_offer \" | \" vwap \" | \" current_bar_close \" | \" next_bar_open \" | \" open_auction \" )。其中 next_tick_last 使用 tick 的 last_price; next_tick_best_own / next_tick_best_counterparty 会按 L1 买一卖一近似 平台内核 的 tick 最优价语义;counterparty_offer 在存在 order_book_depth 多档盘口数据时会按真实档位逐档扫单并计算加权成交价,不存在 depth 时回退 L1 对手方报价;vwap 会在盘中执行价链路上聚合多笔成交为单条 VWAP 成交;open_auction 使用当日集合竞价开盘价 day_open 进行撮合,且不额外施加滑点,并按竞价成交量而不是盘口一档流动性限制成交;滑点支持 execution.slippage( \" none \" ) / execution.slippage( \" price_ratio \" , 0.001) / execution.slippage( \" tick_size \" , 1) / execution.slippage( \" limit_price \" ),其中 limit_price 会在限价单成交时按挂单价模拟 平台内核 的最坏成交价。 " . to_string ( ) ,
detail : " 设置撮合模式和滑点。支持 execution.matching_type( \" next_tick_last \" | \" next_tick_best_own \" | \" next_tick_best_counterparty \" | \" counterparty_offer \" | \" vwap \" | \" current_bar_close \" | \" next_bar_open \" | \" open_auction \" )。其中 next_tick_last 使用 tick 的 last_price; next_tick_best_own / next_tick_best_counterparty 会按 L1 买一卖一近似 平台内核 的 tick 最优价语义;counterparty_offer 在存在 order_book_depth 多档盘口数据时会按真实档位逐档扫单并计算加权成交价,不存在 depth 时回退 L1 对手方报价;vwap 会在盘中执行价链路上聚合多笔成交为单条 VWAP 成交;next_bar_open 使用决策日信号并在下一可交易日开盘撮合,禁止把执行日 open/high/low/close 解释为下单前已知数据; open_auction 使用当日集合竞价开盘价 day_open 进行撮合,且不额外施加滑点,并按竞价成交量而不是盘口一档流动性限制成交;滑点支持 execution.slippage( \" none \" ) / execution.slippage( \" price_ratio \" , 0.001) / execution.slippage( \" tick_size \" , 1) / execution.slippage( \" limit_price \" ),其中 limit_price 会在限价单成交时按挂单价模拟 平台内核 的最坏成交价。 " . to_string ( ) ,
} ,
ManualSection {
title : " 期货提交校验 " . to_string ( ) ,
@@ -262,7 +267,7 @@ pub fn built_in_strategy_manual() -> StrategyAiManual {
fields : vec ! [
ManualField { name : " symbol " . to_string ( ) , field_type : " string " . to_string ( ) , detail : " 证券代码。 " . to_string ( ) } ,
ManualField { name : " market_cap/free_float_cap " . to_string ( ) , field_type : " float " . to_string ( ) , detail : " 总市值、流通市值。 " . to_string ( ) } ,
ManualField { name : " turnover_ratio/effective_turnover_ratio " . to_string ( ) , field_type : " float " . to_string ( ) , detail : " 换手率、有效 换手率。 " . to_string ( ) } ,
ManualField { name : " turnover/turnover _ratio/effective_turnover_ratio " . to_string ( ) , field_type : " float " . to_string ( ) , detail : " 换手率、换手率标准字段、有效换手率;turnover 是 turnover_ratio 的兼容别名 。 " . to_string ( ) } ,
ManualField { name : " open/high/low/close/last/last_price/prev_close/amount " . to_string ( ) , field_type : " float " . to_string ( ) , detail : " 开盘、最高、最低、收盘、盘中价、昨收和成交额。 " . to_string ( ) } ,
ManualField { name : " upper_limit/lower_limit/price_tick/round_lot/minimum_order_quantity/order_step_size " . to_string ( ) , field_type : " float/int " . to_string ( ) , detail : " 涨跌停、最小价位、整手、最小下单量和数量步长。KSH/BJSE 等板块可与 round_lot 不同。 " . to_string ( ) } ,
ManualField { name : " paused/is_st/is_kcb/is_one_yuan/is_new_listing " . to_string ( ) , field_type : " bool " . to_string ( ) , detail : " 可交易性与板块标志。 " . to_string ( ) } ,
@@ -323,9 +328,11 @@ pub fn built_in_strategy_manual() -> StrategyAiManual {
ManualFunction { name : " order/order_status/order_avg_price/order_transaction_cost " . to_string ( ) , signature : " ctx.order(order_id) " . to_string ( ) , detail : " 按订单 id 查询运行时订单对象,支持已结束订单和当前挂单。返回字段包括 status、filled_quantity、unfilled_quantity、avg_price、transaction_cost、symbol、side、reason;可用便捷函数读取状态、成交均价和费用,对齐 平台内核 Order 的核心属性。 " . to_string ( ) } ,
ManualFunction { name : " account/portfolio_view/accounts " . to_string ( ) , signature : " ctx.account() " . to_string ( ) , detail : " 返回当前股票账户/组合运行时视图,字段包括 account_type、cash、available_cash、frozen_cash、market_value、total_value、unit_net_value、daily_pnl、daily_returns、total_returns、transaction_cost、trading_pnl、position_pnl 等;DSL 中同名字段可直接使用。也可用 ctx.stock_account()、ctx.account_by_type( \" STOCK \" )、ctx.accounts() 按账户类型读取;当前股票回测路径不会把 FUTURE 虚假映射成 STOCK。 " . to_string ( ) } ,
ManualFunction { name : " deposit_withdraw/finance_repay/management_fee " . to_string ( ) , signature : " account.deposit_withdraw(amount, receiving_days=0) " . to_string ( ) , detail : " 策略账户资金动作。deposit_withdraw 正数入金、负数出金;receiving_days 大于 0 时按交易日延迟到账,并保持净值口径不把外部资金流当成收益。finance_repay 正数融资、负数还款,会同步维护 cash_liabilities。set_management_fee_rate 设置结算管理费率;普通策略可覆盖 management_fee(ctx, rate) 自定义计算器,对齐 平台内核 管理费回调能力。 " . to_string ( ) } ,
ManualFunction { name : " rolling_mean " . to_string ( ) , signature : " rolling_mean( \" field \" , lookback) " . to_string ( ) , detail : " 任意字段滚动均值,支持 volume/ amount/ turnover_ratio、signal_open/signal_close、benchmark_open/benchmark_close 等。个股 volume 与 close 均按 当前交易日前已完成交易日计算;单只股票 历史窗口不足时, 在选股过滤和买入仓位表达式中按不通过/0 仓处理,不会中断整次回测。任意成交量窗口推荐用它,比如 rolling_mean( \" volume \" , 15) 。" . to_string ( ) } ,
ManualFunction { name : " sma " . to_string ( ) , signature : " s ma(\" field \" , lookback )" . to_string ( ) , detail : " rolling_mean 的别名。任意价格均线窗口推荐用它,比 如 s ma( \" close \" , 15 )。" . to_string ( ) } ,
ManualFunction { name : " 复杂技术指标 " . to_string ( ) , signature : " factor_value (\" macd \" , 1) 或预计算字段 " . to_string ( ) , detail : " BOLL、EMA、WMA、DEMA、TEMA、KAMA、SAR、ADX、CCI、MACD、RSI、KDJ、WILLR、ATR、ROC、TRIX、MFI、Aroon、OBV、ADL、Beta、相关系数、线性回归、标准差、方差、K 线形态等目前不是默认内建函数;可先预计算成数值因子,再用 factor_value/rolling_mean 读取 。" . to_string ( ) } ,
ManualFunction { name : " rolling_mean / sma / ma " . to_string ( ) , signature : " rolling_mean( \" field \" , lookback) / ma( \" close \" , 20) " . to_string ( ) , detail : " 任意字段滚动均值,支持 close、 volume、 amount、turnover_ratio、effective_ turnover_ratio、signal_open/signal_close、benchmark_open/benchmark_close 和所有数值型 extra_factors。个股 close 使用 当前交易日前已完成收盘序列,volume 使用当前交易日前已完成成交量序列; 历史窗口不足时在选股过滤和买入仓位表达式中按不通过/0 仓处理。 " . to_string ( ) } ,
ManualFunction { name : " vma " . to_string ( ) , signature : " v ma(60 )" . to_string ( ) , detail : " rolling_mean( \" volume \" , lookback) 的便捷别名,用于任意窗口成交量均线,例 如 v ma(5) < vma(60 )。" . to_string ( ) } ,
ManualFunction { name : " rolling_sum / rolling_min / rolling_max " . to_string ( ) , signature : " rolling_sum (\" volume \" , 20) " . to_string ( ) , detail : " 任意数值字段滚动求和、最小值、最大值。可用于量能收缩、区间高低点、资金活跃度等过滤或排序 。" . to_string ( ) } ,
ManualFunction { name : " rolling_stddev / stddev / rolling_zscore / pct_change " . to_string ( ) , signature : " stddev( \" close \" , 20) / pct_change( \" close \" , 10) " . to_string ( ) , detail : " 滚动标准差、最新值 Z 分数和区间涨跌幅。pct_change(field, n) 会读取 n+1 个窗口点并计算 latest / first - 1。 " . to_string ( ) } ,
ManualFunction { name : " 数据库指标因子 " . to_string ( ) , signature : " factor_value( \" ths_valid_turnover_stock \" , 1) " . to_string ( ) , detail : " stock_indicator_factors_v1 中的指标会进入 extra_factors,可用 factor( \" 字段 \" )、factors[ \" 字段 \" ]、factor_value( \" 字段 \" , lookback) 或 rolling_mean( \" 字段 \" , n) 读取。市值类指标统一提供亿元口径别名 ths_market_value_stock、ths_market_value_stock_bn、ths_current_mv_stock、ths_current_mv_stock_bn,同时保留 raw 后缀原始值。 " . to_string ( ) } ,
ManualFunction { name : " round/floor/ceil/abs/min/max/clamp " . to_string ( ) , signature : " round(x) " . to_string ( ) , detail : " 常用数值函数。 " . to_string ( ) } ,
ManualFunction { name : " safe_div " . to_string ( ) , signature : " safe_div(lhs, rhs, fallback) " . to_string ( ) , detail : " 安全除法。 " . to_string ( ) } ,
ManualFunction { name : " contains/starts_with/ends_with/lower/upper/trim/strlen " . to_string ( ) , signature : " starts_with(symbol, \" 60 \" ) " . to_string ( ) , detail : " 字符串辅助函数。 " . to_string ( ) } ,
@@ -343,7 +350,7 @@ pub fn built_in_strategy_manual() -> StrategyAiManual {
} ,
ManualFactorSource {
table : " 扩展指标因子 " . to_string ( ) ,
detail : " 当前可用扩展指标主要包括总市值、流通市值、换手率、有效换手率;其他财务、行业、概念、陆股通、技术指标等只有落地为可用因子后才可在策略中直接使用 。" . to_string ( ) ,
detail : " 来自 stock_indicator_factors_v1 和运行时 extra_factors。已入库指标会自动进入策略运行时,字段名使用 dataset 小写下划线;市值类默认换算为亿元口径,raw 后缀保留原始 indicator_value 。" . to_string ( ) ,
fields : vec ! [ ] ,
} ,
ManualFactorSource {
@@ -428,10 +435,15 @@ pub fn render_manual_markdown(manual: &StrategyAiManual) -> String {
out . push_str ( " - 只使用支持语句块:`market`、`benchmark`、`signal`、`rebalance.every_days(...).at([...])`、`selection.limit`、`selection.market_cap_band`、`filter.stock_ma`、`filter.stock_expr`、`ordering.rank_by`、`ordering.rank_expr`、`allocation.buy_scale`、`risk.stop_loss`、`risk.take_profit`、`risk.index_exposure`、`execution.matching_type`、`execution.slippage`、`universe.exclude`。 \n " ) ;
out . push_str ( " - 禁止伪 DSL: `filter(...)`、`rank(...)`、`select.top(...)`、`weight.equal(...)`、`sell_rule(...)`、`backtest(...)`、`risk.max_position(...)`。 \n " ) ;
out . push_str ( " - 市值表达式字段只能用 `market_cap` 或 `free_float_cap`;不要使用数据库原始字段 `float_market_cap`。 \n " ) ;
out . push_str ( " - 60日 价格均线使用 `rolling_mean( \" close \" , 60 )`;不要使用 `ma60`、`stock_ma60`、`signal_ma60` 或 `benchmark_ma60`。 \n " ) ;
out . push_str ( " - 任意窗口 价格均线使用 `rolling_mean( \" close \" , n)` 或 `ma( \" close \" , n)`;任意窗口均量使用 `rolling_mean( \" volume \" , n)` 或 `vma(n )`;不要使用未列出的 `ma60`、`stock_ma60`、`signal_ma60` 或 `benchmark_ma60` 变量 。\n " ) ;
out . push_str ( " - 自定义 `fn` 必须通过参数传入运行时字段;不要用 `fn score()` 这类零参数函数直接引用 `market_cap`、`close`、`ma5` 等股票字段。 \n " ) ;
out . push_str ( " - `selection.market_cap_band` 必须写命名参数:`field= \" market_cap \" ` 或 `field= \" free_float_cap \" `,并包含 `lower=...` 与 `upper=...`。 \n " ) ;
out . push_str ( " - `risk.index_exposure(...)` 只能传一个表达式;`execution.matching_type(...)` 和 `execution.slippage(...)` 必须使用手册列出的合法取值。 \n \n " ) ;
out . push_str (
" - `risk.index_exposure(...)` 只能传一个表达式;不要生成 `risk.exposure(...)`。 \n " ,
) ;
out . push_str ( " - 完整三元表达式 `cond ? a : b` 可在表达式参数中使用;若当前运行环境报 `Unknown operator: '?'`,先重编译并重启回测服务,不要改写策略语义掩盖运行时漂移。 \n " ) ;
out . push_str ( " - `next_bar_open` 的选股、排序和仓位信号来自决策日,订单在下一可交易开盘撮合;不要使用执行日价格作为下单前信号。 \n " ) ;
out . push_str ( " - `execution.matching_type(...)` 和 `execution.slippage(...)` 必须使用手册列出的合法取值。 \n \n " ) ;
out . push_str ( " ## 语句块 \n " ) ;
for item in & manual . statement_blocks {
out . push_str ( & format! ( " - ` {} `: {} \n " , item . title , item . detail ) ) ;
@@ -506,9 +518,9 @@ pub fn build_generation_prompt(
prompt . push_str ( " - 生成的代码必须能转换为 strategy_spec 并提交 POST /v1/backtests。 \n " ) ;
prompt . push_str ( " - 不要使用手册未列出的字段、函数或外部平台 API 名称。 \n \n " ) ;
prompt . push_str ( " 只允许使用这些可编译语句:market、benchmark、signal、rebalance.every_days(...).at([...])、selection.limit、selection.market_cap_band、filter.stock_ma、filter.stock_expr、ordering.rank_by、ordering.rank_expr、allocation.buy_scale、risk.stop_loss、risk.take_profit、risk.index_exposure、execution.matching_type、execution.slippage、universe.exclude。禁止输出 filter(...)、rank(...)、select.top(...)、weight.equal()、sell_rule(...)、backtest(...)、risk.max_position(...) 这类未支持伪语法。 \n " ) ;
prompt . push_str ( " 参数形态必须严格:selection.market_cap_band 必须写 field= \" market_cap \" 或 field= \" free_float_cap \" , lower=..., upper=...;禁止使用 float_market_cap;禁止使用 ma60、stock_ma60、signal_ma60、benchmark_ma60, 60日价格均线写 rolling_mean( \" close \" , 60);不要生成 fn score() 这类零参数函数,股票字段排序直接写在 ordering.rank_expr 内或用带参数函数;布尔字段按布尔使用,写 !is_st、!paused、!at_upper_limit、!at_lower_limit,不要写 is_st == 0; risk.index_exposure 只能传一个数值表达式,例如 ((signal_close < signal_ma20) ? 0.35 : 1.0) ; execution.matching_type 只能取 next_tick_last、next_tick_best_own、next_tick_best_counterparty、counterparty_offer、vwap、current_bar_close、next_bar_open、open_auction; execution.slippage 必须写 execution.slippage( \" none \" ) 或 execution.slippage( \" price_ratio \" , 0.001)。 \n " ) ;
prompt . push_str ( " 参数形态必须严格:selection.market_cap_band 必须写 field= \" market_cap \" 或 field= \" free_float_cap \" , lower=..., upper=...;禁止使用 float_market_cap;禁止使用 ma60、stock_ma60、signal_ma60、benchmark_ma60, 60日价格均线写 rolling_mean( \" close \" , 60) 或 ma( \" close \" , 60),任意窗口均量写 rolling_mean( \" volume \" , n) 或 vma(n) ;不要生成 fn score() 这类零参数函数,股票字段排序直接写在 ordering.rank_expr 内或用带参数函数;布尔字段按布尔使用,写 !is_st、!paused、!at_upper_limit、!at_lower_limit,不要写 is_st == 0; risk.index_exposure 只能传一个数值表达式,不要使用 risk.exposure;完整三元表达式 cond ? a : b 可以使用,但不得输出残缺问号/冒号片段 ; execution.matching_type 只能取 next_tick_last、next_tick_best_own、next_tick_best_counterparty、counterparty_offer、vwap、current_bar_close、next_bar_open、open_auction; next_bar_open 只能使用决策日信号,不能把执行日价格当作下单前信息; execution.slippage 必须写 execution.slippage(\" none \" ) 或 execution.slippage( \" price_ratio \" , 0.001)。 \n " ) ;
prompt . push_str ( " 回测成功但 tradeCount=0 或 holdingCount=0 是无效策略;第一版必须保持稳定买入覆盖率,复杂因子只能在后续优化中逐步加严。 \n " ) ;
prompt . push_str ( " 可参考但不要照抄的最小模板,回复时不要包含 ``` 代码围栏: \n strategy( \" cn_a_smallcap_factor_rotation \" ) { \n market( \" CN_A \" ) \n benchmark( \" 000852.SH \" ) \n signal( \" 000001.SH \" ) \n rebalance.every_days(5).at([ \" 10:18 \" ]) \n selection.limit(40) \n selection.market_cap_band(field= \" market_cap \" , lower=0, upper=1000) \n filter.stock_expr(listed_days >= 60 && !is_st && !paused && close > 2 && !at_upper_limit && !at_lower_limit) \n ordering.rank_by( \" market_cap \" , \" asc \" ) \n allocation.buy_scale(1.0) \n risk.index_exposure((signal_close < signal_ma20) ? 0.35 : 1.0) \n risk.stop_loss(holding_return < -0.08) \n execution.slippage( \" price_ratio \" , 0.001) \n } \n \n " ) ;
prompt . push_str ( " 可参考但不要照抄的最小模板,回复时不要包含 ``` 代码围栏: \n strategy( \" cn_a_smallcap_factor_rotation \" ) { \n market( \" CN_A \" ) \n benchmark( \" 000852.SH \" ) \n signal( \" 000001.SH \" ) \n rebalance.every_days(5).at([ \" 10:18 \" ]) \n selection.limit(40) \n selection.market_cap_band(field= \" market_cap \" , lower=0, upper=1000) \n filter.stock_expr(listed_days >= 60 && !is_st && !paused && close > 2 && !at_upper_limit && !at_lower_limit) \n ordering.rank_by( \" market_cap \" , \" asc \" ) \n allocation.buy_scale(1.0) \n risk.index_exposure(1.0) \n risk.stop_loss(holding_return < -0.08) \n execution.slippage( \" price_ratio \" , 0.001) \n } \n \n " ) ;
prompt . push_str ( " 用户目标: \n " ) ;
prompt . push_str ( & format! ( " - {} \n " , request . user_goal ) ) ;
if ! request . constraints . is_empty ( ) {
@@ -535,6 +547,7 @@ pub fn build_optimization_prompt(
prompt . push_str ( " 输出格式硬约束:回复第一行必须是 strategy( \" ... \" )、let、fn、const 或 //;回复中不得包含 Markdown、解释、思考过程、手册复述、JSON 包装或自然语言总结。 \n " ) ;
prompt . push_str ( " 长度硬约束:策略代码目标 80 行以内,只保留必要 let/fn/strategy 块;不要复制下面的手册片段、历史策略全文或字段清单。 \n " ) ;
prompt . push_str ( " 只修改与优化目标相关的少量参数或过滤条件,保留原策略的市场、基准、信号指数和核心风控;不要引入手册未列出的字段或外部平台 API 名称。 \n " ) ;
prompt . push_str ( " 优化可以调整调仓周期、持仓数、市值带、filter.stock_expr、ordering.rank_expr、allocation.buy_scale、止盈止损;如上一轮无交易或质量分过低,必须先放宽过滤条件并优先使用已入库指标因子、rolling_mean/ma/vma/rolling_stddev/pct_change 等支持函数。 \n " ) ;
prompt . push_str ( " 优化目标: \n " ) ;
prompt . push_str ( & format! ( " - {} \n \n " , request . objective ) ) ;
prompt . push_str ( " 当前策略代码如下,仅作为输入参考;回复时不要包含 Markdown 代码围栏: \n " ) ;