选股策略演化研究系统

SKILL效率
效率 未标注权限 许可证不明确
安装这个技能

把公开研报或既有选股逻辑变成可运行、可审计、可迭代的 clean-room 研究系统。Use when an AI Agent must replicate, audit, backtest, evolve, or document a stock-selection strategy with data contracts, train/validation/test isolation, versioned experiments, no-future-function checks, portfolio constraints, and holdout review. Research only; never output stock tips or return promises.

一句话选型结论

按资料字段整理

选股策略演化研究系统是效率类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类效率 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_5fc3c48c/stock-selection-evolution-research-skill
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

效率
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_5fc3c48c仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791712416
正文体量74.2 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
整理待办与日程

把零散任务收进清单,排出优先级。

批量处理重复任务

把固定动作做成模板,重复执行。

把流程写成清单

把口头流程整理成可复用的步骤。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在效率场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
选股策略演化研究系统当前 未标注权限 未标注 未标注 未标注 有
Nano PDF 文档 联网访问 ClawHub 市场 424.9 万 OpenClaw 有
自动更新程序 浏览器控制 ClawHub 市场 296.4 万 OpenClaw 有
Gemini 助手 联网访问 ClawHub 市场 254.7 万 OpenClaw 有
word DOCX 文档 联网访问 ClawHub 市场 239.6 万 OpenClaw 有
Excel XLSX 前端 联网访问 ClawHub 市场 227.0 万 OpenClaw 有

SKILL.md 全文

74.2 KB
模型实际读到的说明书原文,来自技能仓库

选股策略自进化研究 Skill

0. 使用边界

本 Skill 用于学习研究、研报复刻、量化工作流搭建、回测审计和策略机制验证。它不是投资建议工具,不提供买卖指令,不推荐个股,不承诺收益,不保证未来表现。

必须在所有对外输出、报告、图文和结论中保留:

> 仅供学习研究,不构成投资建议。回测、样本声明和策略代码不代表未来收益,策略结果、数据来源和实盘风险需自行验证。

任何 Agent 使用本 Skill 时,必须遵守以下硬规则:

  1. 不把回测收益、Sharpe、胜率、回撤写成未来收益承诺。
  2. 不生成“买入、卖出、持有、止盈、止损、跟随策略”等交易建议。
  3. 不使用测试集结果筛选、调参、回写策略。
  4. 不在结果不完整时声称“完全复现”或“等同原研报代码”。
  5. 不隐藏数据缺口、字段代理、样本偏差、失败版本和过拟合信号。
  6. 不暴露 API token、账号、密钥、私密路径、非公开数据源凭证。

1. Skill 目标

把一个选股策略想法或一篇公开研报,转成一套可运行、可审计、可迭代的研究系统:

策略协议
  -> 数据契约
  -> 因子与组合配置
  -> 三段样本回测
  -> 候选版本演化
  -> 验证集保留
  -> 测试集人工复核
  -> 版本账本和研究报告

本 Skill 的重点不是“找到一个最好看的历史结果”,而是让 Agent 按研究纪律回答:

  • 原始策略逻辑是什么?
  • 哪些内容来自公开披露,哪些是本地 clean-room 近似?
  • 数据源覆盖是否足够?
  • 训练集、验证集、测试集是否隔离?
  • 每个版本到底改了什么?
  • 验证集改善是否带来测试集外推折损?
  • 结果是否可复跑、可回滚、可追溯?

2. 触发场景

当用户提出以下任一任务时,使用本 Skill:

  • “复刻某篇选股策略研报。”
  • “把这个选股逻辑做成 Skill。”
  • “让 AI 自动迭代选股策略。”
  • “检查这个回测是不是真的有效。”
  • “用训练集/验证集/测试集做策略演化。”
  • “根据 Tushare / AmazingData / 本地行情数据跑选股回测。”
  • “生成策略版本账本、测试集复核和研究报告。”
  • “把华泰选股自进化 Skill 的机制迁移到我的数据源。”

如果用户只想要市场观点、荐股、交易建议或收益承诺,不使用本 Skill;改为提示风险边界。

3. 默认研究对象

默认策略类型是“稳健低波价值优选”:

  • 股票池:A 股可交易股票或用户指定股票池。
  • 基础过滤:流动性、市值、上市时长、ROE、估值数据可用。
  • 价值基础池:盈利收益率相对盈利能力具有吸引力,避免只买低质量低估值。
  • 三组评分:leader、dividend_defense、growth_stability。
  • 组合构建:月度调仓,目标 30 只,缓冲 45 只,单票上限 5%,按下行波动倒数定权。
  • 迭代方式:只允许小步修改参数、权重、持仓数、缓冲池、单票上限、调仓频率和可解释因子组合。

可以迁移到其他策略,但必须保留:

  • 策略协议。
  • 数据契约。
  • 样本隔离。
  • 版本留痕。
  • 测试集只复核。

4. 默认样本切分

若用户没有指定样本区间,默认使用以下区间:

样本 区间 权限 作用
训练集 2014-12-31 至 2018-12-28 策略生成和初筛 建立基础逻辑,观察长期稳定性
验证集 2018-12-28 至 2020-12-31 版本保留判断 比较候选版本,决定是否保留
测试集 2020-12-31 至 2026-04-30 最终人工复核 只做外推风险检查,不参与自动选择

如果数据源不能覆盖默认区间:

  1. 先报告可用区间。
  2. 重新提出可执行的三段切分。
  3. 明确样本变更对可比性的影响。
  4. 不得继续沿用默认指标口径。

5. 数据契约

Agent 必须先检查数据是否满足最小契约,再写回测或调参代码。

5.1 行情数据 market

最小字段:

字段 含义 要求
trade_date 交易日 YYYY-MM-DD 或 YYYYMMDD,可排序
symbol 股票代码 唯一标识
open 开盘价 可选,但建议保留
high 最高价 可选
low 最低价 可选
close 收盘价 必需
pre_close 前收盘 可选
volume 成交量 可选
amount 成交额 流动性过滤需要
adj_factor 复权因子 若没有,必须说明收益计算口径

5.2 估值与交易基础数据 daily_basic

最小字段:

字段 含义 用途
trade_date 日期 对齐调仓日
symbol 股票代码 连接行情
pe_ttm 市盈率 TTM 计算盈利收益率
pb 市净率 估值/稳定性因子
total_mv 或 circ_mv 总市值/流通市值 市值过滤
turnover_rate 换手率 可选
dv_ttm 或 dividend_yield 股息率 股息防御因子,可代理

5.3 财务数据 financial

最小字段:

字段 含义 用途
ann_date 或 end_date 公告日/报告期 必须避免未来函数
symbol 股票代码 连接
roe ROE 价值残差锚点
roic ROIC leader 因子
revenue 或 or_yoy 收入规模/收入增速 leader 代理
debt_to_assets 资产负债率 质量过滤
netprofit_yoy 净利润增速 成长稳定因子
ocf_to_profit 经营现金流/利润 股息防御因子

5.4 股票元数据 stock_basic

最小字段:

字段 含义 用途
symbol 股票代码 连接
name 股票名称 ST 过滤
list_date 上市日期 上市时长过滤
industry 行业 行业内标准化/残差
exchange 交易所 可选

5.5 基准数据 benchmark

建议字段:

  • trade_date
  • close
  • return

如果没有基准,不得计算超额收益,只能计算绝对收益和风险指标。

6. 数据源适配

本 Skill 可使用任意数据源,包括 Tushare、AmazingData、本地 JSONL/CSV/Parquet、数据库、研究平台导出文件。

Agent 必须先完成字段映射表:

| 目标字段 | 数据源字段 | 覆盖区间 | 缺失率 | 是否代理 | 备注 |
|---|---|---:|---:|---|---|
| close | close | 2014-12-31~2026-04-30 | 0.1% | 否 | 后复权 |
| pe_ttm | pe_ttm | ... | ... | 否 | 用于 EP |
| roic | roic | ... | ... | 是/否 | 若代理需说明 |

若字段缺失:

  1. 判断是否可以用代理字段。
  2. 标注代理口径。
  3. 评估对结果的影响。
  4. 写入 known_gaps。

绝不能在缺字段时让 Agent 默默脑补。

7. 策略配置模板

Agent 应把策略参数写入配置,而不是散落在代码或对话中。

skill:
  name: stock_selection_evolution
  version: v0.0.0
  result_root: result/skills

data:
  market_snapshot: data/canonical/daily_bar.jsonl
  financial_snapshot: data/canonical/fina_indicator.jsonl
  daily_basic_snapshot: data/canonical/daily_basic.jsonl
  stock_basic_snapshot: data/canonical/stock_basic.jsonl
  feature_cache: data/canonical/feature_cache.jsonl
  benchmark_snapshot: data/canonical/benchmark.jsonl
  reference_claims: reference_claims.json

sample_splits:
  train:
    start: "2014-12-31"
    end: "2018-12-28"
    permission: strategy_generation_and_first_screening
  valid:
    start: "2018-12-28"
    end: "2020-12-31"
    permission: version_retention_decision
  test:
    start: "2020-12-31"
    end: "2026-04-30"
    permission: final_holdout_review_only

