初始提交:高股息策略研究与回测系统

从 Point-in-Time 股票筛选到统一 Web 前端的完整链路:
筛选 → 画像 → 策略 → 回测 → Walk-forward → 绩效分析 → 报告/前端。

架构
- 数据层与策略层分离;策略代码不写 SQL,只经 data/repo.py 取数
- 所有业务阈值集中在 config/*.yml,代码零硬编码(字段写错直接报错)
- 报告只做「run_id → SQL → 渲染」,不做任何计算,数字可追溯
- 前后端分离:output/ 静态站点 + hdiv web 提供的 REST API

数据安全
- 只增不删:SQL 钩子拦截 DELETE/DROP/TRUNCATE,并有源码扫描测试守护
- qlib 原有表只读,本项目数据写入 hd_ 前缀表
- 回补使用 INSERT IGNORE,保证既有行零改动
- .env 存密钥且已 gitignore;output/、logs/、.venv/ 不入库

交付物
- 30 张 hd_* 表、7 个 YAML 配置、283 项自动化测试
- 统一 Web 前端(hash 路由 SPA)+ nginx 部署配置与 launchd 托管脚本

如实声明的限制
- 策略缺少稳定的样本外超额收益(Walk-forward 7 窗口均值 -0.95%,
  基准 +2.29%);其价值体现在回撤控制,而非超额收益
- 涨跌停/停牌约束仅覆盖 2019 年起;index_weight 尚未填充
- AI Agent 层(plan.md 第四版 P8)未实现

详见 docs/user-guide.md 与 docs/implementation-status.md。
This commit is contained in:
2026-10-03 13:54:56 +08:00
commit fce725e13c
127 changed files with 28001 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
# ============================================================
# 报告与图表输出配置(★ 可直接修改)
# 对应 plan.md §33/§34:K线与交易点、策略研究页面
# 约定:固定格式 HTML,单文件自包含,离线可开,无 CDN 依赖
# ============================================================
version: 1
templates_dir: templates
output_dir: output
assets_dir: assets
theme: light # light | dark | auto
offline_assets: true # 禁止 CDN;图表库必须来自本地 assets/
# 图表库引用方式:
# shared —— 输出 output/assets/echarts.min.js 并相对引用(默认,体积小、生成快)
# inline —— 直接内联进每个 HTML(单文件可携带,但每份约 +1MB)
asset_mode: shared
include_sql_provenance: true # 页脚展示数据来源 SQL + run_id,便于复现
# ------------------------------------------------------------
# 图表开关(plan.md §33 的四联图 + §28 的绩效图)
# ------------------------------------------------------------
charts:
# 个股页:K线 / 股息率 / PE / PB / 回撤 共享 X 轴四联图
kline_signals: true
# 回测页
equity_curve: true
drawdown: true
yearly_returns: true
monthly_heatmap: true
rolling_metrics: true
sector_exposure: true
position_weights: true
# 画像页
yield_percentile: true
yield_histogram: true
financial_trend: true
# 研究页
sensitivity_heatmap: true
walkforward_compare: true
# ------------------------------------------------------------
# 固定输出命名(可预测路径)
#
# 注意:静态报告统一输出到 reports/ 子目录,与统一前端(output/index.html
# + output/app/)分离 —— 站点根只保留前端入口,避免几十份报告平铺在一起。
# 资源引用(assets/echarts.min.js)会按子目录深度自动补 ../。
# ------------------------------------------------------------
# 文件名一律带执行 id:同一天用同一 asof 跑多次会产生多条数据库记录,
# 若文件名只按 asof 命名,后一次会覆盖前一次的报告,与「每次运行都留痕」矛盾。
# 注意:index 是「静态报告目录的索引」,必须放在 reports/ 下。
# 站点根 output/index.html 归统一前端(web/index.html)所有 ——
# 早期把两者都指向 index.html,导致跑一次 `audit --html` 就把前端首页覆盖成静态索引。
naming:
index: "reports/index.html"
audit: "reports/data_audit_{date}.html"
universe: "reports/universe_{asof}_{run_id}.html"
profile: "reports/profile_{symbol}_{asof}_{run_id}.html"
backtest: "reports/backtest_{run_id}.html"
walkforward: "reports/walkforward_{wf_id}.html"
sensitivity: "reports/sensitivity_{sens_id}.html"
# 注:策略说明报告(plan.md §36)属第四版扩展(P8),尚未实现,
# 因此不在此声明命名 —— 配置不应承诺不存在的产物。
# ------------------------------------------------------------
# 页面排版参数
# ------------------------------------------------------------
layout:
# 内容最大宽度(px)
max_width: 1440
# 表格分页大小
table_page_size: 100
# K 线默认展示天数
kline_default_days: 1500
# 净值曲线是否归一化到 1.0
normalize_nav: true
# 数值小数位
decimals:
ratio: 4
money: 2
price: 2