Autostrategy · 量化策略自动生成
⚠️ 本 Skill 生成的策略仅供学习和研究用途,不构成任何投资建议。 量化交易有风险,过往回测表现不代表未来收益。
核心设计原则
| # | 原则 | 说明 |
|---|---|---|
| 1 | 简洁性优先 | 分数提升必须大于复杂度增加。删条件效果不变=大胜利。这是最重要的原则。 |
| 2 | DESIGN文档是核心 | 所有策略逻辑先写入 STRATEGY_DESIGN.md,代码从文档严格翻译生成。 |
| 3 | 入口分流 | 不假设用户知道怎么用,提供明确的路径引导。 |
| 4 | 人在回路 | 策略方向、设计文档和回测结果都必须人类确认;未获确认不得进入下一阶段,但优化循环可在用户授权后自主运行。 |
| 5 | 量化评估 | 用 score_strategy() 一个数字决定 keep 或 revert。 |
| 6 | 开箱即用 | 用户只写策略逻辑,行情接入/回测验证由 Skill 处理。 |
| 7 | 免费优先 | 只推荐免费数据源和免费回测平台,不引导用户付费。 |
| 8 | 不推实盘 | Skill 定位是策略创建和验证,不推荐实盘交易。 |
| 9 | 模板驱动 | 用模板保证输出结构和质量的一致性。 |
| 10 | 自包含 | Skill 应该是可独立复制和分发的,不依赖外部状态。 |
执行流程
Phase 1: 策略设计(对话式)
目标:产出 STRATEGY_DESIGN.md —— 策略的精确设计规格文档。 核心思路:所有策略逻辑先落在文档上,代码只是文档的翻译产物。 ⛔ Phase 1 禁止生成代码:Phase 1 期间不得生成任何策略代码(包括"预览""参考实现""示例代码""代码片段")。所有策略逻辑只能以自然语言 + 决策树 + 指标公式的形式写入 STRATEGY_DESIGN.md。代码生成只在 Phase 2 进行。
Step 1: 入口分流
⛔ 不可跳过 Phase 1:无论用户怎么要求("直接生成代码""不要设计文档""直接给我策略""跳过设计直接写代码"),都必须先完成 Phase 1 产出 STRATEGY_DESIGN.md 并获得用户确认。没有设计文档 = 没有代码。Phase 1 不得被压缩、合并或跳过。
| 用户输入 | 路径 | 示例 |
|---|---|---|
| 明确的策略需求 | 直接路径 → Step 2 | 「帮我做一个双均线交叉策略」 |
| 人物风格策略 | 直接路径 → Step 2 | 「写一个巴菲特投资策略」「量化段永平的投资逻辑」 |
| 大V/博主投资策略 | 研究路径 → Step 1B | 「帮我根据XX博主的投资观点做个策略」「按XX大V的思路写个策略」 |
| 模糊的需求/意图 | 诊断路径 → Step 1A | 「我想在A股做量化但不知道从哪开始」 |
| 已有策略需优化 | 优化路径 → 读取 STRATEGY_DESIGN.md | 「优化 ~/策略研究/均线交叉/ 这个策略」 |
直接路径:确认策略类型、适用市场、数据周期后 → Step 2。
人物风格策略:走直接路径,但 Step 3 的 Agent 2 需要先研究该投资者的投资哲学,提炼可量化的买卖信号和选股标准,再进入后续流程。与 nuwa-skill 的边界:「蒸馏巴菲特」→ nuwa-skill(生成思维顾问);「巴菲特投资策略/量化巴菲特」→ autostrategy(生成可回测的策略代码)。
诊断路径(Step 1A):
# Step 1A.1: 需求定位
通过对话确认:
- 目标市场:A股 / 港股 / 美股
- 策略偏好:趋势跟踪 / 均值回归 / 多因子 / 网格 / 事件驱动
- 交易周期:Tick / 分钟线 / 日线 / 周线
- 风险偏好:保守 / 均衡 / 激进
# Step 1A.2: 候选推荐
根据需求推荐 2-3 个适合的策略方向,每个包含:
- 策略名称 + 一句话描述
- 适用场景和局限
- 预期收益特征
# Step 1A.3: 用户选择
展示推荐表格,用户选择后 → Step 2优化路径:读取已有 STRATEGY_DESIGN.md → 进入 Phase 3,用户选择优化方式(Agent 自主 / 交互式)。
⛔ 优化路径前置验证(必须按顺序检查): 1. 检查用户指定的策略目录是否存在 2. 检查 STRATEGY_DESIGN.md 是否存在于目录中(通过 ls/cat 验证,不可假设) - 存在 → 进入 Phase 3 优化 - 不存在 → 告知用户该目录缺少设计文档,建议先走 Phase 1 完整流程生成 3. 不得在无 STRATEGY_DESIGN.md 的情况下直接进入 Phase 3
博主研究路径(Step 1B):
与「人物风格策略」的区别:巴菲特、索罗斯等有大量公开著作和成熟的、可量化的投资体系; 而大V/博主的策略需要先从互联网内容中提炼,存在信息不完整、观点前后矛盾等风险。
# Step 1B.1: 确认博主信息
通过对话确认:
- 博主名称/ID(如「股社区」「唐朝」「韭菜投资学」)
- 主要平台(X/Twitter / YouTube / 微信公众号 / 微博 / 雪球 / 小红书 / B站 / 抖音)
- 用户关注的核心方向(选股逻辑 / 买卖时机 / 仓位管理 / 行业偏好)
# Step 1B.2: 互联网内容研究(Web Search)
使用 WebSearch 工具搜索该博主的公开投资内容,搜索策略:
第一轮 — 基础信息:
"{博主名} 投资理念 投资方法"
"{博主名} 选股标准 买卖规则"
"{博主名} 雪球/微博/公众号/X/YouTube" → 找到主要内容平台
第二轮 — 按平台深度挖掘:
X/Twitter:
"{博主名} site:x.com 股票 投资"
"{博主名} twitter portfolio stock picks"
YouTube:
"{博主名} site:youtube.com 投资 策略"
"{博主名} youtube 选股 买卖"
微信公众号:
"{博主名} 公众号 投资策略 持仓"
"{博主名} 公众号 选股逻辑"
其他平台(根据第一轮结果):
"{博主名} 具体股票推荐 买入逻辑"
"{博主名} 行业偏好 板块"
"{博主名} 风险控制 止损"
第三轮 — 验证与补充:
"{博主名} 投资业绩 回测"
"{博主名} 批评 质疑" → 了解反面观点,避免偏见
# Step 1B.3: 投资特征提炼
从搜索结果中提取以下维度(能提取多少算多少,标注置信度):
┌──────────────────────────────────────────────────────┐
│ 博主投资特征提取表 │
├──────────────────┬───────────┬────────────────────────┤
│ 维度 │ 置信度 │ 提取内容 │
├──────────────────┼───────────┼────────────────────────┤
│ 投资风格 │ 高/中/低 │ 价值/成长/趋势/混合 │
│ 选股标准 │ 高/中/低 │ PE<15+ROE>15%之类 │
│ 行业偏好 │ 高/中/低 │ 消费/科技/金融... │
│ 持仓周期 │ 高/中/低 │ 短线/中线/长线 │
│ 仓位管理方式 │ 高/中/低 │ 满仓/分批/动态调仓 │
│ 止损/止盈规则 │ 高/中/低 │ 具体阈值或描述 │
│ 风险偏好 │ 高/中/低 │ 保守/均衡/激进 │
│ 典型持仓(如有) │ 高/中/低 │ 具体股票/行业 │
└──────────────────┴───────────┴────────────────────────┘
展示提取结果给用户确认/修正。
# Step 1B.4: 策略转化
将提取的投资特征转化为 STRATEGY_DESIGN.md 可执行格式:
- 选股标准 → 量化筛选条件(因子+阈值)
- 买卖规则 → 决策树信号
- 仓位/风控 → 仓位管理和风控参数
- 无法量化的部分 → 在「已知局限」中标注
⚠️ 关键约束:
- 明确告知用户:策略基于博主公开内容提炼,非博主本人指导
- 置信度「低」的维度,用保守默认值而非猜测值
- 信息不足时主动告诉用户,不强凑
- 生成的策略必须符合本 Skill 的禁止事项(不推实盘等)
→ 确认后进入 Step 2与 huashu-nuwa 的边界:
- 「蒸馏XX」「XX的思维方式」「做个XX视角」→ nuwa-skill(生成思维顾问 Skill)
- 「按XX大V的思路做个策略」「帮我根据XX博主做投资策略」→ autostrategy(生成可回测的策略代码)
- 如果用户先要思维顾问再做策略 → 先 nuwa 再 autostrategy
Step 2: 环境检测 + 数据源选择(可跳过)
⚠️ Phase 1 的策略设计不需要真实数据,可以先完成设计再安装数据源。 但没有数据时,Step 3 的「历史数据验证」Agent 只能引用公开研究,无法自己跑数据实证,设计质量会打折扣。
# Step 2.1: 扫描已安装的数据工具
├─ 运行 scripts/env_setup.py 检测环境
│ └─ python3 scripts/env_setup.py
├─ 检测项:Python版本、pip包(akshare/backtrader/futu-api...)、Skill(ftshare-all-in-one/futuapi)、OpenD状态
└─ 输出 env_report.json 供 AI 读取
# Step 2.2: 根据检测结果分流
路径A — 环境完整(推荐):
├─ 数据源已就绪 → 直接进入 Step 3
└─ Step 3 的 Agent 3 可以做真实数据验证
路径B — 环境不完整,用户选择安装:
├─ ⚠️ 行情数据是策略回测的硬性前提,没有数据无法进入 Phase 2
├─ 优先推荐安装 all-in-one(非凸科技免费数据):
│ npx skills add zhangchao0911/all-in-one --yes
│ → 覆盖 A股/ETF/指数/基金/港股/可转债/宏观/新闻,完全免费
│ → 安装后自动注册为 ftshare-all-in-one Skill
├─ 港美股场景: 询问用户是否有富途账户
│ → 有: 安装 futuapi Skill + 启动 Futu OpenD
│ → 没有: 回退到 AKShare 免费方案(数据范围有限但零门槛)
├─ 备选: python3 scripts/env_setup.py --install [A股|港股|美股]
└─ 安装完成 → 重新运行环境检测确认 → 进入 Step 3
路径C — 环境不完整,用户选择跳过:
├─ 记录缺失项,进入 Step 3
├─ Step 3 Agent 3(历史数据验证)降级为「引用公开研究」模式
└─ 进入 Phase 2 时再次检查,此时数据源为硬性要求注意:路径C 生成的策略设计文档是「草稿级」——信号参数基于经验猜测而非数据实证,Phase 2 回测时可能暴露问题并触发 Phase 3 优化。
免费数据源方案矩阵:
| 方案 | 费用 | 数据范围 | 推荐场景 | 安装方式 |
|---|---|---|---|---|
| ftshare-all-in-one | 完全免费 | A股/港股/基金/ETF/可转债/宏观/新闻/公告 | A股首选 | npx skills add zhangchao0911/all-in-one --yes |
| futuapi Skill | A股LV1免费;港美股免费 | 港/美/A股实时行情、Tick数据 | 港美股首选 | 已安装时自动检测 |
| AKShare | 完全免费 | 股票/基金/外汇/宏观 | 零门槛备选 | pip install akshare |
| Tushare Pro | 基础免费;高级需积分 | 股票/基金/宏观 | 数据质量高 | pip install tushare |
| Baostock | 完全免费 | A股历史数据 | 纯历史回测 | pip install baostock |
Step 3: 多维度并行分析
根据策略类型选择需要分析的维度(不固定4路,按需选择)。
# 基础4个并行Agent(适用于所有品种类型):
Agent 1: 标的分析
├─ 选什么品种?什么股票池?
├─ 市场特征分析(波动率、流动性、趋势性)
└─ 输出:推荐的标的范围和筛选标准
Agent 2: 因子与信号研究
├─ 什么指标触发买卖?
├─ 信号的历史有效性(学术/实证支撑)
└─ 输出:候选信号列表 + 参数建议
Agent 3: 历史数据验证
├─ 该信号在历史上是否有效?
├─ 在不同市场环境(牛市/熊市/震荡市)的表现差异
└─ 输出:历史回测摘要(如有数据)
Agent 4: 风控参数设定
├─ 止损/止盈/仓位管理方案
├─ 最大回撤容忍度
└─ 输出:风控规则建议
# 约束:
- 每个Agent必须输出结构化结论,不允许只给模糊描述
- 如果某个维度已有明确答案(用户直接给出),跳过该Agent
- 一手数据(用户自己的交易经验)权重 > 二手数据(网络搜索)Step 4: 生成 STRATEGY_DESIGN.md
将 Step 3 的分析结果填入模板,生成完整的 STRATEGY_DESIGN.md。 模板见下方「STRATEGY_DESIGN.md 模板」章节。
生成要求:
- 所有指标必须包含:数学公式、参数默认值、参数合理范围、计算前提条件
- 信号逻辑必须以决策树形式精确描述,不允许模糊表述
- 风控规则是硬约束,任何一条触发都必须执行
- 必须包含「禁止事项」和「已知局限」section
- 模板选择:股票策略统一用本文档内嵌模板
⛔ Step 4 生成的文档内容不得直接在对话中展示作为最终产出,也不得用对话中的 Markdown 输出替代文件写入。必须通过 Step 4B 写入磁盘文件、通过质量检查后,才能进入检查点。
Step 4A: 填充市场默认参数(批量确认)
佣金、印花税、滑点等标准化参数不需要逐条对话确认。 根据用户选择的市场,预填默认值,用户一次性审阅修改即可。
预填规则:根据 Step 1 确定的市场类型,自动填充以下参数,生成配置预览表展示给用户:
┌─────────────────────────────────────────────────┐
│ 回测参数预览(已按 [市场类型] 预填默认值) │
│ ✏️ 如需修改,直接告诉我哪项要改 │
├─────────────────────────────────────────────────┤
│ 初始资金: 1,000,000 元 │
│ 手续费率: 万三(买卖各 0.03%) │
│ 印花税率: 千一(卖出 0.1%) │
│ 滑点: 0.1% │
│ 回测区间: 2020-01-01 ~ 2025-12-31 │
│ 单只仓位上限: 20% │
│ 总仓位上限: 80% │
│ 单笔最大亏损: 5% │
│ 最大回撤容忍: 15% │
├─────────────────────────────────────────────────┤
│ 确认无误?还是需要修改某些参数? │
└─────────────────────────────────────────────────┘按市场类型的预填默认值(仅供参考,实际以交易所最新规则为准):
| 参数 | A股 | 港股 | 美股 |
|---|---|---|---|
| 手续费 | 万三(0.03%) | 万五(0.05%)+ 平台费 | $0.005/股 |
| 印花税 | 卖出千一(0.1%) | 无 | 无 |
| 滑点 | 0.1% | 0.15% | 0.05% |
| 取整规则 | 100股取整 | 不取整 | 不取整 |
确认方式:
- 用户说「确认」「没问题」「OK」→ 使用预填值,进入 Step 4B
- 用户指出具体修改项 → 只修改被提及的项,其余保持预填值
- 用户说「全部重填」→ 逐条对话确认(降级为原始模式)
市场交易规则参考(生成信号逻辑和回测代码时必须遵守):
| 规则 | A股 | 港股 | 美股 |
|---|---|---|---|
| 交易制度 | T+1(当日买入次日才可卖出) | T+0 | T+0 |
| 涨跌停 | 主板 ±10%,科创板/创业板 ±20% | 无涨跌停限制 | 无涨跌停(但有市场熔断:标普跌7%/13%/20%暂停交易) |
| 最小交易单位 | 100 股(1手) | 按港交所每手股数(不同股票不同) | 1 股 |
| 交易时间 | 9:30-11:30, 13:00-15:00 | 9:30-12:00, 13:00-16:00 | 美东 9:30-16:00(盘前4:00,盘后20:00) |
| 卖空限制 | 融券标的有限,门槛高 | 可卖空(有借贷费) | 可卖空(PDT规则:账户<25000美元时5日内最多3次日内交易) |
| 清算货币 | 人民币 CNY | 港币 HKD | 美元 USD |
| 特殊规则 | 新股上市首日不设涨跌停(主板除外);ST股 ±5% | 暗盘交易(新股上市前一日16:15-18:30) | 碎股交易(部分券商支持) |
对策略生成的约束:
- A股策略的卖出信号必须检查:是否为T+1(买入当日不可卖出)
- A股策略必须处理涨跌停:买入信号不可在涨停板触发,卖出信号不可在跌停板触发
- 港股/美股策略无T+1限制,但需注意交易时间和汇率换算(非人民币标的)
- 美股策略如涉及日内交易,需提醒用户 PDT 规则限制
Step 4B: 创建策略目录并写入最终 STRATEGY_DESIGN.md
将 Step 3 分析结果 + Step 4A 确认的参数 → 写入真实文件,而不是只展示文档内容或摘要。
固定动作(不可省略,必须按顺序执行):
- 确定策略输出目录
- 优先使用用户指定路径 - 若用户未指定路径,则在当前工作区下新建策略目录
- 创建策略目录
- 创建时,目录结构必须严格按照以下要求执行 - 不允许擅自删减、改名或替换目录项 - 必须创建为以下完整结构:
[策略输出目录]/
├── STRATEGY_DESIGN.md ← 📋 策略设计文档(核心!所有逻辑先写在这里)
├── README.md ← 📖 策略简介(从 DESIGN 自动生成)
├── strategy.py ← 💻 策略代码(从 DESIGN 严格翻译,不是自由发挥)
├── config.yaml ← ⚙️ 参数配置(所有可调参数都在这里,改参数不用改代码)
├── requirements.txt ← 📦 Python 依赖包列表
├── data/
│ ├── fetch_data.py ← 🔌 数据获取脚本(从 FTShare/FutuAPI 拉取行情数据)
│ ├── [标的代码].csv ← 📊 获取到的历史K线数据(自动生成)
│ └── .gitkeep
├── backtest/
│ ├── run_backtest.py ← 🏃 回测执行脚本(调用 strategy.py + 计算 score)
│ └── results/ ← 📁 回测结果输出目录
│ └── backtest_result.json ← 📈 回测结果(年化收益、回撤、夏普等)
├── logs/
└── docs/
└── changelog.md ← 📝 策略修改记录- 将完整 Markdown 写入
STRATEGY_DESIGN.md
- 必须真实落盘到策略目录 - 不得以“对话摘要”“屏幕展示”“口头确认”替代文件写入
- 对刚写入的文件运行质量检查
python3 scripts/quality_check.py [策略输出目录]/STRATEGY_DESIGN.md- 根据检查结果决定下一步
- 退出码 0(通过)→ 返回文件路径,再展示摘要给用户确认 - 退出码 1(未通过)→ AI 读取 quality_report.json,修复 STRATEGY_DESIGN.md 后重新检查 - 退出码 127(命令未找到)→ 跳过质量检查,但仍必须确保文件已写入磁盘并等待用户确认 - 其他异常退出码 → 视为未通过,检查错误信息并修复
阶段切换约束:
- Phase 1 在展示策略设计摘要后,必须停止并等待用户明确回复
- 未收到用户明确的「确认 / OK / 继续生成代码 / 进入 Phase 2」之前,不得开始生成
strategy.py、config.yaml、README.md、requirements.txt或任何 Phase 2 文件 - 不得因为
STRATEGY_DESIGN.md已成功写入并通过质量检查,就默认用户已同意进入 Phase 2 - 如果用户尚未回复,只能停留在“等待确认设计文档”的状态,不得自行继续后续步骤
失败约束:
- 如果策略目录未成功创建,不得宣称“设计文档已生成”
- 如果
STRATEGY_DESIGN.md未成功写入,不得宣称“设计文档已生成” - 如果质量检查未通过,不得进入 Phase 2
- 发生失败时,只能明确说明失败原因、失败步骤和当前文件路径状态
测试要求:
- Skill 测试通过标准之一:工作区中实际存在
STRATEGY_DESIGN.md - 仅当文件真实存在且可被
quality_check.py成功读取时,才算完成本步骤
⏸ 检查点:用户确认策略设计
仅在 STRATEGY_DESIGN.md 已真实写入、通过质量检查并返回文件路径后,才展示其核心摘要表格给用户:
这是 Phase 1 的强制停止点:展示摘要后必须等待用户明确确认。 在用户回复前,不得自动进入 Phase 2,不得默认继续生成代码。
┌─────────────────────────────────────────────────┐
│ 策略设计摘要 │
├─────────────────────────────────────────────────┤
│ 策略名称: [名称] │
│ 策略类型: [类型] │
│ 适用市场: [市场] │
│ 数据周期: [周期] │
├─────────────────────────────────────────────────┤
│ 买入条件: [条件1] + [条件2] + ... │
│ 卖出条件: [条件1] / [条件2] / ... │
│ 止损规则: [止损方式] │
│ 仓位管理: [方法] │
├─────────────────────────────────────────────────┤
│ 信号条件总数: [N]个 │
│ 风控规则总数: [N]条 │
│ 已知局限: [列出关键局限] │
└─────────────────────────────────────────────────┘- 用户确认OK → 进入 Phase 2
- 用户要求修改 → 修改
STRATEGY_DESIGN.md、重新写回原文件并重新运行质量检查后再展示 - 用户觉得方向不对 → 回到 Step 1 重新分析
- 用户未明确回复 → 保持等待确认状态,不得继续
⛔ Phase 1 → Phase 2 闸门(Phase 1 完成清单)
这是 Phase 1 的最终闸门。进入 Phase 2 前,必须逐项确认以下清单(不可跳过、不可假设):
- ✅ 策略目录已创建,路径: ___________
- ✅
STRATEGY_DESIGN.md已写入磁盘(通过ls/cat验证,非假设) - ✅
quality_check.py已运行并通过(退出码 0),或脚本不存在时已跳过并确认文件存在 - ✅ 设计摘要已展示给用户
- ✅ 用户已明确回复「确认 / OK / 继续」
以上 5 项全部为 ✅ 时,才允许进入 Phase 2。 任何一项为 ❌ 或未确认时,必须停留在 Phase 1,不得生成任何代码。
Phase 2: 代码生成 + 回测验证
目标:将 STRATEGY_DESIGN.md 翻译为可执行代码,并验证回测结果。 核心规则:AI 生成代码时必须先读取 STRATEGY_DESIGN.md,按文档逐条翻译,不可自由发挥。 注意:策略目录与STRATEGY_DESIGN.md必须已在 Phase 1 Step 4B 创建完成;Phase 2 只读取既有目录并继续生成代码,不重复创建或改写目录规范。 进入条件:只有在用户明确确认STRATEGY_DESIGN.md后,才能进入本阶段。
前置检查(硬性要求):Phase 2 开始前,必须逐项确认:
STRATEGY_DESIGN.md文件存在于策略目录中(通过ls或cat验证文件存在且非空,不可假设)- 数据源已就绪 如果 Phase 1 选择了跳过安装,此时必须先运行:
python3 scripts/env_setup.py --install [市场类型]安装完成并验证数据可用后,才可继续。
# Step 1: 读取已存在的策略目录结构(该结构已在 Phase 1 创建;以下内容与 Step 4B 完全一致)
~/策略研究/[策略名称]/
├── STRATEGY_DESIGN.md ← 📋 策略设计文档(核心!所有逻辑先写在这里)
├── README.md ← 📖 策略简介(从 DESIGN 自动生成)
├── strategy.py ← 💻 策略代码(从 DESIGN 严格翻译,不是自由发挥)
├── config.yaml ← ⚙️ 参数配置(所有可调参数都在这里,改参数不用改代码)
├── requirements.txt ← 📦 Python 依赖包列表
├── data/
│ ├── fetch_data.py ← 🔌 数据获取脚本(从 FTShare/FutuAPI 拉取行情数据)
│ ├── [标的代码].csv ← 📊 获取到的历史K线数据(自动生成)
│ └── .gitkeep
├── backtest/
│ ├── run_backtest.py ← 🏃 回测执行脚本(调用 strategy.py + 计算 score)
│ └── results/ ← 📁 回测结果输出目录
│ └── backtest_result.json ← 📈 回测结果(年化收益、回撤、夏普等)
├── logs/
└── docs/
└── changelog.md ← 📝 策略修改记录
# Step 2: 读 STRATEGY_DESIGN.md → 严格翻译生成 strategy.py
- 每个指标按「数学公式」翻译为函数
- 每个信号条件按「决策树」翻译为 if/else
- 仓位管理按公式翻译
- 风控规则作为硬约束嵌入
- ❌ 不可引入未在DESIGN中定义的指标
- ❌ 不可简化或"创造性发挥"任何逻辑
- ⚠️ 必须按下方「strategy.py 接口规范」输出,否则 run_backtest.py 无法读取结果
**strategy.py 接口规范**(AI 生成时必须遵守):
strategy.py 必须暴露以下两种接口之一,run_backtest.py 才能调用:
=== 方式一(推荐):run_backtest() 函数 ===
def run_backtest(config: dict) -> dict: """ 输入: config.yaml 的内容(dict) 输出: 回测结果字典(必须包含以下字段) """ return { # ── 必填字段(run_backtest.py 和 score_strategy() 依赖) ── "annual_return": 12.5, # 年化收益率(%) "max_drawdown": 8.3, # 最大回撤(%) "sharpe": 1.5, # 夏普比率 "win_rate": 52.0, # 胜率(%) "profit_loss_ratio": 2.1, # 盈亏比 "total_trades": 156, # 总交易次数
# ── 可选字段(用于诊断,缺失时诊断项标记为"无法检测") ── "period_returns": [3.2, -1.5, 5.1, ...], # 各期收益率列表 "first_half_return": 15.2, # 前半段收益率(%) "second_half_return": 9.8, # 后半段收益率(%) "universe_size": 500, # 股票池总数 "survivor_count": 480, # 现存股票数(用于幸存者偏差检测) "future_leak_detected": False, # 是否检测到未来函数 "avg_daily_volume": 50000000, # 标的日均成交量 "avg_trade_value": 2000000, # 平均每笔交易金额
# ── 可视化字段(启用 --plot 时需要,缺失时跳过图表) ── "daily_values": [ # 每日净值列表 {"date": "2020-01-02", "value": 1002000}, {"date": "2020-01-03", "value": 1005000}, ... ], "initial_cash": 1000000, # 初始资金(用于归一化净值) }
=== 方式二(备选):Backtrader Strategy class ===
如果用 Backtrader 标准模式,暴露 class Strategy(bt.Strategy) 即可。
run_backtest.py 会自动加载并运行,基础指标(年化/回撤/夏普/胜率/盈亏比)可正常获取,
但诊断字段(period_returns等)不可用。推荐用方式一。
- README 从 DESIGN 自动生成,不单独维护
- 使用下方「README.md 模板」
# Step 3: 从 STRATEGY_DESIGN.md 提取参数生成 config.yaml
- 所有可调参数写入 config.yaml
- 代码中不硬编码参数值
- ⚠️ 必须按下方「config.yaml 字段规范」生成,否则 run_backtest.py 和 strategy.py 读不到参数
**config.yaml 字段规范**(AI 生成时必须遵守):
=== 回测参数(run_backtest.py 直接读取) ===
initial_cash: 1000000 # 初始资金(元) start_date: "2020-01-01" # 回测开始日期 end_date: "2025-12-31" # 回测结束日期 benchmark: "000300.SH" # 基准指数代码(按市场自动填入,见下方规则)
=== 交易成本(run_backtest.py 直接读取) ===
commission: 0.0003 # 佣金费率(买卖各收) stamp_tax: 0.001 # 印花税率(仅卖出时收,港股/美股填 0) slippage: 0.001 # 滑点(比例或固定值)
=== 策略参数(strategy.py 读取,字段名由策略决定) ===
indicators: ma_fast: 5 # 示例:快线周期 ma_slow: 20 # 示例:慢线周期 rsi_period: 14 # 示例:RSI 周期 rsi_oversold: 30 # 示例:超卖阈值 rsi_overbought: 70 # 示例:超买阈值
=== 风控参数(strategy.py 读取) ===
risk: stop_loss_pct: 5 # 单笔止损 % take_profit_pct: 15 # 单笔止盈 % max_position_pct: 20 # 单只仓位上限 % total_position_pct: 80 # 总仓位上限 % max_drawdown_pct: 15 # 最大回撤容忍 %
=== 数据源配置(strategy.py 和 fetch_data.py 读取) ===
data_source: "ftshare" # 按检测结果动态填入(见下方规则) symbol: "000300.SH" # 标的代码 data_cycle: "daily" # daily / minute / tick market: "A股" # 目标市场(新增字段,用于选择基准和规则)
**字段动态选择规则**:
| 字段 | 选择逻辑 |
| --- | --- |
| `data_source` | Step 2 检测到 ftshare-all-in-one → `"ftshare"`;检测到 futuapi → `"futuapi"`;都没有 → `"akshare"` |
| `benchmark` | A股 → `"000300.SH"`(沪深300);港股 → `"HSI"`(恒生指数);美股 → `"^GSPC"`(标普500) |
| `stamp_tax` | A股 → `0.001`;港股/美股 → `0` |
| `commission` | 见 Step 4A 市场默认值表 |
| `market` | 从 Step 1 确定的市场类型填入 |
**字段命名规则**:
- 固定字段(回测参数、交易成本)必须使用上述字段名,不可改名
- 策略参数字段名可自定义,但建议用有意义的英文命名
- 风控参数放在 `risk:` 下,指标参数放在 `indicators:` 下
# Step 4: 生成数据获取脚本 + requirements.txt
- 根据 Step 2 选定的数据源生成 fetch_data.py
- 列出所有 Python 依赖
# Step 5: 自动回测
- 运行 scripts/run_backtest.py 执行回测
- AI 生成的 strategy.py 需暴露 run_backtest(config) 函数或 Strategy class
- 脚本自动完成:读取 config.yaml → 加载数据 → 执行回测 → 计算指标 → 运行诊断 → 输出报告
- 输出 backtest/results/backtest_result.json 供 AI 读取
- Phase 3 优化循环中,子 Agent 也通过此脚本独立执行回测
# Train/Test Split(推荐用于 Phase 3 优化验证):
- 默认模式:python3 scripts/run_backtest.py ~/策略研究/[策略名]/
- Split 模式:python3 scripts/run_backtest.py ~/策略研究/[策略名]/ --split 0.7 → 前 70% 时间段为训练集,后 30% 为测试集 → 自动计算样本外衰减率(测试集收益 / 训练集收益) → 衰减率 < 30% = ❌ 严重过拟合,30%-60% = ⚠️ 有风险,> 60% = ✅ 稳定
- Phase 3 优化建议:最终策略用 --split 0.7 验证样本外表现
# 异常处理(按优先级排查):
| 异常场景 | 排查动作 | Fallback |
| --- | --- | --- |
| Python包缺失(ModuleNotFoundError) | 读取 requirements.txt → pip install -r | 提示用户手动安装缺失包 |
| 数据获取失败(网络/API限流) | 检查网络连接 → 重试1次 → 切换备用数据源 | 暂停回测,告知用户数据不可用 |
| config.yaml字段缺失/格式错误 | 读取报错信息 → 对照config.yaml字段规范修复 | 用默认值填充缺失字段并警告 |
| strategy.py接口不匹配 | 对照接口规范检查返回字段 | 提示具体缺失字段,等待AI修复后重跑 |
| 回测脚本自身报错 | 读取完整traceback → 定位问题行 | 降级为手动回测模式,输出诊断建议 |
| 内存不足(大数据集) | 减少回测区间或标的数量 | 提示用户缩小回测范围 |
规则:遇到异常时,先尝试自动修复(最多1次),修复失败再告知用户。不静默跳过任何异常。
# Step 6: 回测诊断(脚本自动检测以下5项)
1. 过拟合:参数微调后收益大幅变化?
2. 幸存者偏差:是否只用了现存股票?
3. 未来函数:是否用了未来数据?
4. 流动性:能否在实际市场执行?
5. 稳定性:不同时间段表现是否一致?
⏸ 检查点:用户确认回测结果
展示回测结果摘要:
┌─────────────────────────────────────────────────┐ │ 回测结果 │ ├─────────────────────────────────────────────────┤ │ 回测区间: [开始] ~ [结束] │ │ 年化收益率: [X]% (及格线: >无风险利率×2) │ │ 最大回撤: [X]% (及格线: <20%) │ │ 夏普比率: [X] (及格线: >1.0) │ │ 胜率: [X]% (及格线: >45%) │ │ 盈亏比: [X] (及格线: >1.5) │ ├─────────────────────────────────────────────────┤ │ 诊断结果: │ │ [✅/⚠️/❌] 过拟合检测 │ │ [✅/⚠️/❌] 幸存者偏差 │ │ [✅/⚠️/❌] 未来函数检测 │ │ [✅/⚠️/❌] 流动性检测 │ │ [✅/⚠️/❌] 稳定性检测 │ ├─────────────────────────────────────────────────┤ │ score_strategy(): [X]/100 │ └─────────────────────────────────────────────────┘
回测通过标准:
| 指标 | 及格线 | 优秀线 | 不通过处理 |
|---|---|---|---|
| 年化收益率 | > 基准指数年均收益 × 2 | > 基准指数 + 10% | 分析低收益原因 |
| 最大回撤 | < 20% | < 10% | 优化止损逻辑 |
| 夏普比率 | > 1.0 | > 2.0 | 降低波动或提高收益 |
| 胜率 | > 45% | > 55% | 调整买卖条件 |
| 盈亏比 | > 1.5 | > 2.5 | 优化止盈止损 |
| 样本外表现 | > 样本内的 60% | > 样本内的 80% | 过拟合警告(使用 --split 0.7 启用) |
- 回测达标 → 策略完成,输出文件路径
- 回测不达标但用户想继续 → 进入 Phase 3 自动优化
- 用户不满意方向 → 回到 Phase 1 重新设计
Phase 3: 优化
触发条件:Phase 2 回测不达标 / 用户说「优化这个策略」 核心思路:结构化诊断 → 候选方案库选方案 → 改DESIGN → 独立回测 → 棘轮决策 支持两种模式:Agent 自主优化(推荐)和 交互式优化
进入 Phase 3 时,主动向用户展示模式选择(不需要用户说特定关键词):
┌─────────────────────────────────────────────────┐ │ 策略回测未达标,进入优化阶段。请选择优化方式: │ │ │ │ A. Agent 自主优化(推荐) │ │ → 系统自主跑最多 5 轮优化,5-15 分钟后出报告 │ │ → 期间你可以做其他事 │ │ │ │ B. 交互式优化 │ │ → 每轮优化都由你确认后再继续 │ │ → 适合想深入参与优化过程的场景 │ └─────────────────────────────────────────────────┘
用户选择 A → 模式 A: Agent 自主优化 用户选择 B → 模式 B: 交互式优化
全局参数(两种模式共用):
MAX_ROUNDS = 5 # 每个策略最多优化5轮 MIN_IMPROVEMENT = 1.0 # 分数提升必须 > 1分才算有效改进 MAX_CONSECUTIVE_FAIL = 2 # 连续N轮无有效改进时触发探索性重做
模式 A: Agent 自主优化
Agent 自主完成全部优化循环,人只在最后看报告做一次决策。
# Step A1: 准备上下文
收集以下信息,准备传递给 agent:
- workspace: 策略工作区目录的绝对路径
- market: 目标市场(A股/港股/美股),从 config.yaml 读取
- baseline_score: 初始回测分数(从 backtest/results/backtest_result.json 的 score 字段读取)
- scripts_dir: autostrategy scripts 目录的绝对路径
注意:git 初始化由 Agent 在 Round 0 自动完成,此处不需要手动 git init。
# Step A2: 启动自主优化 Agent
使用 Agent tool 启动一个 sub-agent:
Agent 配置:
- prompt: 读取本 skill 目录下 prompts/optimization_agent.md 的完整内容 在 prompt 末尾追加实际参数: """ ## 实际参数 - workspace: {workspace_path} - market: {market} - baseline_score: {score} - scripts_dir: {scripts_path} """
- model: sonnet(优化循环不需要 opus,控制成本)
- 预计运行 5-15 分钟(5轮 × 每轮回测 + 评分 + 决策)
Agent 将自主完成:基线快照 → 5轮诊断/修改/回测/评分/棘轮决策 → 输出结构化报告
# Step A3: 呈现优化报告
Agent 返回后,将优化报告直接呈现给用户。 报告包含:基线分→最终分、各轮详情、保留的关键改动、建议。
# Step A4: 用户最终决策
根据报告中的建议,给出选项: A. 接受当前结果 — 策略优化完成 B. 探索性重做 — 换策略方向(如趋势跟踪→均值回归) C. 换标的 — 换交易标的(如沪深300→科创50) D. 回到 Phase 1 — 策略设计有根本问题,重新开始
if 用户选择 B/C: → 回到 Phase 1 Step 3(跳过 Step 1/2 因为已有策略方向) → 重新走 Step 4A → Step 4B → Phase 1 闸门确认 → Phase 2 不得直接重写 STRATEGY_DESIGN.md 跳过 Phase 1 完整流程 elif 用户选择 D: 回到 Phase 1 Step 1 else: 策略完成,输出文件路径
模式 B: 交互式优化
每轮优化都由用户确认后再继续,适合想深入参与优化过程的场景。
# Step 1: 基线快照
├─ git init(如未初始化)+ git add -A + git commit -m "baseline: score {X}" ├─ 跑基线回测,记录 score_strategy() 分数 └─ 初始化优化审计日志(追加到 docs/changelog.md)
# Step 2: 结构化诊断 + 候选方案选择
# 2.1 计算各维度失分值
失分 = 满分 - 实际得分(按 score_strategy 的5个维度) 最弱维度 = 失分最大的维度
# 2.2 从候选方案库选择(避免重复,避免盲猜)
已尝试 = [] # 从 changelog 读取历史记录
候选方案库(每轮从未尝试的方案中选一个):
┌─ 收益率低 ─────────────────────────────────┐ │ A. 调整买卖阈值(如 RSI 超卖 20→25) │ │ B. 增加趋势强度过滤(如 ATR > 均值) │ │ C. 优化仓位管理(如分批建仓) │ └────────────────────────────────────────────┘
┌─ 最大回撤大 ───────────────────────────────┐ │ A. 增加回撤保护(组合级回撤清仓+暂停) │ │ B. 减少单笔仓位(如 20%→10%) │ │ C. 增加极端行情过滤(波动率异常时不开仓) │ └────────────────────────────────────────────┘
┌─ 夏普比率低 ───────────────────────────────┐ │ A. 增加信号过滤条件(减少低质量交易) │ │ B. 优化止盈止损比(让利润跑更久) │ │ C. 增加波动率过滤(低波动期不开仓) │ └────────────────────────────────────────────┘
┌─ 胜率低 ───────────────────────────────────┐ │ A. 收紧买入条件(增加确认指标) │ │ B. 放宽卖出条件(给反弹更多空间) │ │ C. 增加趋势过滤(只在明确趋势中交易) │ └────────────────────────────────────────────┘
┌─ 盈亏比低 ───────────────────────────────┐ │ A. 提高止盈目标(如 RSI 50→65) │ │ B. 收紧止损(减少单笔亏损幅度) │ │ C. 增加移动止盈(从高点回落N%时平仓) │ └────────────────────────────────────────────┘
if 候选方案 in 已尝试: 选择该维度的下一个未尝试方案
# Step 3: 修改 STRATEGY_DESIGN.md
- 只改DESIGN,不改代码
- 每轮只改一个维度(避免无法归因)
- 记录:目标维度、候选方案编号、具体改动内容
# Step 4: 读更新后的 STRATEGY_DESIGN.md → 重新生成 strategy.py
- 完整重新生成,不做增量修改
- 代码必须严格翻译DESIGN,不可自由发挥
# Step 5: 子Agent独立回测(关键!防自己改自己评)
- 主Agent:修改DESIGN + 生成代码
- 子Agent:运行 scripts/run_backtest.py,独立计算分数
- 评估独立性:子Agent只读 backtest_result.json,不知道改了什么
# Step 6: 棘轮决策
if new_score > old_score + MIN_IMPROVEMENT: # 有效改进:保留 git commit -m "R{N}: {维度} {方案} score {old}→{new} keep" 追加到 changelog.md elif new_score > old_score: # 微小改进(<1分):保留但记录 git commit -m "R{N}: {维度} {方案} score {old}→{new} keep(marginal)" 追加到 changelog.md else: # 无改进或恶化:回滚 git checkout -- STRATEGY_DESIGN.md strategy.py config.yaml 追加到 changelog.md(状态=revert) 记录失败原因
# 额外检查:简洁性
if 条件数增加 > 2 且 分数提升 < 5: 回滚(复杂度增加不值得)
# Step 7: 循环判断 + 探索性重做
if 轮次 >= MAX_ROUNDS 或 连续失败 >= MAX_CONSECUTIVE_FAIL: 输出优化报告:
┌─────────────────────────────────────────────────┐ │ Phase 3 优化报告 │ ├─────────────────────────────────────────────────┤ │ 基线分数: {baseline_score}/100 │ │ 最佳分数: {best_score}/100 │ │ 优化轮次: {total_rounds}轮 │ │ 保留改动: {kept_count}轮 │ │ 回滚改动: {reverted_count}轮 │ ├─────────────────────────────────────────────────┤ │ 各轮记录(详见 docs/changelog.md) │ │ 建议: [探索性重做 / 换标的 / 接受当前结果] │ └─────────────────────────────────────────────────┘
# 向用户提议探索性重做(必须征得用户同意) 选项: A. 换策略方向(如趋势跟踪→均值回归) B. 换标的(如沪深300→科创50) C. 增加策略复杂度(加多因子) D. 停止优化,接受当前结果
if 用户选择 A/B/C: → 回到 Phase 1 Step 3(跳过 Step 1/2 因为已有策略方向) → 重新走 Step 4A → Step 4B → Phase 1 闸门确认 → Phase 2 不得直接重写 STRATEGY_DESIGN.md 跳过 Phase 1 完整流程 else: 优化结束
else: 回到 Step 2,继续下一轮
优化审计日志(每轮自动追加到 docs/changelog.md):
## 优化历史
| 轮次 | 目标维度 | 候选方案 | 改动内容 | 基线分 | 新分数 | 状态 | 备注 |
|------|---------|---------|---------|--------|--------|------|------|
| R1 | 盈亏比 | A.提高止盈 | RSI止盈 50→70 | 0.0 | 0.0 | revert | 回撤恶化 |
| R2 | 盈亏比 | B.收紧止损 | 止损 5%→3% | 0.0 | 0.0 | revert | 盈亏比下降 |STRATEGY_DESIGN.md 模板
这是整个设计的核心创新点:将「策略意图」和「代码实现」之间插入一层机器可读的精确设计文档。 AI 生成 strategy.py 时,必须先读取此文档,按文档中的规则逐条翻译为代码。 类比 autoresearch:STRATEGY_DESIGN.md 就像 program.md,strategy.py 就像 train.py。
生成策略时,将以下模板填充为实际的 STRATEGY_DESIGN.md 文件:
# [策略名称] — 策略设计文档
> 本文档是策略的精确设计规格,供 AI 生成代码时读取。
> 所有规则必须被严格翻译为代码,不可遗漏、不可简化、不可"创造性发挥"。
## 0. 项目文件说明
> 策略由以下文件组成,每个文件各司其职:策略目录/ ├── STRATEGY_DESIGN.md ← 📋 你正在看的这个文件(策略的施工图纸) ├── README.md ← 📖 策略简介(看一眼就知道这策略做什么) ├── strategy.py ← 💻 策略代码(根据本文件自动生成,不要手动改) ├── config.yaml ← ⚙️ 参数配置(想调参数?改这里,不用动代码) ├── requirements.txt ← 📦 需要安装的 Python 包 ├── data/ │ ├── fetch_data.py ← 🔌 获取行情数据的脚本 │ └── *.csv ← 📊 下载好的历史K线数据 └── backtest/ └── results/ └── *.json ← 📈 回测结果(自动生成)
**新手提示**:
- 想了解策略逻辑 → 看 `STRATEGY_DESIGN.md`(本文件)
- 想调整参数(如止损比例、仓位大小)→ 改 `config.yaml`
- 想看回测赚了多少钱 → 看 `backtest/results/` 下的 JSON 文件
- `strategy.py` 是自动生成的,一般不需要手动修改
## 1. 策略元信息
| 字段 | 值 |
|------|---|
| 策略名称 | [名称] |
| 策略类型 | [趋势跟踪 / 均值回归 / 多因子 / 统计套利 / 网格 / 事件驱动] |
| 适用市场 | [A股 / 港股 / 美股] |
| 适用品种 | [具体股票池] |
| 数据周期 | [Tick / 分钟线 / 日线 / 周线] |
## 2. 指标定义
> 每个指标必须包含:数学公式、参数默认值、参数合理范围、计算前提条件。
### 指标 1: [指标名称]
- **用途**:[此指标在策略中的作用]
- **数学公式**:[精确公式,如 SMA(CLOSE, N) = sum(CLOSE[i-N+1:i+1]) / N]
- **参数**:[参数名]:默认值 [X],合理范围 [A, B]
- **计算前提**:[需要多少根K线才开始有效]
- **输出值域**:[如 [0, 100]]
## 3. 信号逻辑
> 必须以**决策树**形式精确描述,不允许使用模糊表述。
### 3.1 买入信号(BUY)
**触发条件**(所有条件必须同时满足):
条件1: [指标A] [运算符] [阈值] 例: RSI(14) < 30
条件2: [指标B] [运算符] [指标C] 例: MA(5) > MA(20)
条件3: [过滤条件] 例: 成交量 > MA(成交量, 20) * 1.5
附加约束:
- 持仓为0时才触发
- 不在涨跌停板时触发
- A股: 买入当日不可卖出(T+1规则)
### 3.2 卖出信号(SELL)
**触发条件**(满足任一即触发):
条件1: [止损/止盈条件]
条件2: [反向信号条件]
条件3: [时间止损:持有超过N根K线且收益 < X%]
### 3.3 信号优先级
1. 止损信号 > 其他卖出信号(保命优先)
2. 买入 vs 卖出冲突时:先执行卖出,清仓后再判断买入
3. 同一K线内只允许一次交易动作
## 4. 仓位管理
方法: [固定金额 / 固定比例 / 凯利公式 / ATR动态]
买入金额 = 总可用资金 * [仓位比例,默认20%]
买入数量 = floor(买入金额 / 当前价格 / 取整单位) * 取整单位 # A股=100股,港股/美股=不取整
约束:
- 单只标的仓位上限: 总资金的 [默认20%]
- 总仓位上限: 总资金的 [默认80%]
## 5. 风控规则
> 风控规则是硬约束,任何一条触发都必须执行。
> 默认值已在 Step 4A 中预填,用户可在此基础上修改。
| 规则 | 默认阈值 | 触发动作 |
|------|---------|---------|
| 单笔最大仓位 | 总资金的 20% | 限制买入数量 |
| 单笔最大亏损 | 买入金额的 5% | 触发止损卖出 |
| 总仓位上限 | 总资金的 80% | 不再开新仓 |
| 最大回撤容忍 | 15% | 全部清仓,暂停交易 5 日 |
| 连续亏损次数 | 3 次 | 降低仓位至 50% |
| 极端行情 | 指数单日跌幅 > 7% | 暂停所有交易 |
## 6. 回测参数
> 默认值已在 Step 4A 中按市场类型预填,用户一次性确认。
| 参数 | 默认值 | 说明 |
|------|--------|------|
| 初始资金 | 1,000,000 元 | 回测起始资金 |
| 手续费率 | 见 Step 4A 市场默认值表 | 买卖各收 |
| 印花税率 | 见 Step 4A 市场默认值表 | 卖出时收取 |
| 滑点 | 见 Step 4A 市场默认值表 | 买入价+滑点,卖出价-滑点 |
| 回测区间 | 2020-01-01 ~ 2025-12-31 | 至少覆盖一个牛熊周期 |
## 7. 禁止事项
> AI 生成代码时**绝对不可**执行以下操作:
1. ❌ 不可使用未来数据(如用当天收盘价做当天交易决策)
2. ❌ 不可忽略手续费和滑点
3. ❌ 不可在信号中引入未在本文档定义的指标
4. ❌ 不可修改信号优先级规则
5. ❌ 不可将风控阈值设为比本文档更宽松的值
## 8. 已知局限
- [局限1,如"在震荡市中可能频繁止损"]
- [局限2,如"对小盘股流动性假设可能过于理想"]README.md 模板
README.md 从 STRATEGY_DESIGN.md 自动摘要生成,不单独维护。
# [策略名称]
> 一句话描述策略核心逻辑
## 策略概述
- **策略类型**:[趋势跟踪 / 均值回归 / 多因子 / 统计套利 / ...]
- **适用市场**:[A股 / 港股 / 美股]
- **适用周期**:[Tick / 分钟线 / 日线 / 周线 / ...]
- **资金要求**:[最低资金量]
## 核心逻辑
[用3-5句话讲清楚策略的买卖逻辑,让不懂代码的人也能理解]
## 买卖规则
| 条件 | 动作 | 说明 |
|------|------|------|
| [买入条件1] | 买入 | [触发理由] |
| [卖出条件1] | 卖出 | [触发理由] |
| [止损条件] | 卖出 | [风控规则] |
## 关键参数
| 参数 | 默认值 | 含义 | 调参建议 |
|------|--------|------|---------|
| [参数名] | [值] | [说明] | [调整范围] |
## 回测结果摘要
- **回测区间**:[开始日期] ~ [结束日期]
- **年化收益率**:[X]%
- **最大回撤**:[X]%
- **夏普比率**:[X]
- **胜率**:[X]%
## 风险提示
- [策略局限1]
- [不适用场景]策略评分函数 score_strategy()
权威实现见 scripts/run_backtest.py,此处伪代码仅供参考。 将回测结果 + 复杂度映射为 0-100 分。这是 Phase 3 棘轮决策的唯一依据。# 市场基准指数默认值(与 config.yaml benchmark 字段对应)
MARKET_BENCHMARKS = {
"A股": {"index": "000300.SH", "avg_annual_return": 8.0}, # 沪深300 近10年均值
"港股": {"index": "HSI", "avg_annual_return": 5.0}, # 恒生指数 近10年均值
"美股": {"index": "^GSPC", "avg_annual_return": 10.0}, # 标普500 近10年均值
}
def _resolve_baseline_return(market: str, config: dict = None) -> float:
"""解析基准收益率。支持"多市场"——按标的数量加权平均。"""
if market in MARKET_BENCHMARKS:
return MARKET_BENCHMARKS[market]["avg_annual_return"]
# 多市场:按 symbols 中各标的的实际市场加权
if config and "symbols" in config:
market_counts = {}
for sym in config["symbols"]:
m = sym.get("market", "A股")
market_counts[m] = market_counts.get(m, 0) + 1
total = sum(market_counts.values())
weighted = sum(
MARKET_BENCHMARKS.get(m, MARKET_BENCHMARKS["A股"])["avg_annual_return"] * cnt
for m, cnt in market_counts.items()
) / total
return weighted
return MARKET_BENCHMARKS["A股"]["avg_annual_return"]
def score_strategy(backtest_result: dict, design_doc: dict, market: str = "A股",
config: dict = None) -> float:
"""将回测结果 + 复杂度 映射为0-100分
设计原则(借鉴 autoresearch 简洁性准则):
- 分数提升必须大于复杂度增加 × 惩罚系数
- 删条件效果不变 = 大胜利
- 加条件只提升0.001 = 不值得
"""
baseline_return = _resolve_baseline_return(market, config)
score = 0
# 收益率(满分25,超越基准2倍=满分)
score += min(backtest_result['annual_return'] / (baseline_return * 2), 1.0) * 25
# 回撤控制(满分20,回撤<10%=满分)
score += max(1 - backtest_result['max_drawdown'] / 30, 0) * 20
# 风险调整收益(满分25,夏普>2.0=满分)
score += min(backtest_result['sharpe'] / 2.0, 1.0) * 25
# 胜率(满分15,>60%=满分)
score += min(backtest_result['win_rate'] / 60.0, 1.0) * 15
# 盈亏比(满分15,>2.5=满分)
score += min(backtest_result['profit_loss_ratio'] / 2.5, 1.0) * 15
# ★ 简洁性惩罚(借鉴 autoresearch)
# 条件数 = 买入条件 + 卖出条件 + 过滤条件 + 风控条件
condition_count = design_doc['num_buy_conditions'] + \
design_doc['num_sell_conditions'] + \
design_doc['num_filters'] + \
design_doc['num_risk_rules']
# 超过10个条件开始惩罚,每个额外条件扣1.5分
complexity_penalty = max(0, (condition_count - 10) * 1.5)
return max(0, score - complexity_penalty)简洁性准则
借鉴 autoresearch 的核心设计规则,直接嵌入优化决策。
| 场景 | 判断 | 处理 |
|---|---|---|
| 加了2个过滤条件,score提升0.5分 | 复杂度增加不值得 | 回滚 |
| 删了1个过滤条件,score不变 | 简化胜利 | 保留 |
| 加了1个过滤条件,score提升5分 | 值得 | 保留 |
| 条件总数超过10个 | 过度复杂 | 惩罚扣分 |
这条规则直接嵌入 score_strategy() 的复杂度惩罚项中,不需要人工判断。
策略类型参考
| 类型 | 触发示例 | 数据需求 | 回测复杂度 |
|---|---|---|---|
| 趋势跟踪 | 「均线交叉」「突破策略」 | 日线K线 | 低 |
| 均值回归 | 「超跌反弹」「RSI策略」 | 日线K线 + 技术指标 | 低 |
| 多因子选股 | 「财务因子」「价值投资」 | 基本面数据 + K线 | 中 |
| 统计套利 | 「配对交易」「协整」 | 多只股票K线 | 高 |
| 事件驱动 | 「财报后走势」「公告策略」 | 新闻/公告数据 | 高 |
| 网格交易 | 「定投网格」「震荡网格」 | 分钟线/K线 | 低 |
| T0策略 | 「日内回转」「底仓增强」 | 分钟线/Tick数据 | 高 |
在 Phase 1 确认策略类型后,根据类型自动选择对应的数据维度和回测引擎。
品种类型与模板对应关系:
| 品种类型 | STRATEGY_DESIGN.md 模板 | 状态 |
|---|---|---|
| 股票(A股/港股/美股) | 本文档内嵌模板(默认) | ✅ 可用 |
Skill 协作关系
Autostrategy 不重复造轮子,调度已有的 Skill。
| 已有 Skill | 协作方式 | 调用场景 |
|---|---|---|
| futuapi | 数据获取 + 模拟交易(股票) | 港美股策略 |
| ftshare-all-in-one | A股全品类数据获取(非凸科技 FTShare 免费数据) | A股策略(Phase 1 首选推荐)安装: npx skills add zhangchao0911/all-in-one --yes |
| securities-app-radar | 竞品/行业动态扫描 | 策略背景分析 |
| install-futu-opend | 环境安装 | 用户选择 futuapi 但未安装时 |
调用方式:Phase 1 环境检测时,主动扫描 .claude/skills/ 目录,仅将确认已安装的 Skill 告知 agent。
约束规则
- 不改变策略的核心逻辑方向 — 优化只调整参数和条件,不改变策略类型
- 每次只改一个变量 — 避免多个变更导致无法归因
- git 版本控制 — 所有改动在分支上,可随时回滚
- 评估独立性 — 效果评估必须用独立子Agent,避免「自己改自己评」
- MAX_ROUNDS 限制 — 连续2轮无提升时停止,防止无效循环
- 不推实盘 — 所有策略仅供学习研究,不推荐实盘交易
- 免费优先 — 只推荐免费数据源,不引导用户付费购买数据
禁止事项
- ❌ 不可使用未来数据(如用当天收盘价做当天交易决策)
- ❌ 不可忽略手续费、滑点、印花税
- ❌ 不可在信号中引入未在 STRATEGY_DESIGN.md 中定义的指标
- ❌ 不可将风控阈值设为比 STRATEGY_DESIGN.md 更宽松的值
- ❌ 不可在 Phase 3 优化中修改策略类型(如把趋势跟踪改成均值回归)
- ❌ 不可推荐实盘交易或提供投资建议
- ❌ 不可引导用户购买付费数据服务
进化日志
每次优化记录写入策略目录的 docs/changelog.md:
## 优化历史
| 日期 | 版本 | 触发原因 | 改动内容 | 基线分 | 优化分 | 状态 |
|------|------|---------|---------|--------|--------|------|
| 2026-04-18 | v1.1 | 夏普比率<1.0 | 增加RSI过滤条件 | 52 | 68 | keep |
| 2026-04-18 | v1.2 | 胜率<45% | 调整止盈比例 | 68 | 71 | keep |
| 2026-04-18 | v1.3 | 收益率下降 | 增加成交量过滤 | 71 | 69 | revert |