strategy:
  profile: stable_lowvol_value_selection
  hold_n: 30
  buffer_n: 45
  rebalance_days: 21
  cost_bps_per_side: 30
  min_history_days: 120
  min_listed_days: 250
  vol_lookback_days: 250
  adv_lookback_days: 20
  dividend_lookback_days: 504
  dividend_min_observations: 60
  min_adv_20d: 20000
  adv_quantile_floor: 0.40
  market_cap_quantile_floor: 0.35
  fallback_adv_quantile_floor: 0.20
  value_residual_keep_quantile: 0.33
  fallback_value_residual_keep_quantile: 0.50
  min_roe: 0.0
  max_pe_ttm: 40.0
  max_weight_per_stock: 0.05
  weighting: inverse_downside_volatility
  industry_grouping: true
  factor_groups:
    leader:
      weight: 0.333333
      factors:
        - {name: roic, direction: 1}
        - {name: revenue_scale, direction: 1}
        - {name: debt_to_assets, direction: -1}
    dividend_defense:
      weight: 0.333333
      factors:
        - {name: earnings_yield, direction: 1}
        - {name: dividend_yield_2y_avg, direction: 1}
        - {name: dividend_price_ratio_2y_avg, direction: 1}
        - {name: ocf_to_profit, direction: 1}
        - {name: downside_volatility, direction: -1}
    growth_stability:
      weight: 0.333334
      factors:
        - {name: netprofit_yoy, direction: 1}
        - {name: profit_growth_stability, direction: 1}
        - {name: volatility, direction: -1}
        - {name: pb, direction: -1}

evaluation:
  primary_metric: sharpe
  annualization_days: 252
  test_used_once: true

8. 因子计算规则

8.1 基础衍生因子

使用以下默认近似:

因子 默认计算 注意事项
earnings_yield 1 / pe_ttm PE 小于等于 0 或缺失时剔除或置空
value_residual 盈利收益率对 ROE 做横截面回归残差 优先行业内做,数据不足时全市场做
revenue_scale log(revenue) 或可得收入规模字段 不能用未来公告
dividend_yield_2y_avg 最近两年股息率均值 无股息字段时标注代理
dividend_price_ratio_2y_avg 两年股利价格比均值 需说明口径
volatility 过去 vol_lookback_days 日收益波动 年化与否要标注
downside_volatility 过去窗口负收益标准差 用于权重
profit_growth_stability 净利润增速时间序列稳定性 可用负波动或稳定性分数代理

8.2 标准化规则

默认处理:

  1. 每个调仓日单独计算横截面因子。
  2. 能行业内标准化时,优先行业内 z-score 或 rank。
  3. 行业内样本太少时,回退全市场标准化。
  4. 极值应 winsorize 或用 rank,避免少数异常值主导。
  5. 所有因子方向必须明确:越大越好为 1,越小越好为 -1。

8.3 价值基础池

默认规则:

  1. 先过滤可交易、上市时长、流动性、市值、ROE、PE 等基础条件。
  2. 计算 earnings_yield。
  3. 用 earnings_yield ~ roe 做横截面回归,取残差。
  4. 保留残差最有利的一部分,如 top 1/3。
  5. 若候选数量不足,使用 fallback 阈值,但必须写入报告。

9. 组合构建规则

默认组合规则:

  1. 每个调仓日生成得分排名。
  2. 目标持仓数 hold_n = 30。
  3. 缓冲池 buffer_n = 45,用于降低换手。
  4. 单票权重上限 max_weight_per_stock = 5%。
  5. 权重按下行波动倒数分配。
  6. 若权重超上限,截断后再归一。
  7. 交易成本按 cost_bps_per_side 进入回测。
  8. 不做择时,不做仓位择时,不因为市场环境临时空仓,除非策略协议明确允许。

10. 运行流程

Step 1:创建研究目录

推荐结构:

stock_selection_evolution/
  SKILL.md
  skill_config.yaml
  reference_claims.json
  data/
    raw/
    canonical/
  scripts/
    build_snapshot.py
    build_feature_cache.py
    strategy_gen.py
    strategy_backtest.py
    evolve_versions.py
  result/
    skills/
      {skill_name}/
        v0.0.0/
        evolution/

如果系统只能上传一个 Markdown Skill,则 Agent 应在首次运行时根据本 Skill 自动创建上述目录和文件。

Step 2:建立公开声明文件

把研报或用户描述中的结构化事实写入 reference_claims.json:

{
  "source_note": "Structured facts from public report or user-provided strategy description. No verbatim copyrighted report text.",
  "sample_splits": {
    "train": {"start": "2014-12-31", "end": "2018-12-28"},
    "valid": {"start": "2018-12-28", "end": "2020-12-31"},
    "test": {"start": "2020-12-31", "end": "2026-04-30"}
  },
  "initial_strategy": {
    "name": "稳健低波价值优选",
    "portfolio": {
      "rebalance": "monthly",
      "target_holdings": 30,
      "buffer_pool": 45,
      "max_weight_per_stock": 0.05,
      "weighting": "inverse downside volatility"
    }
  },
  "reported_metrics": []
}

不要复制大段原文,不要搬运非公开代码。

Step 3:构建 canonical 数据

把不同数据源统一成标准格式:

daily_bar.jsonl
daily_basic.jsonl
fina_indicator.jsonl
stock_basic.jsonl
benchmark.jsonl

每个 JSONL 一行一个对象,日期和代码字段必须可连接。

构建后生成 data_inventory.md:

| 数据表 | 行数 | 股票数 | 起始日期 | 结束日期 | 缺失说明 |
|---|---:|---:|---|---|---|
| market | 1662810 | 700 | 2014-12-31 | 2026-04-30 | ... |

Step 4:生成特征缓存

若样本较大,必须优先构建调仓日特征缓存:

feature_cache.jsonl
feature_cache.meta.json

feature_cache.meta.json 至少包含:

  • 数据文件路径。
  • 数据文件 hash 或修改时间。
  • 策略参数中影响原始特征的字段。
  • 调仓日数量。
  • 特征行数。
  • 覆盖股票数。
  • 构建耗时。

如果缓存签名不匹配,Agent 必须回退现场计算,不得复用旧缓存。

Step 5:跑基线版本

基线版本固定为 v0.0.0。

输出目录:

result/skills/{skill_name}/v0.0.0/
  skill_config.yaml
  reference_claims.json
  metrics.json
  metrics_table.csv
  validation_report.json
  equity_curve_train.csv
  equity_curve_valid.csv
  equity_curve_test.csv
  positions_train.jsonl
  positions_valid.jsonl
  positions_test.jsonl

报告必须包含:

  • 样本覆盖。
  • 有效起止日期。
  • 交易日数量。
  • 年化收益。
  • 年化波动。
  • Sharpe。
  • 最大回撤。
  • Calmar。
  • 年化换手。
  • 月/季/半年/年度胜率,如可计算。
  • 已知缺口。

Step 6:生成候选版本

候选版本只允许做小步变更。

推荐候选类别:

类别 可变参数 不允许
价值池 value_residual_keep_quantile、max_pe_ttm 改写策略目标
流动性 adv_quantile_floor、min_adv_20d 事后剔除亏损股票
市值 market_cap_quantile_floor 事后按收益筛行业
因子权重 三组因子权重 加入测试集表现因子
组合 hold_n、buffer_n、max_weight_per_stock 用测试集决定持仓数
风险窗口 vol_lookback_days 用未来波动
调仓 rebalance_days 按测试集择时

候选版本示例:

- version: v0.1.4
  note: lower PE ceiling
  set:
    strategy.max_pe_ttm: 30.0

- version: v0.2.20
  note: moderate liquidity and market-cap floors
  set:
    strategy.adv_quantile_floor: 0.35
    strategy.market_cap_quantile_floor: 0.30

- version: v0.2.27
  note: report-aligned final candidate
  set:
    strategy.value_residual_keep_quantile: 0.25
    strategy.adv_quantile_floor: 0.40
    strategy.market_cap_quantile_floor: 0.35
    weight.leader: 0.35
    weight.dividend_defense: 0.40
    weight.growth_stability: 0.25

Step 7:验证集保留

版本保留规则:

  1. 每个候选都先跑验证集。
  2. 主指标默认 valid_sharpe。
  3. 只有验证集 Sharpe 创新高且逻辑未漂移,才进入 retained versions。
  4. 测试集可以随候选计算用于最终研究记录,但绝不能参与自动选择。
  5. 每个候选都进入版本账本,失败版本也保留。

账本字段:

| iteration | version | retained | mutation | valid_sharpe | test_sharpe | valid_return | test_return | max_drawdown | note |
|---:|---|---|---|---:|---:|---:|---:|---:|---|

Step 8:测试集人工复核

测试集复核必须回答:

  1. 验证集冠军在测试集是否同步改善?
  2. 测试集收益是否来自少数年份?
  3. 最大回撤是否恶化?
  4. 换手是否显著上升?
  5. 是否出现“验证集越高,测试集越差”的过拟合信号?
  6. 是否应拒绝最后验证集冠军,改保留更稳版本?

测试集复核结论必须人工化表达,不得让程序自动用测试集选择版本。

可用模板:

## 测试集人工复核

- 验证集冠军:vX.X.X
- 测试集表现较稳版本:vY.Y.Y
- 是否接受验证集冠军:接受 / 拒绝 / 暂缓
- 理由:
  - ...
- 风险:
  - ...
- 后续动作:
  - ...

11. 指标计算口径

默认口径:

指标 计算
日收益 equity_t / equity_{t-1} - 1
年化收益 equity_end / equity_start 按交易日年化
年化波动 日收益标准差 × sqrt(252)
Sharpe 年化收益 / 年化波动,若有无风险收益则扣除
最大回撤 净值相对历史高点最大跌幅
Calmar 年化收益 / 最大回撤
年化换手 单期换手按年化折算
胜率 月/季/半年/年度收益为正的比例

输出指标时必须同时写:

  • 样本区间。
  • 交易日数量。
  • 年化天数。
  • 是否同一窗口比较。
  • 是否包含交易成本。
  • 是否使用完整股票池。

12. 版本目录规范

不得覆盖旧版本。

每个版本目录必须包含:

v0.2.20/
  skill_config.yaml
  candidate_config.json
  validation_report.json
  metrics.json
  metrics_table.csv
  equity_curve_train.csv
  equity_curve_valid.csv
  equity_curve_test.csv
  positions_train.jsonl
  positions_valid.jsonl
  positions_test.jsonl
  figures/

演化目录必须包含:

