fix: align AI strategy prompt constraints

This commit is contained in:
shy3130
2026-07-18 18:31:02 +08:00
parent ff12790042
commit e462c63b45
4 changed files with 33 additions and 16 deletions
@@ -20,19 +20,19 @@
## 你应该做的事
- 增/删/改参数 → 更新 META["params"],同步修改 filter()
- 增/删/改参数 → 更新 META["params"],同步修改当前执行后端对应的 `filter()``filter_history()``MATRIX_STRATEGY`
- 调整信号 → 更新 ENTRY_SIGNALS / EXIT_SIGNALS
- 修改止损/持有 → 更新 STOP_LOSS / MAX_HOLD_DAYS
- 增减告警 → 更新 ALERTS
- 调整评分 → 更新 META["scoring"],权重总和保持 100
- 调整评分 → 更新 META["scoring"];只使用真实数值字段或受控虚拟字段 `ma20_bias`,权重总和保持 1.0
- 修改筛选逻辑 → 更新唯一公式;新增历史回溯时切换为 `python_history_legacy` + `filter_history()`,移除回溯时切回 `polars_expr` + `filter()`,不得同时保留两套公式
## 规则
1. 保持策略文件结构完整,不丢失任何已有字段(包括 RULES)
2. 删除参数后 filter() 中用原 default 值代替
3. 新增参数要有 type、label、default、min、max、step
4. 删除信号时 ENTRY_SIGNALS / EXIT_SIGNALS 至少保留一个
1. 保持策略文件结构完整,不丢失任何已有字段(包括 RULES)`META` 必须保持为模块顶层字面量字典 `META = {...}``META: dict = {...}`
2. 删除参数后,在当前执行入口中用原 default 值代替
3. 新增参数必须有 id、type、label、defaultfloat/int 增加 min、max、stepselect 增加 options
4. ENTRY_SIGNALS / EXIT_SIGNALS 只保留与策略逻辑直接相关的信号;没有匹配信号时允许为空,不得凑数
5. 如果修改了筛选逻辑,同步更新 RULES 中的对应条目
6. 用户可能调节的阈值才需要放入 META["params"];公式常数、固定窗口边界不必强行参数化
7. 优先使用 Polars 表达式、窗口函数、聚合和 join,不要默认改成逐行/逐股 Python 循环
@@ -4,14 +4,15 @@
## 必须遵守
1. Polars/历史策略允许 `polars``datetime`;矩阵策略允许 `numpy``app.backtest.matrix`
2. AI 策略只属`data/strategies/ai/``META.id` 使用用户给定的 `ai_` ID。
3. 不要读写文件,不要使用 `open/exec/eval/compile/__import__/globals/locals/vars/dir/getattr/setattr/delattr/type/input`
4. `META.params` 每项使用 `id/label/type/default/min/max/step`只放可调阈值
5. `META.scoring` 仅使用真实数值字段或 `ma20_bias`,权重和为 1.0。
6. `ENTRY_SIGNALS` / `EXIT_SIGNALS` 只选和策略逻辑直接相关信号,不要凑数
7. `RULES` 用中文逐条列出核心逻辑,至少 3 条。
8. 优先 Polars 表达式、`with_columns``over("symbol")``group_by``join``filter`,避免逐行循环。
1. Polars/历史策略限用 `polars/datetime`;矩阵策略限用 `numpy/app.backtest.matrix`
2. AI 策略`data/strategies/ai/``META.id` 用指定的 `ai_` ID。
3. 禁止文件读写和 `open/exec/eval/compile/__import__/globals/locals/vars/dir/getattr/setattr/delattr/type/input`
4. `META.params` 只放可调项:必填 `id/label/type/default`;数值项加 `min/max/step`select 加 `options`
5. `META.scoring` 用真实数值字段或 `ma20_bias`,权重和为 1.0。
6. `ENTRY_SIGNALS/EXIT_SIGNALS` 只选相关信号,无匹配项可为空
7. `RULES` 用中文列出至少 3 条核心逻辑
8. 优先 Polars 向量化,避免逐行循环。
9. `META` 须为顶层字面量字典(可用 `META: dict = {...}`),禁止改名或动态构造。
## 文件结构
@@ -220,6 +220,12 @@ REQUIRED_FEATURES = {"ma20", "momentum_20d", "vol_ratio_5d"}
| annual_vol_20d | 20日年化波动率 |
| high_60d, low_60d | 60日最高/最低价 |
### 受控虚拟评分字段
| 列名 | 说明 |
|------|------|
| ma20_bias | `close / ma20 - 1`,仅在内存中计算,不写入数据表 |
### 涨跌停
| 列名 | 说明 |
@@ -281,7 +287,7 @@ REQUIRED_FEATURES = {"ma20", "momentum_20d", "vol_ratio_5d"}
1. `filter()` 必须返回 `pl.Expr` (用 `&` `|` 组合布尔表达式)`filter_history()` 返回筛选后的 `DataFrame`
2. 信号列使用 `.fill_null(False)` 处理空值
3. 用户可能调节的数值阈值通过 `params` 暴露;公式常数、固定窗口边界、一次性内部变量不必强行参数化
4. `scoring` 权重总和必须为 1.0
4. `scoring` 只能使用上述真实数值字段或受控虚拟字段 `ma20_bias`,权重总和必须为 1.0;不要使用条件名称或信号列作为评分字段
5. 遵循 A 股 T+1 规则 (当日买入次日才能卖出)
6. Polars 策略允许 `import polars as pl``from datetime import date/datetime`;矩阵策略只允许 NumPy 和 `app.backtest.matrix` 协议/算子
7. 禁止使用 `open()`, `exec()`, `eval()`, `os`, `sys`, `subprocess`
+11 -1
View File
@@ -3,7 +3,7 @@ from __future__ import annotations
import pytest
from app.strategy.ai_generator import GUIDE_PATH, AIStrategyGenerator
from app.strategy.prompt_builder import build_step1
from app.strategy.prompt_builder import build_step1, build_step2
def test_ai_strategy_generator_uses_compact_guide():
@@ -31,6 +31,16 @@ def test_build_step1_keeps_user_prompt_compact():
assert len(prompt) < 1000
def test_build_step2_uses_runtime_meta_constraints():
prompt = build_step2("META = {}", "调整参数和评分")
assert "权重总和保持 1.0" in prompt
assert "权重总和保持 100" not in prompt
assert "filter()`、`filter_history()` 或 `MATRIX_STRATEGY" in prompt
assert "没有匹配信号时允许为空" in prompt
assert "模块顶层字面量字典" in prompt
def test_matrix_backend_prompt_and_imports_are_supported():
prompt = build_step1(
"矩阵策略",