# 高股息回测系统 A 股 **高股息 + 安全边际 + 估值均值回归** 策略的研究与回测系统。 从 Point-in-Time 股票筛选 → 个股特性画像 → 策略定义 → 历史回测 → Walk-forward 样本外验证 → 绩效与敏感性分析 → **统一 Web 前端**,全链路打通。 采用**前后端分离**:前端为 `output/` 下的单页应用(hash 路由,nginx 直接托管), 后端为 `hdiv web` 提供的 REST API(nginx 反代 `/api`)。 --- ## 快速开始 ```bash cd ~/project/高股息回测 cp .env.example .env # 填入数据库密码与 Tushare token export PYTHONPATH=src # 建表 .venv/bin/python -m hdiv ddl apply # 同步数据(首次约 3~4 小时,可后台跑) .venv/bin/python -m hdiv sync dividend --only-missing .venv/bin/python -m hdiv sync financial --interleaved --only-missing .venv/bin/python -m hdiv sync index .venv/bin/python -m hdiv sync trading --start 2019-01-01 # 审计 → 打开 output/index.html .venv/bin/python -m hdiv audit ``` 完整用法见 **[使用手册](docs/user-guide.md)**。 --- ## 文档 | 文档 | 内容 | |---|---| | **[使用手册](docs/user-guide.md)** | 安装、配置、命令、报告解读、故障排查 | | [实施状态](docs/implementation-status.md) | 交付清单、验收映射、已修复问题、**实测结论与限制** | | [开发计划](docs/development-plan.md) | 架构设计、数据库设计、分阶段计划 | | [需求原文](docs/plan.md) | 项目的原始方案与验收标准 | --- ## 目录 ```text config/ ★ 所有可调参数(YAML,代码零硬编码) src/hdiv/ 代码:数据层、筛选、画像、策略、回测、分析、报告 templates/ HTML 模板(Jinja2,离线) assets/ 图表库(ECharts,本地化,不依赖 CDN) output/ ★ 报告输出(部署这个目录) sql/ 建表 SQL 副本(供人工审查) tests/ 262 项自动化测试 docs/ 文档 ``` --- ## 三条设计原则 | 原则 | 落实方式 | |---|---| | **配置零硬编码** | 任何业务阈值只出现在 `config/*.yml`;字段名写错直接报错 | | **只增不删** | SQL 钩子拦截 `DELETE`/`DROP`/`TRUNCATE`;源码扫描测试守护 | | **无未来函数** | 所有取数必经 `data/repo.py`,PIT 纪律有负例测试 | --- ## 重要提示 **本系统的实测结论是:策略没有稳定的样本外超额收益。** 全期回测(2015–2026)显示 +92.73% / CAGR 5.75%, 但 7 窗口 Walk-forward 的样本外收益均值仅 **+1.16%**(基准 +2.29%,超额 **−1.12pp**)。 它真正的价值在于**回撤控制**(样本外最差 −22.97%,基准同期 −46%~−52%)—— 更像降低波动的配置工具,而非超额收益来源。 > **四条必须说的结论**(详见[实施状态 §4.6c/§4.6d/§9](docs/implementation-status.md)): > > 1. **修数据让结果变差、但变真实了。** 行情原先只到 2015-01-05, > 使「过去 5 年」窗口在 2019 年前被静默截短(覆盖率仅 20%~67%)。 > 2026-10-04 已把行情回补到 **2005-01-04**、涨跌停/停牌到 **2010**, > 5 年窗口覆盖率提升到 **98.7%~100%**。代价是全期收益从 +117.36% > 降到 **+92.73%** —— 因为 **2015 年(牛市顶 + 股灾)从「被数据缺口 > 挡住」变成被真实交易(−3.18%)**。靠数据缺口躲过股灾不是策略能力。 > 2. **实时画像闸门在两个口径下结论相反**: > 单条路径 **−8.47pp**(有害),样本外 **+1.16pp**(有益)。 > > | 口径 | 闸门开 | 闸门关 | > |---|---:|---:| > | 全期单路径总收益 | +92.73% | **+101.20%** | > | Walk-forward 样本外均值 | **+1.16%** | −0.00% | > | 样本外最差回撤 | **−22.97%** | −24.22% | > > **按本项目一贯立场以样本外为准**:闸门是改善。是否启用由你决定 > (`entry.profile_gate.enabled`);全期剔除 1027 次买入信号。 > 3. **同一项数据修正,在两个口径下的「效果」相差 32.9pp** > (回补对样本外贡献 **0** —— 7 个窗口逐窗口未变;对单路径贡献 −32.9pp)。 > 这是「不要采信单条路径」最有力的例证。 > 4. **`stock_daily` 的量价单位曾前后不一致**(2015-2019 存「手/千元」, > 2020 起存「股/元」),使流动性门槛在早年低估 1000 倍、**把 2015-2019 > 的股票池整体清空**。已修复(读取层幂等归一化 + 审计 `UNIT-OHLCV` 防回归)。 **请始终以 Walk-forward 的样本外结果为主要依据,不要采信单条路径的全期数字。** 详见[实施状态 §4.6](docs/implementation-status.md)。 --- ## Web 部署(前后端分离) ```bash # 1) 归一化站点目录(归档历史 + 同步前端) .venv/bin/python -m hdiv site normalize # 2) 本地预览 ./deploy/serve.sh start-dev # http://127.0.0.1:8099/ # 3) 生产:同步前端 + 启动后端(仅 API) rsync -av --delete output/ user@host:/srv/hddiv/site/ ./deploy/serve.sh start # 监听 127.0.0.1:8099 --api-only ``` nginx 需做两件事:托管 `output/`、把 `/api` 反代到后端。 配置模板见 **[deploy/nginx.conf.example](deploy/nginx.conf.example)**(含子路径与站点根两种布局)。 验证: ```bash curl http://:8080/ggx/api/health # 应返回 {"ok": true, ...} ``` 浏览器打开首页后,右上角应显示 **「API 正常」**;若显示「API 不可用」, 说明 nginx 的 `/api` 反代未生效。 > 静态报告(`output/reports/`)通过相对路径引用 `assets/echarts.min.js`, > 因此部署时**必须整体同步 `output/` 目录**,不能只拷 HTML。 > > 静态报告是**导出件**,默认不生成(SPA 已提供同样内容)。需要离线单文件快照时 > 加 `--html` 导出,文件名带 run_id,同一天多次运行不会互相覆盖。 --- ## 测试 ```bash .venv/bin/python -m pytest tests/ -q ``` 覆盖:配置校验(含 18 类非法配置必须被拒)、SQL 安全约束、表结构幂等性、 单位换算与量级检测、PIT 纪律、分红口径、回测资金对账、参数阶梯、CLI 接口契约。