evolution/run_YYYYMMDD_HHMMSS/
  evolution_ledger.json
  retained_versions.json
  evolution_summary.csv
  evolution_sharpe.svg
  v0.0.0/candidate_config.json
  v0.0.0/candidate_result.json
  ...

13. 验证报告模板

每次运行必须输出 validation_report.md 或 validation_report.json。

Markdown 模板:

# 选股策略自进化验证报告

## 1. 运行摘要

- Skill 名称:
- 版本:
- 运行时间:
- 数据源:
- 股票池:
- 样本区间:
- 是否使用交易成本:
- 是否使用特征缓存:

## 2. 数据覆盖

| 数据 | 行数 | 股票数 | 起始 | 结束 | 缺口 |
|---|---:|---:|---|---|---|

## 3. 样本结果

| 样本 | 起始 | 结束 | 交易日 | 年化 | Sharpe | 最大回撤 | 年化换手 |
|---|---|---|---:|---:|---:|---:|---:|

## 4. 版本演化

| 版本 | 保留 | 验证 Sharpe | 测试 Sharpe | 变更 | 备注 |
|---|---|---:|---:|---|---|

## 5. 测试集人工复核

- 验证集冠军:
- 测试集复核较稳版本:
- 是否接受:
- 理由:

## 6. 已知缺口

- 股票池:
- 因子口径:
- 交易约束:
- 行业分类:
- 数据缺失:

## 7. 风险提示

仅供学习研究,不构成投资建议。回测、样本声明和策略代码不代表未来收益,策略结果、数据来源和实盘风险需自行验证。

14. 复刻研报前的 10 项审计

任何 Agent 在声称“复刻”前,必须逐项回答:

项目 状态 说明
1. 样本区间是否完整 已对齐 / 代理 / 未复刻
2. 训练/验证/测试是否隔离 已对齐 / 代理 / 未复刻
3. 股票池是否一致 已对齐 / 代理 / 未复刻
4. 因子口径是否一致 已对齐 / 代理 / 未复刻
5. 是否有未来函数 已排除 / 有风险 / 未检查
6. 是否处理 ST/停牌/涨跌停 已处理 / 代理 / 未处理
7. 是否包含交易成本 已包含 / 代理 / 未包含
8. 是否有版本账本 已生成 / 部分 / 未生成
9. 测试集是否只复核 是 / 有污染 / 未说明
10. 失败结果是否也保留 是 / 部分 / 否

如果任一项为“未复刻、未检查、有污染”,不得输出“完美复刻”。

15. 当前 clean-room 参考结果

以下结果来自一个本地 clean-room pilot,用于说明工作流,不代表未来收益。

测试集区间:2020-12-31 至 2026-04-30,约 1289 个交易日。

版本 选择状态 验证 Sharpe 测试年化 测试 Sharpe 最大回撤 年化换手
500只基线 v0.0.0 原中证500代理 0.853 7.32% 0.458 30.50% 3.58
700只基线 v0.0.0 全A代理基线 0.954 11.26% 0.677 17.95% 3.25
700只 v0.2.20 验证集保留且测试复核较好 1.098 13.05% 0.753 24.24% 2.91
700只 v0.2.27 最后验证集冠军 1.168 7.01% 0.458 30.87% 2.99

重要结论:

  • 股票池是第一关键变量。500只代理池测试 Sharpe 0.458;700只全A代理池测试 Sharpe 0.677,接近公开披露初始版本约 0.69。
  • 验证集也会骗人。v0.2.27 是最后验证集冠军,但测试集弱于 v0.2.20。
  • 自进化不是一路把指标调高,而是持续暴露样本适配和过拟合风险。

16. 输出格式

当用户要求“运行 Skill”时,Agent 最终必须输出:

# 运行结果

## 已完成

- 数据契约检查:
- 基线回测:
- 候选版本:
- 验证集保留:
- 测试集复核:
- 报告位置:

## 核心指标

| 版本 | 验证 Sharpe | 测试年化 | 测试 Sharpe | 最大回撤 | 年化换手 |
|---|---:|---:|---:|---:|---:|

## 结论

...

## 已知风险

...

## 下一步

...

风险提示:仅供学习研究,不构成投资建议。回测、样本声明和策略代码不代表未来收益,策略结果、数据来源和实盘风险需自行验证。

17. 失败处理

如果运行失败,Agent 不得只说“失败”。必须给出:

  • 失败步骤。
  • 错误信息摘要。
  • 已确认的输入文件。
  • 缺失字段或缺失数据。
  • 是否影响样本隔离。
  • 最小可执行下一步。

失败输出模板:

# 运行失败报告

## 失败步骤

...

## 直接原因

...

## 已验证事实

- ...

## 不应继续的原因

- ...

## 最小下一步

...

18. Agent 行为纪律

  1. 先读配置和数据契约,再写代码。
  2. 先跑基线,再跑候选版本。
  3. 先解释数据边界,再解释收益指标。
  4. 不为了让结果好看而隐藏失败。
  5. 不把测试集反馈写回参数。
  6. 不覆盖旧结果。
  7. 不在没有数据支持时编造图表或指标。
  8. 不输出任何密钥、token、私密 ID。
  9. 对所有代理字段、近似口径、缺失处理做显式标注。
  10. 输出结论必须先讲研究边界,再讲指标。

19. 推荐用户指令

用户可以这样调用:

请使用“选股策略自进化研究 Skill”,基于我提供的 Tushare/AmazingData 数据,复刻这篇研报的公开机制。先做数据契约检查,再跑基线,最后做验证集保留和测试集人工复核。不要给投资建议。

或:

请把我的这个选股逻辑写成自进化 Skill。要求训练集、验证集、测试集隔离,每个候选版本落盘,测试集只做最终复核,并输出版本账本和风险报告。

20. 首次运行询问清单

当用户没有提供足够信息时,Agent 不要直接写代码。先用最少问题补齐关键输入。

20.1 必问问题

我需要先确认 6 件事,才能按自进化 Skill 跑得可靠:

1. 数据源是什么?Tushare、AmazingData、本地文件、数据库,还是研究平台导出?
2. 股票池是什么?全A、沪深300、中证500、中证1000、行业池,还是用户自定义列表?
3. 样本区间是否沿用默认切分:训练 2014-12-31~2018-12-28,验证 2018-12-28~2020-12-31,测试 2020-12-31~2026-04-30?
4. 是否允许我创建本地项目目录并写入配置、缓存、回测结果和报告?
5. 策略来源是什么?公开研报、用户自定义逻辑,还是已有代码?
6. 你希望本轮只做基线复刻,还是同时跑候选版本演化?

20.2 可默认假设

如果用户没有回答,Agent 可以采用以下默认值,但必须写入报告:

项目 默认值 报告说明
股票池 用户数据中可交易 A 股 若非完整历史全A,标注为代理池
调仓频率 21 个交易日近似月度 写明近似
目标持仓 30 只 来自默认协议
缓冲池 45 只 来自默认协议
单票上限 5% 来自默认协议
交易成本 单边 30 bps 若用户未指定,标注默认假设
年化天数 252 写入指标口径
无风险收益 0 若未提供无风险利率

20.3 不可默认假设

以下内容不能默认脑补:

  • API token、数据库密码、私有数据下载权限。
  • 完整历史全A股票池。
  • ST、停牌、涨跌停处理已经完成。
  • 行业分类是历史点位行业。
  • 财务公告日已经正确避免未来函数。
  • 研报内部原始代码和候选生成逻辑。

21. 跨 Agent 安装说明

本 Skill 是 Markdown-only 版本,适合上传到 Red Skill、Workbuddy、Hermes、OpenClaw、Codex 或其他支持 Markdown Skill 的 Agent 系统。

21.1 Red Skill / Workbuddy

安装方式:

  1. 创建新 Skill。
  2. Skill 名称填:选股策略自进化研究 Skill。
  3. 简介填入本文件 frontmatter 的 description 或 red_skill_description.md 的“一句话描述”。
  4. Skill 正文粘贴本 Markdown 全文。
  5. 如果平台支持默认 Prompt,填入“默认调用 Prompt”。
  6. 如果平台支持标签,使用:量化研究、AI投研、回测审计、策略自进化、Auto Research。

使用注意:

  • Red Skill 若不允许执行代码,则让 Agent 先生成项目文件和运行说明,再由用户在本地执行。
  • Red Skill 若可调用文件工具,则必须按本文目录规范创建文件,不要只输出解释。
  • Red Skill 若接入数据源连接器,先做字段映射,不要直接跑策略。

21.2 Hermes / OpenClaw

安装方式:

  1. 将本文件保存为 SKILL.md。
  2. 放入技能目录,例如 skills/stock-selection-evolution-research/SKILL.md。
  3. 如果系统支持技能索引,重启或刷新技能索引。
  4. 首次调用时,让 Agent 在工作区创建项目目录。

推荐目录:

stock-selection-evolution-research/
  SKILL.md
  projects/
    {project_name}/
      skill_config.yaml
      reference_claims.json
      data/
      scripts/
      result/
      reports/

21.3 Codex / Claude Code

安装方式:

  1. 将本文件保存为 ~/.codex/skills/stock-selection-evolution-research/SKILL.md 或 Claude Skill 目录。
  2. 确认 YAML frontmatter 只有 name 和 description。
  3. 调用时明确说“使用 stock-selection-evolution-research”。
  4. 对涉及数据写入、长时间回测、外部 API 拉取的动作,先确认数据源和权限。

21.4 只有聊天能力、不能写文件的 Agent

如果 Agent 不能写文件或执行代码,应输出:

  1. 字段映射表。
  2. skill_config.yaml 文本。
  3. reference_claims.json 文本。
  4. Python 脚本草稿。
  5. 运行命令。
  6. 报告模板。

并明确说明:当前未实际运行,结果只是可执行方案。

22. 从零创建项目的执行蓝图

