Files
shy3130 ffe1ff0d3e feat(import): 统一导入备份入口并支持后端扩展包
集中处理策略与定义、配置备份、数据源和页面插件导入,保留旧入口跳转。新增可信后端及前后端完整包的预检、暂存、重启生效、失败回退和版本管理。

验证:扩展、资源、备份与页面定向 pytest 通过,前端 41 项测试及生产构建通过,并完成桌面、窄屏和明暗主题联调。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-11-01 20:01:59 +08:00

112 lines
9.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 策略指南
策略是策略引擎、回测、监控的基础。本文介绍策略体系与三种扩展方式。
完整策略开发规范(AI 生成与手写)见 [`backend/app/strategy/prompts/strategy-guide.md`](../backend/app/strategy/prompts/strategy-guide.md)。
---
## 示例策略
**策略全部是用户自定义文件**,每个策略一个独立 Python 文件,基于 Polars 表达式向量化实现,存放在 `data/strategies/custom/`(可编辑、可删除);原 25 个示例策略已随数据目录一次性迁移为普通自定义策略。按类型概览:
| 类型 | 代表策略 |
| :---------- | :------------------------------------------------------- |
| 趋势 / 形态 | 趋势突破 · 均线多头 · MA 金叉 · MACD 金叉放量 · 布林突破 · 均线粘合突破 · 平台整理突破 · 放量创60日新高 |
| 量价 / 涨停 | 量价齐升 · 高换手强势 · 连板股 · 断板反包 · 涨停动量 · 接近涨停 · 涨停基因活跃股 |
| 反转 / 波动 | 超跌反弹 · 超卖反转 · 新低反转 · 低波动龙头 · 回踩 MA20 · 回踩支撑 · 强势开盘 · MACD 零下回升 · 长下影反击 · RSI 中轴回踩 |
`backend/app/strategy/research/` 保留一个仅供挖掘 worker 使用的受控因子排名研究模板(research_only)。它不出现在普通策略列表,也不能通过普通策略 API 直接运行或删除;挖掘结果发布时会生成独立策略。详见 [因子与策略挖掘](./mining.md)。
策略引擎只加载用户数据目录(`data/strategies/custom|ai|composite`)与研究模板目录,**不再有内置策略目录**;新装环境策略库为空。旧版本升级用户首次启动时自动把 25 个原内置策略补回为自定义文件(按 ID 补缺、不覆盖已有,删除后重启不复活)。AI 生成的策略只落入 `data/strategies/ai/`。
「策略池」窗口按策略库和已选列表组织。可搜索名称、ID 或描述,组合来源和周期筛选;勾选后条目仍保留在策略库中并显示“已加入”。已选列表可拖动或用上下按钮排序,清空后可“撤销清空”,也可“还原”打开窗口时的选择;只有点击“保存策略池”才应用选择。失效项须显式移除,列表加载失败时禁止保存并提供重试。窄屏在策略库和已选列表间切换。AI 草稿需先发布;发布立即生效,加入池仍须另行保存。
---
## 扩展策略的三种方式
### 🎛️ 方式一:自定义信号(不写代码)
在策略页 UI 上用 `字段 + 操作符 + 阈值` 组合,编译成 Polars 表达式热加载。适合:
- 快速验证一个简单的筛选思路(如 `RSI < 30 AND 量比 > 2`)
- 不熟悉 Python 但想自定义筛选条件
底层实现在 `backend/app/strategy/custom_signals.py`。
### 🤖 方式二:AI 生成
一句话描述思路,LLM 读取精简运行时指南生成完整策略文件:
1. **配置 AI 接口**(留空即关闭,见 [configuration.md → AI](./configuration.md#ai可选)):
```ini
AI_PROVIDER=openai_compat
AI_BASE_URL=https://api.deepseek.com/v1
AI_API_KEY=sk-...
AI_MODEL=deepseek-chat
```
2. 在策略页打开「AI 策略生成器」,用自然语言描述你的策略思路
3. 前端流式接收生成代码,后端经 `ast` 安全校验(import 白名单 + 危险内建引用/dunder 遍历/模块命名空间句柄/文件读写原语拦截,实现见 `ai_generator._validate_safety`)后返回结果
4. 保存后落入 `data/strategies/ai/`,文件名/ID 用 `ai_` 前缀
生成策略相关提示词位于 `backend/app/strategy/prompts/`:
- `strategy-guide-compact.md` — AI 运行时精简指南(用于降低长请求超时概率)
- `strategy-guide.md` — 完整策略开发规范(供人工开发和详细参考)
- `strategy-builder-step2.md` — 步骤 2 提示词模板(修改已有策略)
- `strategy-example.md` — 从零创建强势反包策略的三步演示
> 💡 **文件与范围铁律**:AI 生成的策略只生成一个 `.py` 文件,只 `import polars as pl`,绝不修改 `backend/`、`docs/`、`frontend/` 等现有文件。
生成之后的持续改进(假设—验证—判定闭环),见 [AI 策略迭代指南](./strategy-iteration.md)。
### 📝 方式三:自定义编写 / 代码迁移
可以在策略页「自定义编写」中直接编辑策略代码并保存,新建自定义策略会落入 `data/strategies/custom/`,文件名/ID 用 `custom_` 前缀。也可以手动把已有策略改写为 Polars 文件后放入该目录,引擎会自动发现;或用策略页顶部的**导入与导出图标**打开「导入策略」,上传 `.py` 文件。
手写策略需遵循 [`strategy-guide.md`](../backend/app/strategy/prompts/strategy-guide.md) 的文件结构(META / basic_filter / scoring / ENTRY_SIGNALS / filter 等),完整规范见该文档。
### 资源导入与批量导出
策略、因子和信号页顶部各有一个**小盒子图标**,进入「设置 → 导入与备份」并保留资源类型上下文;策略页入口位于右侧基础配置按钮左边。统一页展示资源与关联依赖,自动携带所需依赖;批量导出使用同页的资源导出入口。
单个策略的下载入口位于策略配置对话框顶部,导出的 ZIP 包包含策略源码、已保存调参、相关自定义因子和信号(及其递归依赖);未保存修改须先保存后再导出。页面顶部的小盒子弹窗内可批量导出多项策略、因子或信号,完成后关闭窗口继续使用当前页面。
- **批量导出**:按名称或 ID 搜索,可多选、全选当前筛选结果;选择不改变运行策略池。先预览包内清单,再下载一个 ZIP。策略源码、已保存调参、引用的信号、因子、叠加子策略与同目录辅助模块随依赖携带,共享依赖只保存一份。也可单独导出信号、自定义/组合因子或用户 AI 草稿,内置因子无需打包。
- **统一导入**:支持新资源包、旧策略包、含字面量 `META.id` 的策略 `.py`、信号/因子 `.json`,也支持直接将这些文件压成的普通 ZIP(可有外层文件夹,无需 `manifest.json`);自动忽略说明文档与 macOS 附加文件。可一次混合选择多个 ZIP、策略和定义文件,一起补齐依赖。文件先识别预览,尚不写入;优先选择包内属于当前页面类型的原始导出项;若没有此类原始项,则列出并选择包内该类型的定义(例如在因子页从策略包提取因子)。也可只选其中一部分,所需依赖自动关联。
- **重复与冲突**:同 ID 且内容相同自动复用;内容不同须逐项确认替换,可展开比较两份内容并查看本机引用方。不自动改 ID,也不静默替换已有定义。同一策略 ID 位于不同来源目录时拒绝导入。
- **一致性**:校验所选资源与本机已有依赖的合并快照;缺少依赖或存在循环时阻止相关选择导入。预览后本机资源发生变化须重新预览。写入、因子注册或策略重载失败时回滚本次所选批次,成功后刷新运行缓存与页面查询。导入不改变策略池配置,也不自动发布草稿。
AI 策略 `.py` 未声明发布状态时默认导入为草稿;资源包中明确的草稿/发布状态则原样保留。AI 草稿可在策略池的「AI」分组发布后使用。
因子排名等 `matrix_native` 策略的进出场信号由策略计算,`signal_factor_rank_entry` / `signal_factor_rank_exit` 是输出标签,无需在信号库创建同名定义。打包和预检不把这些输出标签作为外部依赖;显式输入列、评分因子以及普通策略引用的自定义信号仍需完整。新生成的因子排名策略引用 `app.strategy.research.factor_rank_research`,旧 `app.strategy.builtin.factor_rank_research` 转发路径继续兼容。
资源包只包含策略/调参/信号/因子及策略辅助代码,不包含行情、计算缓存、账号或密钥;全量设备迁移仍使用「配置备份」。依赖识别覆盖评分、进出场信号、叠加条件、组合成员和源码中明确的自定义列引用;动态拼接的列名应通过 `META.required_features` 或 `REQUIRED_FEATURES` 显式声明。
新包使用 `tick-resource-bundle` v1,条目路径沿用配置备份白名单。统一接口位于 `/api/definitions/resources`:GET 查询目录;POST `/export/preview` 预览导出、`/export` 下载、`/inspect` 预览导入、`/apply` 提交导入。旧 `/api/strategies/{id}/bundle` 与旧策略包格式继续兼容;旧接口保留默认跳过同名文件、逐文件报告导入结果的行为。
清单由应用在导出 ZIP 时自动生成,用于保存原始选择、版本和依赖信息,不是手工导入的前置条件。无清单 ZIP 按文件内容识别资源;保留标准资源目录时也会保留策略来源、辅助模块与已保存调参。有清单的包仍校验其格式和版本,损坏或不兼容的清单会明确报错。
---
## 策略文件结构(简述)
一个策略 `.py` 文件通常包含:
| 部分 | 作用 |
| :--- | :--- |
| `META` | 策略元信息(名称、参数、方向等),用户可在 UI 调整阈值 |
| `basic_filter(df, params)` | 模式 A:单日过滤,返回 `pl.Expr` |
| `filter_history(df, params)` | 模式 B:历史窗口过滤,返回 `pl.DataFrame`(配 `LOOKBACK_DAYS`) |
| `scoring` | 策略权重,总和 = 1.0 |
| `ENTRY_SIGNALS` / `EXIT_SIGNALS` | 进出场信号列(回测用) |
完整字段说明与示例见 [`strategy-guide.md`](../backend/app/strategy/prompts/strategy-guide.md)。
---
## 新增示例策略(贡献者)
如果你想随项目分发一个示例策略:在 `backend/tests/fixtures/strategies/` 维护参考实现(仅测试用);面向用户的策略分发请直接提供 `.py` 文件由用户导入 `data/strategies/custom/`,引擎会自动发现并加载。