# 实施状态报告 > 对应 `docs/development-plan.md`(计划)与 `docs/plan.md`(需求) > 更新:2026-10-02 --- ## 0. 一句话结论 **系统已端到端可运行**:从 Point-in-Time 股票池筛选 → 个股画像 → 策略定义 → 回测 → Walk-forward → 绩效分析 → 参数敏感性 → 固定格式 HTML 报告, 全链路打通并通过 403 项自动化测试。`plan.md §50` 的 14 项验收能力**全部具备**。 **2026-10-03 完成三项正确性改造**(详见 §9):修复 `stock_daily` 量价单位不一致、 拒绝「用未来时点的股票池跑更早区间」、新增**实时(PIT)个股画像闸门**。 三项都让「交易依据更符合实际」,且在 walk-forward 样本外口径下**都改善了绩效** (样本外均值 −0.95% → **+1.16%**,最差回撤 −24.62% → **−22.97%**; 2026-10-04 又把行情回补到 2005,样本外逐窗口未变、单路径则从 +117.36% 降到 +92.73%), 但**仍未取得正超额**(−1.12pp)。 数据层已补齐:行情/每日指标/复权因子覆盖 **2005-01-04 起**, 停牌与涨跌停价覆盖 **2010-01-04 起**,分红 1990 起、四张财报表 1990/2001 起。 审计 `FAIL=0`(14 OK / 5 WARN,WARN 均为已知且已声明)。 --- ## 1. 已交付清单 ### 1.1 数据层(P0a / P0b / G1–G6) | 缺口 | 状态 | 实测结果 | |---|---|---| | **G1 分红明细** | ✅ 完成 | `hd_dividend` 5,880 只 / 267,295 行,覆盖 1990–2026 | | **G2 日线行情** | ✅ 完成 | `stock_daily` **起点 2005-01-04**(2026-10-04 回补,+3,927,792 行),16,007,169 行 / 5,265 个交易日 | | **G2b 复权因子** | ✅ 完成 | `adjust_factor` 同区间,16,789,137 行 / 5,267 个交易日 | | **G3 每日指标** | ✅ 完成 | `daily_basic` 起点 **2005-01-04**(+4,309,461 行),15,972,821 行 / 5,275 个交易日 | | **G4 扩展财务** | ✅ 完成 | 财务指标 5,903 只(100%)、现金流 5,893、资产负债表/利润表 5,902;公告日齐全率 100%。缺失的 10 只均为 1990 年代退市股(Tushare 无报表) | | **G5 基准指数** | ✅ 完成 | `hd_index_daily` 7 个指数 / 40,083 行;沪深300 覆盖 2002 起 | | **G6 停牌/涨跌停** | ✅ 完成 | `hd_suspend` **468,388 行**、`hd_limit` **14,837,155 行**,均覆盖 **2010-01-04** 起(2026-10-04 回补,各 +400,623 / +5,787,253 行) | ### 1.2 数据库(30 张 `hd_*` 表) 全部建表完成,结构迁移幂等(连续两次 `ddl apply` 均返回 0 个动作)。 **只增不删**由三层保证:SQL 安全钩子 + 源码扫描测试 + 迁移的前置条件守卫。 ### 1.3 代码模块 | 模块 | 文件 | 状态 | |---|---|---| | 配置层 | `core/config.py`(7 类配置 + 严格校验 + config_hash) | ✅ | | 数据安全 | `data/db.py`(SQL 钩子)、`data/ddl.py`(幂等 DDL) | ✅ | | 单位归一化 | `data/units.py`(万元/万股/百分数 → 元/股/小数) | ✅ | | PIT 取数 | `data/repo.py`(唯一取数出口) | ✅ | | 同步器 | `data/sync/`(分红/财报/指数/行情/停牌涨跌停) | ✅ | | 数据审计 | `data/audit.py`(15 项检查,含量价单位一致性) | ✅ | | 股票池 | `universe/selector.py` + 4 个 Filter | ✅ | | 因子 | `factor/dividend_yield.py` | ✅ | | 个股画像 | `profile/builder.py` | ✅ | | 策略管理 | `strategy/registry.py` | ✅ | | 回测引擎 | `backtest/engine.py` | ✅ | | Walk-forward | `backtest/walk_forward.py` | ✅ | | 绩效分析 | `analysis/performance.py` | ✅ | | 敏感性 | `analysis/sensitivity.py` | ✅ | | 报告渲染 | `report/`(7 类报告 + 离线校验) | ✅ | --- ## 2. `plan.md §50` 十四项验收 | # | 能力 | 状态 | 落库位置 | |---|---|---|---| | ① | 找出符合条件的股票 | ✅ | `hd_universe_member` | | ② | 生成 PIT 股票池 | ✅ | `hd_universe_run` | | ③ | 每股历史股息率序列 | ✅ | `hd_profile_series` | | ④ | P10/P25/P50/P75/P90 | ✅ | `hd_profile_stat` | | ⑤ | 生成买卖信号 | ✅ | `hd_backtest_signal` | | ⑥ | 执行历史回测 | ✅ | `hd_backtest_run` | | ⑦ | 正确处理分红与除权 | ✅ | `hd_dividend` + 分红台账(含红利税) | | ⑧ | 加入交易成本 | ✅ | `hd_backtest_trade.*_cost` | | ⑨ | K线 + 买卖点 | ✅ | `output/profile_*.html`(四联图 + P75/P25 阈值线) | | ⑩ | 收益/回撤/Sharpe | ✅ | `hd_backtest_metric` | | ⑪ | 基准比较 | ✅ | 沪深300 / 中证红利 / 上证指数 | | ⑫ | Walk-forward | ✅ | `hd_walkforward_window` | | ⑬ | 样本内/外结果 | ✅ | `hd_backtest_metric.scope` | | ⑭ | 完整参数与版本 | ✅ | `hd_strategy` + `hd_strategy_param`(36 项) | --- ## 3. 关键正确性保障 以下是开发过程中**真实踩到**并已修复的静默错误 —— 它们共同特点是「不报错,只是给出错误结论」,因此每一条都配了回归测试。 | # | 问题 | 后果 | 修复 | |---|---|---|---| | 1 | Tushare `total_mv` 单位是**万元**,配置阈值是**元** | 市值过滤选中 **0 只**股票 | `data/units.py` 统一归一化 + `UNIT` 审计(恒等式 + 绝对量级双判据) | | 2 | 用**季报累计** ROE 比「年均 8%」阈值 | 几乎所有好公司被误杀 | `annual_financial_averages()` 只用年报口径 | | 3 | 银行负债率天然 90%+ | 整个金融板块被误杀(招商银行) | `industry_exemptions` 行业豁免,Risk/Quality 统一口径 | | 4 | 年度分红除权间隔中位数 **366 天** > 365 | 股息率被算成 0,污染历史分位 | TTM 加 45 天宽限期 | | 5 | 分红除权晚于 asof | 稳定分红公司被误判「连续分红 0 年」(中国神华) | 一年宽限期 | | 6 | `NaN or 0.0` 返回 `NaN` | 10 万条 NULL 分红被当成数值参与者 | `_fnum()` NaN 感知转换 | | 7 | 费率 side 配置小写 `sell`、代码传大写 `SELL` | **印花税永远为 0**,成本系统性低估 | 统一大写比较 | | 8 | 净值曲线漏加现金 | 净值严重失真 | `总市值 = 现金 + 持仓` + 断言测试 | | 9 | 建仓阶梯与减仓阶梯各自判定 | 持仓时会「因高分位被减仓」,年换手 8.9、持仓仅 30 天 | 合成唯一阶梯 + 死区(修复后:换手 0.91、持仓 345 天) | | 10 | MySQL 唯一约束**不约束 NULL** | 静默重复行 | 显式 `dedup_key`;三张表补 `NOT NULL`;专门测试守护 | | 11 | pandas 3.0 字符串列不再是 `object` dtype | 空串 `ts_code` 被写进库 | 改用 `is_numeric_dtype` 判定 | | 12 | `is_buy` 在涨跌停分支前未定义 | 一旦 `hd_limit` 有数据即崩溃 | 定义提前 | | 13 | Jinja2 autoescape 转义 `