当用户允许写文件时,Agent 必须创建以下最小可运行项目。

22.1 目录结构

{project_root}/
  README.md                         # 简短说明,可选
  SKILL.md                          # 本 Skill 或项目专用协议
  skill_config.yaml                 # 策略配置
  reference_claims.json             # 公开声明/用户策略描述结构化记录
  data_contract_report.md           # 数据契约审计
  data/
    raw/                            # 原始数据,可选
    canonical/
      daily_bar.jsonl
      daily_basic.jsonl
      fina_indicator.jsonl
      stock_basic.jsonl
      benchmark.jsonl
      feature_cache.jsonl
      feature_cache.meta.json
  scripts/
    normalize_data.py
    build_feature_cache.py
    strategy_gen.py
    strategy_backtest.py
    evolve_versions.py
    report_results.py
  result/
    skills/
      {skill_name}/
        v0.0.0/
        evolution/
  reports/
    validation_report.md
    test_review.md

如果用户要求严格单文件项目,至少创建:

skill_config.yaml
reference_claims.json
run_stock_selection_evolution.py
validation_report.md

22.2 文件创建顺序

  1. reference_claims.json
  2. skill_config.yaml
  3. data_contract_report.md
  4. canonical 数据文件
  5. build_feature_cache.py
  6. strategy_backtest.py
  7. evolve_versions.py
  8. validation_report.md

不要先写演化脚本再补数据契约。

22.3 最小运行命令约定

Agent 生成脚本时,应尽量支持以下命令:

python scripts/normalize_data.py --config skill_config.yaml
python scripts/build_feature_cache.py --config skill_config.yaml
python scripts/strategy_backtest.py --config skill_config.yaml
python scripts/evolve_versions.py --config skill_config.yaml
python scripts/report_results.py --config skill_config.yaml

如果系统只有一个脚本:

python run_stock_selection_evolution.py --config skill_config.yaml --mode all
python run_stock_selection_evolution.py --config skill_config.yaml --mode baseline
python run_stock_selection_evolution.py --config skill_config.yaml --mode evolve
python run_stock_selection_evolution.py --config skill_config.yaml --mode report

23. 数据源适配细则

23.1 Tushare 适配

常用接口映射:

目标表 Tushare 接口 关键字段 备注
行情 daily / pro_bar trade_date, ts_code, open, high, low, close, vol, amount 注意复权
估值 daily_basic pe_ttm, pb, total_mv, circ_mv, dv_ttm 需按交易日对齐
财务 fina_indicator roe, roic, debt_to_assets, netprofit_yoy, ocf_to_profit 必须使用公告可得日期
股票元数据 stock_basic ts_code, name, list_date, industry, exchange 当前行业不等于历史行业
指数 index_daily trade_date, close 用于基准

Tushare 风险:

  • fina_indicator 若按报告期直接 merge,容易未来函数。
  • stock_basic 行业通常是当前行业,不是历史行业。
  • daily_basic 缺失会影响 PE/PB/股息率。
  • 当前上市股票列表会产生幸存者偏差,完整复刻必须用历史可交易股票池。

23.2 AmazingData 适配

Agent 应先让用户或连接器提供 AmazingData 字段说明。不要假设字段名完全等于 Tushare。

适配步骤:

  1. 读取表列表和字段字典。
  2. 建立字段映射表。
  3. 抽样 5 个交易日检查日期、代码、复权、停牌、ST、行业字段。
  4. 检查财务数据是否有公告日。
  5. 将数据导出为 canonical JSONL 或直接在代码中映射。

字段映射模板:

| canonical | AmazingData 字段 | 类型 | 缺失率 | 转换规则 | 风险 |
|---|---|---|---:|---|---|
| symbol | ... | string | ... | 转成统一股票代码 | |
| trade_date | ... | date | ... | YYYY-MM-DD | |
| close | ... | float | ... | 复权/不复权说明 | |
| pe_ttm | ... | float | ... | 小于等于0置空 | |
| ann_date | ... | date | ... | 用于防未来函数 | |

23.3 本地文件适配

支持 CSV、JSONL、Parquet。

Agent 必须检查:

  • 编码是否正确。
  • 日期字段是否可解析。
  • 股票代码是否统一。
  • 是否有重复行。
  • 是否有同一股票同一日期多条记录。
  • 是否有明显异常值,如价格小于等于 0、市值小于等于 0。
  • 是否有缺失严重的核心字段。

本地文件读取后统一输出为 canonical JSONL,除非用户明确要求保留原格式。

23.4 数据库适配

如果用户提供数据库连接,Agent 不得在报告中输出连接串、密码、token。

执行步骤:

  1. 只读取 schema 和样本行。
  2. 写字段映射表。
  3. 用只读查询导出需要字段。
  4. 不修改源表。
  5. 对大表使用分区日期增量拉取。

24. 未来函数防线

未来函数是本 Skill 的最高优先级风险之一。

24.1 财务数据可得性

财务数据必须按可得日期使用:

  • 优先使用公告日 ann_date。
  • 如果只有报告期 end_date,必须加保守滞后,例如 90 天或 120 天。
  • 调仓日只能使用 ann_date <= rebalance_date 的最新财务数据。
  • 不允许把 2020 年年报数据用于 2020 年年报公告前的调仓。

伪代码:

def latest_financial_asof(financial_rows, symbol, rebalance_date):
    rows = [
        r for r in financial_rows[symbol]
        if r["ann_date"] <= rebalance_date
    ]
    return max(rows, key=lambda r: r["ann_date"]) if rows else None

如果没有公告日:

available_date = report_end_date + conservative_lag_days

并在报告中写:

> 财务数据缺少公告日,使用报告期后 120 天作为可得日近似。该处理可能改变因子时点,需要后续用公告日精确复核。

24.2 股票池未来函数

禁止使用“当前成分股”回推历史,除非明确标注为代理池。

股票池优先级:

  1. 历史全A可交易股票池。
  2. 历史指数成分或行业成分。
  3. 用户指定静态股票池。
  4. 当前股票池回推历史,只能作为代理实验。

报告必须写:

股票池口径:完整历史全A / 历史成分 / 静态代理池 / 当前成分回推
幸存者偏差风险:低 / 中 / 高

24.3 调仓时点

调仓时使用的信息必须满足:

  • 行情:只能使用调仓日前一交易日或更早数据。
  • 财务:只能使用调仓日已公告数据。
  • 估值:只能使用调仓日前一交易日或当日收盘后可得数据;若假设次日开盘交易,必须写清。
  • ST/停牌/涨跌停:必须用调仓日可得状态。

24.4 指标污染

以下行为视为测试集污染:

  • 用测试集 Sharpe 决定参数。
  • 看到测试集后改变候选版本顺序。
  • 用测试集年度收益决定是否保留版本。
  • 删除测试集差的候选版本。
  • 把测试集表现写入下一轮候选生成提示词。

25. 回测引擎实现蓝图

25.1 核心伪代码

load_config()
load_canonical_data()
validate_data_contract()
build_or_load_feature_cache()

for split in ["train", "valid", "test"]:
    dates = get_rebalance_dates(split.start, split.end)
    portfolio = {}
    equity = 1.0
    for date in dates:
        tradable_universe = filter_universe(date)
        factor_panel = get_features_asof(date, tradable_universe)
        scores = score_stocks(factor_panel, config.factor_groups)
        target = construct_portfolio(scores, previous_portfolio=portfolio)
        turnover = calculate_turnover(portfolio, target)
        cost = turnover * cost_bps_per_side / 10000
        period_return = calculate_forward_return(target, date, next_rebalance_date)
        equity = equity * (1 + period_return - cost)
        save_positions(date, target, scores, turnover)
        portfolio = target
    save_equity_curve(split)
    calculate_metrics(split)

25.2 股票过滤顺序

推荐顺序:

  1. 是否上市满 min_listed_days。
  2. 是否有足够历史行情 min_history_days。
  3. 是否停牌。
  4. 是否 ST 或退市风险。
  5. 是否涨跌停导致不可买入/卖出。
  6. 成交额是否达到绝对阈值。
  7. 成交额是否达到横截面分位阈值。
  8. 市值是否达到分位阈值。
  9. ROE 是否为正。
  10. PE/PB/财务字段是否可用。

如果某项无法处理,写入 known_gaps,不要假装已处理。

25.3 打分流程

def score_stocks(panel, factor_groups):
    group_scores = {}
    for group_name, group in factor_groups.items():
        factor_scores = []
        for factor in group["factors"]:
            values = panel[factor["name"]]
            values = winsorize(values)
            ranks = cross_sectional_rank(values)
            if factor["direction"] == -1:
                ranks = 1 - ranks
            factor_scores.append(ranks)
        group_scores[group_name] = average(factor_scores)
    total_score = sum(group.weight * group_scores[name] for name, group in factor_groups.items())
    return total_score.sort(descending=True)

25.4 缓冲池逻辑

缓冲池用于降低换手:

top_hold = ranked[:hold_n]
buffer = ranked[:buffer_n]

kept_old = [s for s in old_holdings if s in buffer]
new_needed = hold_n - len(kept_old)
new_names = [s for s in top_hold if s not in kept_old][:new_needed]
target = kept_old + new_names

如果 buffer_n < hold_n,配置无效。

25.5 权重计算

默认使用下行波动倒数:

risk = downside_volatility(symbol)
raw_weight = 1 / max(risk, epsilon)
weights = normalize(raw_weight)
weights = cap_at_max_weight(weights, max_weight_per_stock)
weights = renormalize(weights)

如果风险数据缺失:

  1. 优先使用普通波动率。
  2. 再回退等权。
  3. 必须写入报告。

26. 特征缓存设计

当股票数超过 300、调仓日超过 50,建议使用特征缓存。

26.1 缓存文件

feature_cache.jsonl 每行:

{
  "rebalance_date": "2020-12-31",
  "symbol": "000001.SZ",
  "industry": "银行",
  "listed_days": 7300,
  "adv_20d": 123456789.0,
  "market_cap": 12345678900.0,
  "roe": 0.12,
  "roic": 0.10,
  "earnings_yield": 0.08,
  "pb": 0.9,
  "volatility": 0.22,
  "downside_volatility": 0.15,
  "dividend_yield_2y_avg": 0.03,
  "netprofit_yoy": 0.10,
  "profit_growth_stability": 0.75
}

feature_cache.meta.json:

{
  "signature": "hash of data paths and feature-affecting parameters",
  "created_at": "YYYY-MM-DD HH:MM:SS",
  "rebalance_date_count": 133,
  "row_count": 77064,
  "symbol_count": 700,
  "build_seconds": 104.4,
  "inputs": {
    "market_snapshot": "...",
    "financial_snapshot": "...",
    "daily_basic_snapshot": "...",
    "stock_basic_snapshot": "..."
  },
  "feature_params": {
    "min_history_days": 120,
    "min_listed_days": 250,
    "vol_lookback_days": 250,
    "adv_lookback_days": 20,
    "dividend_lookback_days": 504
  }
}

26.2 缓存使用规则

  1. 缓存签名一致,允许使用。
  2. 缓存签名不一致,必须重建或现场计算。
  3. 因子权重变化不需要重建原始特征缓存。
  4. 影响原始特征的窗口参数变化,需要重建或回退现场计算。
  5. 缓存缺少某调仓日,不得静默跳过,必须报错或回退。

27. 候选版本库

Agent 可以从下列候选库开始,但必须根据用户策略和数据质量裁剪。

27.1 基线

- version: v0.0.0
  note: base stable low-vol value profile
  set: {}

27.2 价值基础池

- version: v0.1.1
  note: looser value residual pool
  set: {strategy.value_residual_keep_quantile: 0.25}
- version: v0.1.2
  note: mildly looser value residual pool
  set: {strategy.value_residual_keep_quantile: 0.28}
- version: v0.1.3
  note: stricter value residual pool
  set: {strategy.value_residual_keep_quantile: 0.40}
- version: v0.1.4
  note: lower PE ceiling
  set: {strategy.max_pe_ttm: 30.0}
- version: v0.1.5
  note: higher PE ceiling
  set: {strategy.max_pe_ttm: 50.0}

27.3 流动性和市值

- version: v0.1.6
  note: lower market-cap floor
  set: {strategy.market_cap_quantile_floor: 0.25}
- version: v0.1.7
  note: higher market-cap floor
  set: {strategy.market_cap_quantile_floor: 0.45}
- version: v0.1.8
  note: lower liquidity floor
  set: {strategy.adv_quantile_floor: 0.30}
- version: v0.1.9
  note: higher liquidity floor
  set: {strategy.adv_quantile_floor: 0.50}

27.4 因子权重

- version: v0.2.1
  note: mild dividend-defense tilt
  set: {weight.leader: 0.30, weight.dividend_defense: 0.40, weight.growth_stability: 0.30}
- version: v0.2.2
  note: strong dividend-defense tilt
  set: {weight.leader: 0.25, weight.dividend_defense: 0.50, weight.growth_stability: 0.25}
- version: v0.2.3
  note: quality leader tilt
  set: {weight.leader: 0.45, weight.dividend_defense: 0.30, weight.growth_stability: 0.25}
- version: v0.2.4
  note: growth stability tilt
  set: {weight.leader: 0.25, weight.dividend_defense: 0.30, weight.growth_stability: 0.45}

27.5 组合约束

- version: v0.2.5
  note: lower single-name cap
  set: {strategy.max_weight_per_stock: 0.04}
- version: v0.2.6
  note: higher single-name cap
  set: {strategy.max_weight_per_stock: 0.06}
- version: v0.2.7
  note: more concentrated portfolio
  set: {strategy.hold_n: 25, strategy.buffer_n: 40}
- version: v0.2.8
  note: more diversified portfolio
  set: {strategy.hold_n: 35, strategy.buffer_n: 50}
- version: v0.2.9
  note: wider retention buffer
  set: {strategy.buffer_n: 60}

27.6 调仓和风险窗口

- version: v0.2.10
  note: lower turnover cadence
  set: {strategy.rebalance_days: 42}
- version: v0.2.11
  note: higher turnover cadence
  set: {strategy.rebalance_days: 10}
- version: v0.2.12
  note: shorter risk lookback
  set: {strategy.vol_lookback_days: 120}
- version: v0.2.13
  note: longer risk lookback
  set: {strategy.vol_lookback_days: 500}

27.7 组合候选

- version: v0.2.20
  note: moderate liquidity and market-cap floors
  set:
    strategy.adv_quantile_floor: 0.35
    strategy.market_cap_quantile_floor: 0.30
- version: v0.2.24
  note: lower drawdown retention profile
  set:
    strategy.buffer_n: 60
    strategy.max_weight_per_stock: 0.04
    strategy.rebalance_days: 21
- version: v0.2.27
  note: public-report-aligned final candidate
  set:
    strategy.hold_n: 30
    strategy.buffer_n: 45
    strategy.max_weight_per_stock: 0.05
    strategy.value_residual_keep_quantile: 0.25
    strategy.adv_quantile_floor: 0.40
    strategy.market_cap_quantile_floor: 0.35
    weight.leader: 0.35
    weight.dividend_defense: 0.40
    weight.growth_stability: 0.25

27.8 候选库使用纪律

  • 不需要一次跑完所有候选。数据慢时先跑 5-8 个代表候选。
  • 每轮候选应围绕一个主题,避免同时改太多变量。
  • 如果候选改变了原始特征窗口,确认特征缓存是否需要重建。
  • 如果连续多轮验证集提升但测试集下降,停止追加候选,先做过拟合复盘。

28. 验收测试

Agent 在交付前必须完成以下检查。

28.1 文件验收

- [ ] `skill_config.yaml` 存在。
- [ ] `reference_claims.json` 存在。
- [ ] canonical 数据文件存在。
- [ ] `result/skills/{skill_name}/v0.0.0/` 存在。
- [ ] `validation_report` 存在。
- [ ] 若跑演化,`evolution_summary.csv` 存在。
- [ ] 未覆盖旧版本目录。

28.2 数据验收

- [ ] 行情覆盖训练、验证、测试三段。
- [ ] 财务数据有公告日或保守滞后处理。
- [ ] 股票代码格式统一。
- [ ] 调仓日特征行数合理。
- [ ] 股票池口径已说明。
- [ ] 缺失字段和代理字段已列出。

28.3 逻辑验收

- [ ] 基线版本先于候选版本运行。
- [ ] 验证集用于保留版本。
- [ ] 测试集未用于自动选择。
- [ ] 候选版本变更可解释。
- [ ] 失败版本也保留在账本。
- [ ] 输出包含已知缺口。

28.4 指标验收

- [ ] 每个指标写明样本区间。
- [ ] 年化天数写明。
- [ ] 是否含交易成本写明。
- [ ] 最大回撤和换手没有被省略。
- [ ] 没有只展示最优版本。
- [ ] 没有把回测写成未来收益。

29. 常见失败和恢复

29.1 数据覆盖不足

症状:

  • 训练集或验证集无数据。
  • 某段样本只有很少交易日。
  • 股票数太少。

处理:

  1. 输出实际覆盖区间。
  2. 建议新的样本切分。
  3. 降级为 smoke test。
  4. 不输出策略有效性结论。

29.2 财务字段未来函数风险

症状:

  • 财务表只有报告期,没有公告日。
  • 因子在报告期结束日立即可用。

处理:

  1. 加 90-120 天保守滞后。
  2. 把该处理写入 known gaps。
  3. 重新跑基线。
  4. 比较滞后前后差异。

29.3 股票池偏差

症状:

  • 用当前上市股票回推历史。
  • 指数成分不是历史成分。
  • 剔除了退市股票。

处理:

  1. 标注为代理池。
  2. 不与研报指标做强对齐。
  3. 优先补历史股票池。
  4. 先比较 500/700/全A 不同股票池的基线差异。

29.4 版本过拟合

症状:

  • 验证集 Sharpe 连续提升。
  • 测试集 Sharpe 下降。
  • 最大回撤恶化。
  • 收益集中在少数年份。

处理:

  1. 停止追加候选。
  2. 输出验证集保留路径。
  3. 输出测试集人工复核。
  4. 允许拒绝验证集冠军。
  5. 回到更早、更稳的版本。

29.5 运行太慢

症状:

  • 每个候选都重新构造全量特征。
  • 全A池循环耗时过长。

处理:

  1. 建调仓日特征缓存。
  2. 缓存不受因子权重影响的原始特征。
  3. 将组合收益矩阵预计算。
  4. 先跑代表候选,再扩展候选库。

29.6 字段口径不一致

症状:

  • ROIC、股息率、收入规模、行业分类与研报定义不一致。

处理:

  1. 标注代理口径。
  2. 输出“公开披露 / 本地实现 / 差异影响”三列表。
  3. 不声称完全复现。
  4. 优先补影响最大的字段。

30. 交付物清单

完整运行后,Agent 应交付:

1. data_contract_report.md
2. skill_config.yaml
3. reference_claims.json
4. baseline validation_report.md/json
5. metrics_table.csv
6. equity_curve_train.csv
7. equity_curve_valid.csv
8. equity_curve_test.csv
9. positions_train.jsonl
10. positions_valid.jsonl
11. positions_test.jsonl
12. evolution_ledger.json
13. retained_versions.json
14. evolution_summary.csv
15. test_review.md
16. known_gaps.md
17. next_iteration_plan.md

如果某项未生成,报告中必须解释原因。

31. 对外表达规范

用于小红书、公众号、报告摘要或对外分享时,必须采用研究表达:

推荐说法:

  • “本地 clean-room 复刻实验。”
  • “测试集回测样本结果。”
  • “验证集冠军在测试集出现外推折损。”
  • “该版本只用于研究复核。”
  • “股票池和因子口径仍需继续对齐。”

禁止说法:

  • “这个策略可以赚钱。”
  • “未来大概率跑赢。”
  • “直接跟这个策略。”
  • “稳赚/保本/无风险。”
  • “完美复现华泰内部代码。”

对外摘要模板:

这是一套选股策略自进化研究 Skill,用于把公开研报或已有选股逻辑拆成可配置、可回测、可版本留痕的 AI 投研流程。它强调训练集、验证集、测试集隔离:训练集用于生成,验证集用于保留,测试集只做最终人工复核。所有结果仅供学习研究,不构成投资建议。

32. 更严格的质量门

如果用户要求“尽可能接近原研报”,Agent 必须提高质量门:

  1. 股票池必须从代理池升级到历史全A。
  2. ST、停牌、涨跌停必须逐日处理。
  3. 行业分类必须尽量使用历史行业。
  4. 财务字段必须使用公告日。
  5. 股息因子必须用真实分红数据,而不是只用估值表代理。
  6. ROIC、收入规模、利润稳定性必须逐项校验。
  7. 交易成本、调仓价格、复权口径必须写清。
  8. 输出与公开披露指标的差异归因。

差异归因模板:

| 差异来源 | 当前实现 | 原研报/目标口径 | 可能影响 | 优先级 |
|---|---|---|---|---|
| 股票池 | 700只代理池 | 完整历史全A | 高 | P0 |
| 行业分类 | 当前行业 | 历史行业 | 中 | P1 |
| 股息因子 | daily_basic近似 | 分红明细两年均值 | 中 | P1 |
| 涨跌停 | 未精确处理 | 逐日可交易约束 | 高 | P0 |

33. 二次迭代路线

当第一版跑通后,按以下顺序升级,不要直接继续调参:

  1. 补全历史股票池。
  2. 补公告日财务数据。
  3. 补 ST、停牌、涨跌停。
  4. 补历史行业分类。
  5. 补真实分红明细。
  6. 补组合收益矩阵缓存。
  7. 再扩展候选版本。
  8. 最后才讨论是否增加新因子。

每次升级只改一个大类,并输出升级前后基线对照。

34. 高质量回答示例

当用户问“这个策略现在怎么样”时,Agent 应回答:

当前只能说研究复刻进展,不能说策略可用。

已完成:
- 三段样本隔离。
- 基线回测。
- 候选版本演化。
- 验证集保留。
- 测试集人工复核。

关键发现:
- 股票池从 500 只代理扩到 700 只代理后,测试 Sharpe 从 0.458 提升到 0.677,说明数据边界是第一变量。
- v0.2.20 测试 Sharpe 0.753,但 v0.2.27 虽是验证集冠军,测试 Sharpe 回落到 0.458,说明继续追验证集会有外推折损。

不能下的结论:
- 不能说未来会有效。
- 不能说已经完全复现原研报。
- 不能给任何交易建议。

下一步:
- 补完整历史全A。
- 补 ST/停牌/涨跌停。
- 补历史行业和真实分红口径。

35. 最小可执行 Prompt 库

35.1 数据契约检查

使用选股策略自进化研究 Skill。请先读取我提供的数据文件,只做数据契约检查和字段映射,不要跑回测。输出字段覆盖、缺失率、样本区间、股票数、未来函数风险和最小补数建议。

35.2 基线复刻

使用选股策略自进化研究 Skill。基于当前数据创建 v0.0.0 基线版本,按训练/验证/测试三段回测,保存配置、持仓、净值、指标和验证报告。不要生成候选版本。

35.3 候选演化

使用选股策略自进化研究 Skill。在已有 v0.0.0 基线基础上,围绕价值池、流动性、市值、因子权重、持仓和调仓频率生成候选版本。只用验证集决定保留,测试集只做最终复核。

35.4 测试集复核

使用选股策略自进化研究 Skill。请读取演化账本,比较验证集冠军和测试集表现较稳版本,输出测试集人工复核意见。不要用测试集重新选择参数。

35.5 对外内容改写

使用选股策略自进化研究 Skill。请把这次复刻结果改写成研究型对外摘要,必须保留风险提示,不要提供投资建议,不要把回测结果写成未来收益。

36. Agent 执行协议

Agent 使用本 Skill 时必须按阶段工作,每个阶段都要有明确产物和退出条件。

36.1 Phase A:研究对象锁定

目标:确认要复刻的不是“收益率数字”,而是一套策略研究机制。

必须产出:

## 研究对象锁定

| 项目 | 内容 |
|---|---|
| 目标研究 | |
| 目标市场 | |
| 股票池 | |
| 样本切分 | |
| 调仓频率 | |
| 持仓数量 | |
| 交易成本 | |
| 因子组 | |
| 组合约束 | |
| 已知缺口 | |

退出条件:

  1. 用户提供了数据源或明确说明暂时只做框架设计。
  2. Agent 明确了复刻层级:概念复刻、代理池复刻、历史全A复刻、接近原研报复刻。
  3. Agent 写明哪些结论不能直接从公开材料得到。

36.2 Phase B:数据契约审计

目标:先判断数据能不能支撑研究,而不是先写回测。

必须产出:

## 数据契约审计

| 数据表 | 是否存在 | 日期范围 | 股票数 | 关键字段覆盖 | 主要风险 |
|---|---:|---:|---:|---|---|
| market | | | | | |
| daily_basic | | | | | |
| financial | | | | | |
| dividend | | | | | |
| stock_basic | | | | | |
| industry | | | | | |
| trade_status | | | | | |
| benchmark | | | | | |

退出条件:

  1. 能解释为什么训练集是否覆盖 2014-12-31 至 2018-12-28。
  2. 能解释是否覆盖验证集 2018-12-28 至 2020-12-31。
  3. 能解释是否覆盖测试集 2020-12-31 至 2026-04-30。
  4. 能识别财务字段是否有公告日。
  5. 能识别股票池是否存在幸存者偏差。

36.3 Phase C:基线先行

目标:先建立一个可解释、可重复的 v0.0.0,不得直接做多版本搜索。

必须产出:

  • configs/v0.0.0.yaml
  • results/v0.0.0/holdings.csv
  • results/v0.0.0/nav.csv
  • results/v0.0.0/metrics_by_split.csv
  • results/v0.0.0/yearly_returns.csv
  • results/v0.0.0/run_manifest.json

退出条件:

  1. 基线结果可复跑。
  2. 每个指标都有日期区间、交易日数量和年化口径。
  3. Agent 能说明基线为什么是基线,而不是调参后的版本。

36.4 Phase D:候选版本演化

目标:只在明确协议内做小步变化。

候选版本只能来自以下变化类型:

类型 示例 是否允许一次多改
股票池 500 代理池升级到 700 代理池、代理池升级到历史全A 否
价值池阈值 PE/PB/股息率/ROE/ROIC 阈值 否
因子权重 价值、防御、成长、质量、风险权重 否
组合约束 持仓数量、缓冲池、单票上限、行业上限 否
调仓机制 调仓频率、调仓日、延迟交易 否
风控参数 波动率窗口、下行波动率、流动性过滤 否

每个候选版本必须写明:

## 候选版本说明

| 字段 | 内容 |
|---|---|
| version | |
| parent_version | |
| changed_one_thing | |
| reason | |
| expected_effect | |
| validation_result | |
| test_review_status | not_opened / reviewed_once / rejected |
| keep_or_reject | |

36.5 Phase E:测试集人工复核

目标:测试集只用于“最后一次人工审计”,不用于挑参数。

Agent 必须在报告中声明:

测试集使用声明:
本轮测试集结果只用于最终复核,不用于新增候选版本、调参、排序或重新选择冠军版本。如果测试集暴露出风险,只允许回到研究问题和数据口径层面做下一轮独立实验设计。

37. 代码实现接口标准

当 Agent 有文件写入和代码运行能力时,必须优先生成模块化实现。已有项目可映射到现有文件名,但接口语义应保持一致。

37.1 推荐文件结构

stock_evolution_research/
  README.md
  configs/
    base.yaml
    v0.0.0.yaml
  data/
    raw/
    canonical/
    cache/
  src/
    io_contract.py
    data_quality.py
    universe.py
    factors.py
    portfolio.py
    backtest.py
    evolution.py
    metrics.py
    report.py
    plots.py
  tests/
    test_no_future.py
    test_schema.py
    test_backtest_math.py
    test_portfolio_constraints.py
  results/
    version_ledger.csv
    skills/
      stock_selection_evolution/
        v0.0.0/

37.2 io_contract.py

必须负责把不同数据源映射为 canonical schema。

推荐接口:

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
import pandas as pd

@dataclass(frozen=True)
class DataCoverage:
    table: str
    start_date: str
    end_date: str
    row_count: int
    symbol_count: int
    missing_required_fields: list[str]
    risk_flags: list[str]

def load_market(path_or_conn: str) -> pd.DataFrame:
    """Return market rows with date, symbol, open, high, low, close, adj_factor, volume, amount."""

def load_daily_basic(path_or_conn: str) -> pd.DataFrame:
    """Return valuation and trading rows with date, symbol, pe_ttm, pb, ps_ttm, dv_ttm, total_mv, circ_mv, turnover_rate."""

def load_financial(path_or_conn: str) -> pd.DataFrame:
    """Return financial rows with ann_date, end_date, symbol, revenue, net_profit, roe, roic and balance sheet fields."""

def audit_coverage(tables: dict[str, pd.DataFrame], required: dict[str, list[str]]) -> list[DataCoverage]:
    """Return table-level coverage and risk flags before any backtest is allowed."""

37.3 data_quality.py

必须先于回测运行。

推荐接口:

def assert_unique_key(df, keys: list[str], table_name: str) -> None:
    """Fail if duplicate canonical keys exist."""

def assert_date_range(df, date_col: str, start: str, end: str, table_name: str) -> None:
    """Fail if required sample window is not covered."""

def detect_price_anomalies(market) -> pd.DataFrame:
    """Return rows with negative price, zero close, impossible high/low, or extreme split-like jumps."""

def detect_future_financial_join(financial, feature_dates) -> pd.DataFrame:
    """Return rows where feature date uses financial data before ann_date is available."""

def write_data_contract_report(audit_rows, output_path: str) -> None:
    """Write a Markdown report that explains coverage and blocking risks."""

37.4 universe.py

必须逐日生成股票池,不能只用期末股票列表。

推荐接口:

def build_tradable_universe(
    trade_date: str,
    stock_basic,
    market,
    trade_status=None,
    st_status=None,
    index_membership=None,
    min_listed_days: int = 250,
) -> pd.DataFrame:
    """Return symbols tradable on trade_date after listing age, ST, suspension and limit filters."""

def build_proxy_universe(
    trade_date: str,
    stock_basic,
    market,
    size: int,
    industry_col: str | None = None,
) -> pd.DataFrame:
    """Return a deterministic proxy pool when full historical all-A is unavailable."""

37.5 factors.py

必须只使用当时已可获得的数据。

推荐接口:

def asof_financial_snapshot(financial, trade_date: str, min_lag_days: int = 0):
    """Return latest financial records with ann_date <= trade_date."""

def compute_base_features(trade_date: str, canonical: dict, config: dict) -> pd.DataFrame:
    """Return one row per symbol with value, quality, growth, dividend, liquidity and risk features."""

def winsorize_by_date(df, cols, lower=0.01, upper=0.99):
    """Clip cross-sectional outliers at each rebalance date."""

def zscore_by_date(df, cols):
    """Standardize cross-sectional features at each rebalance date."""

def score_candidates(features, factor_weights: dict) -> pd.DataFrame:
    """Return score and factor contribution columns."""

37.6 portfolio.py

必须把选股和权重分开,便于审计。

推荐接口:

def select_with_buffer(
    scored,
    previous_holdings,
    hold_n: int,
    buffer_n: int,
) -> pd.DataFrame:
    """Keep existing names inside buffer first, then fill by rank."""

def assign_weights(
    selected,
    scheme: str,
    max_weight: float,
    risk_col: str | None = None,
) -> pd.DataFrame:
    """Return symbol and target_weight."""

def validate_portfolio_constraints(weights, max_weight: float, hold_n: int) -> list[str]:
    """Return violations, not silent fixes."""

37.7 backtest.py

必须明确调仓日、成交价格、费用、持仓收益计算。

推荐接口:

def generate_rebalance_dates(calendar, start: str, end: str, rebalance_days: int) -> list[str]:
    """Return deterministic rebalance dates from trading calendar."""

def run_backtest(config: dict, canonical: dict, features_cache=None) -> dict:
    """Return nav, holdings, trades, metrics_by_split and manifest."""

def compute_daily_portfolio_returns(holdings, market_returns, cost_bps: float) -> pd.DataFrame:
    """Return daily portfolio returns after turnover cost."""

37.8 evolution.py

必须生成候选版本账本。

推荐接口:

def generate_candidate_configs(base_config: dict, candidate_library: list[dict]) -> list[dict]:
    """Return candidate configs where each candidate changes one controlled dimension."""

def evaluate_on_validation(results: list[dict], selection_rule: dict) -> pd.DataFrame:
    """Rank candidates by validation split only."""

def freeze_test_review(version_id: str, reviewer_note: str) -> None:
    """Record one-time test review without allowing further automatic tuning."""

37.9 report.py 和 plots.py

必须生成可复核报告和图表数据,而不是只生成图片。

推荐接口:

def write_version_ledger(results, output_csv: str) -> None:
    """Write every version, parent, changed field, validation metrics and review status."""

def write_validation_report(context: dict, output_md: str) -> None:
    """Write conclusion-first Markdown report with known gaps and next steps."""

def export_chart_data(results, output_dir: str) -> None:
    """Write CSV files behind every chart so charts can be audited."""

38. Canonical 数据样例

Agent 应把所有数据源统一为以下样例形态。字段可以更多,但必需字段不能少。

38.1 market.jsonl

{"date":"2021-01-04","symbol":"000001.SZ","open":18.70,"high":19.10,"low":18.40,"close":18.90,"pre_close":18.34,"adj_factor":112.31,"volume":155000000,"amount":2920000000.0}

必需检查:

  • date + symbol 唯一。
  • high >= max(open, close, low)。
  • low <= min(open, close, high)。
  • close > 0。
  • volume >= 0。
  • 复权方式在报告中声明。

38.2 daily_basic.jsonl

{"date":"2021-01-04","symbol":"000001.SZ","pe_ttm":10.5,"pb":1.08,"ps_ttm":2.31,"dv_ttm":2.15,"total_mv":360000000000.0,"circ_mv":310000000000.0,"turnover_rate":0.87}

必需检查:

  • 极端负值是否合理。
  • 市值单位是否统一。
  • 股息率单位是百分比还是小数。
  • pe_ttm 为负时是否参与价值排序。

38.3 financial.jsonl

{"ann_date":"2021-04-20","end_date":"2020-12-31","symbol":"000001.SZ","revenue":153542000000.0,"net_profit":28928000000.0,"roe":0.103,"roic":0.078,"total_assets":4468514000000.0,"total_liab":4101582000000.0}

必需检查:

  • 任何特征日只能使用 ann_date <= trade_date 的记录。
  • 如果只有 end_date 没有 ann_date,必须降级可信等级。
  • 同一 symbol + end_date 多条记录时,优先使用最新修订还是首次公告必须声明。

38.4 dividend.jsonl

{"ann_date":"2021-05-10","ex_date":"2021-06-18","symbol":"000001.SZ","cash_dividend":0.18,"base_shares":19405900000}

必需检查:

  • 股息用公告日、除权日还是实施日必须声明。
  • 近两年股息率必须基于当时可见信息。
  • 不能用未来分红填充过去特征。

38.5 stock_basic.jsonl

{"symbol":"000001.SZ","name":"示例银行","list_date":"1991-04-03","delist_date":null,"exchange":"SZSE","board":"main"}

必需检查:

  • 退市股票是否保留。
  • 股票名称变更不应导致代码断裂。
  • 上市不足 min_listed_days 的股票是否剔除。

38.6 trade_status.jsonl

{"date":"2021-01-04","symbol":"000001.SZ","is_trade":true,"is_st":false,"is_suspended":false,"is_limit_up":false,"is_limit_down":false}

必需检查:

  • 无法买入涨停、无法卖出跌停的处理方式。
  • 停牌日收益是否沿用上一可交易价格。
  • ST 状态是否使用历史状态,而不是当前状态。

39. 数据质量检查清单

回测前必须运行以下检查,并将结果写入 data_contract_report.md。

检查项 失败条件 处理方式
日期覆盖 任一样本段缺少交易日 停止回测,报告缺口
主键唯一 date + symbol 重复 停止回测,输出重复样例
股票数异常 样本内股票数突变无法解释 标注股票池风险
价格异常 负价格、零价格、高低价冲突 停止或剔除并说明
复权口径 前复权/后复权/不复权混用 停止回测
财务可得性 ann_date > trade_date 被使用 停止回测
股票池幸存者 只用期末成分或当前全A 降级为代理复刻
ST/停牌缺失 无法逐日过滤 标注为高优先级缺口
行业历史缺失 只用当前行业 标注行业偏差
分红缺失 股息因子无法真实计算 使用代理因子并标注

数据质量报告模板:

# 数据契约检查报告

## 结论

当前数据可信等级:高 / 中 / 低 / 阻塞

## 样本覆盖

| 样本段 | 目标区间 | 实际区间 | 交易日数 | 是否通过 |
|---|---|---|---:|---|
| 训练集 | 2014-12-31 至 2018-12-28 | | | |
| 验证集 | 2018-12-28 至 2020-12-31 | | | |
| 测试集 | 2020-12-31 至 2026-04-30 | | | |

## 字段覆盖

| 表 | 必需字段缺失 | 可选字段缺失 | 风险 |
|---|---|---|---|

## 阻塞项

## 可降级项

## 最小补数建议

40. 单元测试样例

如果 Agent 能写代码,至少生成以下测试。测试不必覆盖全部业务,但必须覆盖未来函数和组合约束。

40.1 Schema 测试

def test_market_unique_date_symbol(market):
    duplicated = market.duplicated(["date", "symbol"]).sum()
    assert duplicated == 0

def test_market_price_sanity(market):
    assert (market["close"] > 0).all()
    assert (market["high"] >= market[["open", "close", "low"]].max(axis=1)).all()
    assert (market["low"] <= market[["open", "close", "high"]].min(axis=1)).all()

40.2 财务未来函数测试

def test_financial_asof_no_future(financial_features):
    assert (financial_features["ann_date"] <= financial_features["feature_date"]).all()

40.3 样本隔离测试

def test_split_boundaries(metrics_by_split):
    assert set(metrics_by_split["split"]) == {"train", "valid", "test"}
    assert metrics_by_split.loc[metrics_by_split["split"] == "train", "end_date"].max() <= "2018-12-28"
    assert metrics_by_split.loc[metrics_by_split["split"] == "valid", "start_date"].min() >= "2018-12-28"
    assert metrics_by_split.loc[metrics_by_split["split"] == "test", "start_date"].min() >= "2020-12-31"

40.4 权重约束测试

def test_portfolio_weight_sum(holdings):
    sums = holdings.groupby("date")["weight"].sum()
    assert ((sums - 1.0).abs() < 1e-6).all()

def test_portfolio_max_weight(holdings, max_weight=0.05):
    assert (holdings["weight"] <= max_weight + 1e-9).all()

40.5 测试集污染测试

def test_version_ledger_no_test_selection(version_ledger):
    selected = version_ledger[version_ledger["selected_for_final_review"] == True]
    assert not selected["selection_reason"].str.contains("test", case=False, na=False).any()

41. 回测计算细节

Agent 必须把回测口径写成可审计规则。

41.1 调仓日

推荐规则:

  1. 使用交易日历生成调仓日。
  2. 第一个调仓日为样本起点之后第一个可交易日。
  3. 每隔 rebalance_days 个交易日调仓一次。
  4. 调仓信号使用调仓日前一交易日收盘后可见数据。
  5. 成交价格默认使用下一交易日开盘价;若无开盘价则降级为下一交易日收盘价并声明。

41.2 收益计算

日收益推荐:

portfolio_return_t = sum(weight_{i,t-1} * stock_return_{i,t}) - turnover_cost_t

换手成本推荐:

turnover_t = 0.5 * sum(abs(target_weight_i - current_weight_i))
turnover_cost_t = turnover_t * cost_bps_per_side / 10000

若使用买卖双边成本,可写为:

turnover_cost_t = sum(abs(target_weight_i - current_weight_i)) * cost_bps_per_side / 10000

必须在报告中声明采用哪一种。

41.3 停牌、涨跌停和无法成交

推荐降级顺序:

  1. 有逐日状态:按真实可交易状态处理。
  2. 无逐日状态但有成交量:成交量为 0 视为不可交易候选。
  3. 无状态也无成交量:标注为高风险回测,只能做概念验证。

涨跌停处理:

  • 涨停日不允许新买入。
  • 跌停日不允许卖出。
  • 已持仓无法卖出时,保留至下一可卖日。
  • 无法买入时,现金保留或按剩余标的重新归一,必须声明。

41.4 年化口径

默认:

annual_return = (ending_nav / beginning_nav) ** (252 / trading_days) - 1
annual_vol = daily_return_std * sqrt(252)
sharpe = annual_return / annual_vol
max_drawdown = min(nav / cumulative_max(nav) - 1)
calmar = annual_return / abs(max_drawdown)

如果样本不足 60 个交易日,不输出年化结论,只输出区间收益。

42. 华泰式图表复刻规格

为了让研究报告有可读性,Agent 应输出图表数据和图表,而不是只输出表格。图表可借鉴公开研报的表达结构,但必须标注本地数据和 clean-room 口径。

42.1 策略自进化框架图

用途:解释协议层、版本层、隔离层和策略核心。

图表规格:

chart_id: figure_strategy_framework
type: framework_diagram
required_elements:
  - protocol_layer
  - version_layer
  - isolation_layer
  - strategy_core
  - factor_branch
  - rule_branch
  - risk_branch
  - train_valid_test_boxes
message: 策略自进化不是随机调参,而是协议约束下的版本化实验。

42.2 样本切分表

用途:解释训练集、验证集、测试集的权限。

图表规格:

chart_id: figure_sample_split
type: table
columns:
  - sample
  - date_range
  - permission
  - use_case
rows:
  - ["训练集", "2014-12-31 至 2018-12-28", "可用于生成和初筛", "建立基础逻辑,观察长期稳定性"]
  - ["验证集", "2018-12-28 至 2020-12-31", "可用于版本保留判断", "比较迭代版本,决定是否回滚"]
  - ["测试集", "2020-12-31 至 2026-04-30", "不进入自动调参闭环", "最终人工复核,评估真实外推风险"]
message: 样本权限比收益数字更重要。

42.3 Skill 组成表

用途:让读者知道这个 Skill 包含哪些文件和职责。

图表规格:

chart_id: figure_skill_components
type: table
columns:
  - component
  - file_or_directory
  - function
  - design_note
rows:
  - ["策略说明", "SKILL.md", "描述策略逻辑和禁止事项", "把策略内核写成协议"]
  - ["参数配置", "skill_config.yaml", "定义股票池、因子组、权重和调仓参数", "参数入参,不默认改代码"]
  - ["组合生成", "strategy_gen.py", "生成持仓、得分和调仓", "不在每轮实验中改公共工具"]
  - ["分段回测", "strategy_backtest.py", "训练/验证/测试分别回测", "测试集只做最终复核"]
  - ["版本目录", "results/skills/{skill_name}/v{version}/", "保存配置和结果", "避免覆盖旧结果"]
message: 好的 Skill 首先是可复核的工程结构。

42.4 复用比率趋势图

用途:展示每次迭代相对上一版本的持仓变化。

数据字段:

version, split, reuse_ratio, changed_names, total_holdings, version_label

图表规则:

  • x 轴为版本顺序。
  • y 轴为复用比率。
  • 训练、验证、测试三条线分色。
  • 每个点标注版本号。
  • 如果某一版本复用比率大幅下降,报告中解释原因。

message:

复用比率越高,说明版本更像小步迭代;复用比率骤降通常意味着策略逻辑发生漂移。

42.5 测试集净值曲线

用途:展示保留版本在测试集的表现分化。

数据字段:

date, version, nav, split

图表规则:

  • x 轴为日期。
  • y 轴为净值。
  • 初始版本、验证集冠军、测试集较稳版本必须突出显示。
  • 其他版本可用浅色线。
  • 图例写清版本号和迭代次数。
  • 标注样本区间和交易成本。

42.6 业绩指标热力图

用途:快速识别每个版本的强弱项。

数据字段:

version, annual_return, annual_vol, sharpe, max_drawdown, calmar, win_rate_monthly, win_rate_quarterly, win_rate_half_year, win_rate_yearly

图表规则:

  • 行为版本。
  • 列为指标。
  • 收益、Sharpe、Calmar 越高越好。
  • 波动、回撤越低越好,颜色方向需反转。
  • 表下注明交易成本、样本区间、数据源。

42.7 版本贡献拆解图

用途:解释哪些迭代贡献了测试集复用比率或净值改善。

数据字段:

version, parent_version, metric_before, metric_after, delta, changed_field, note

图表规则:

  • 左侧可画小型版本路径。
  • 右侧画瀑布图或阶梯图。
  • 每个变化点标注“改了什么”和“指标变化”。
  • 不要只标收益,必须同时标风险指标变化。

43. 年度收益和归因模板

用户询问“每年收益怎么样”时,Agent 应输出年度表,而不是只说总收益。

年度收益表:

| 年份 | 策略收益 | 基准收益 | 超额收益 | 最大回撤 | 换手率 | 主要解释 |
|---:|---:|---:|---:|---:|---:|---|
| 2021 | | | | | | |
| 2022 | | | | | | |
| 2023 | | | | | | |
| 2024 | | | | | | |
| 2025 | | | | | | |
| 2026YTD | | | | | | |

归因说明必须包含:

  1. 该年市场环境。
  2. 策略暴露是否偏价值、低波、股息、质量或小市值。
  3. 是否有单一年份贡献过高。
  4. 是否存在回撤集中期。
  5. 是否与版本迭代有关。

如果没有基准数据,只能输出策略年度收益,并说明缺少基准导致无法计算超额收益。

44. 人工复核评分表

测试集复核不能只看收益。Agent 应输出评分表。

| 维度 | 权重 | 评分 | 证据 | 结论 |
|---|---:|---:|---|---|
| 数据完整性 | 20% | | | |
| 无未来函数 | 20% | | | |
| 样本隔离 | 15% | | | |
| 测试集稳健性 | 15% | | | |
| 回撤可接受性 | 10% | | | |
| 换手和成本敏感性 | 10% | | | |
| 与研报机制一致性 | 10% | | | |

评分解释:

  • 90 分以上:可作为高可信研究复刻,但仍不是投资建议。
  • 75-89 分:可作为阶段性复刻,需要补数据和做压力测试。
  • 60-74 分:只能作为概念验证。
  • 60 分以下:不应继续讨论策略有效性,应先修数据或协议。

45. 差异归因协议

当本地结果和目标研报差异明显时,Agent 不得直接继续调参,而要先做差异归因。

差异归因优先级:

  1. 样本区间是否一致。
  2. 股票池是否一致。
  3. 数据源和复权口径是否一致。
  4. 财务公告日是否一致。
  5. ST、停牌、涨跌停是否处理一致。
  6. 因子定义是否一致。
  7. 因子标准化和缺失值处理是否一致。
  8. 调仓日和成交价格是否一致。
  9. 交易成本是否一致。
  10. 组合约束是否一致。

输出模板:

## 与目标结果差异归因

| 排名 | 差异来源 | 当前实现 | 目标口径 | 证据 | 影响方向 | 下一步 |
|---:|---|---|---|---|---|---|
| 1 | 股票池 | | | | | |
| 2 | 财务可得性 | | | | | |
| 3 | 可交易约束 | | | | | |

只有当差异归因表完成后,才能进入下一轮迭代。

46. 完成定义

只有同时满足以下条件,Agent 才能说“本轮 Skill 运行完成”:

  1. 数据契约报告已生成。
  2. 样本切分已写入配置。
  3. 基线版本已独立保存。
  4. 候选版本账本已生成。
  5. 验证集保留规则已执行。
  6. 测试集没有被用于自动调参。
  7. 年度收益、关键指标、净值、持仓、换手至少有一种可审计输出。
  8. 图表背后的 CSV 数据已保存。
  9. 已知缺口已写入 known_gaps.md。
  10. 最小下一步已写入 next_iteration_plan.md。

如果其中任一项缺失,Agent 必须说“本轮未完成”,并说明缺失项和最小补救动作。

常见问题

5 问
答案由本站依据条目字段整理
选股策略演化研究系统怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_5fc3c48c/stock-selection-evolution-research-skill。安装方式为未标注。装完刷新技能列表或重开客户端。

选股策略演化研究系统支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

选股策略演化研究系统权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

选股策略演化研究系统收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

选股策略演化研究系统用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。