13-定投回测方法论与结果
基于本地数据库的历史行情与估值分位,对比"简单定投"与"估值分位定投"两种策略的长期收益。回测脚本:backtest_dca.py,数据来源:05-数据库。
回测快照时间:2026-07-15 数据库最新交易日:2026-07-14
一、回测方法论
1.1 设计原则
回测遵循 数据库概览 中"回测在终点段 02-定投策略研究 内完成"的边界:
- 数据库只提供数据:从
index_daily与index_valuation表读取行情和 PE 历史分位 - 回测逻辑在 Python 中执行:扣款、累计份额、计算收益等步骤不进入 SQL
- 不写入数据库:回测结果仅用于策略选型,不污染行为数据表(
decision_log等留给真实决策)
1.2 策略定义
估值分位定投的倍数映射,与 06-定投决策查询 中的信号生成逻辑保持一致:
分位缺失的月份按 1.0x 正常定投处理,避免数据缺失导致策略中断。
1.3 回测参数
1.4 回测标的
只选取同时具备完整日线与估值数据、历史深度达 10 年的标的:
未纳入回测的标的及原因:
二、回测结果
2.1 逐标的对比
000016 上证50(2016-07-18 ~ 2026-07-14,121 个月)
000852 中证1000(2016-07-18 ~ 2026-07-14,121 个月)
000905 中证500(2016-07-18 ~ 2026-07-14,121 个月)
2.2 三只标的汇总
三、结论与局限
3.1 结论
-
估值分位定投在三只标的上都跑赢简单定投。10 年周期内,累计超额收益 +3.70% ~ +5.67%,年化超额 +0.34% ~ +0.47%。这印证了 00-定投策略总览 中"估值定投、低估加倍、高估暂停"策略的有效性。
-
估值定投的优势主要来自"高估暂停"。上证50 的估值定投跳过了 34 个月(占 28%),避开了高估阶段的回撤;中证1000 与中证500 分别跳过 9、15 个月,同时低估加倍又增加了投入。两种机制共同贡献了超额收益。
-
不同指数的定投收益差异主要由指数本身表现决定。中证500 > 中证1000 > 上证50 的排序在两种策略下都一致,说明定投策略的 α(超额)建立在指数 β 之上。策略优化不能弥补选错标的的代价。
-
绝对收益水平偏低。10 年年化 0.77% ~ 3.80%,与 00-定投策略总览 中 "A 股年化预期 5-10%" 的区间相比偏低,反映了 2016-2026 区间 A 股宽基整体震荡的特征。这也佐证了路线图把纳指100 作为第一大仓位(20%)的配置逻辑。
3.2 局限
3.3 对实盘的启示
-
估值定投的纪律性比单次择时更重要。回测中估值定投的优势来自系统性地"高估不买",而不是某一次精准逃顶。实盘中应让倍数映射固化在扣款流程里,避免人工干预。
-
暂停月不是"错失机会"而是"等更好的价格"。上证50 的 34 个暂停月看似很多,但最终年化反而更高。实盘中遇到暂停信号时,应按纪律执行,而不是因为"已经涨了"就追进去。
-
策略验证需要持续复盘。本次回测是 2016-2026 的历史样本,未来市场结构可能变化。建议每季度用 06-定投决策查询 的查询接口重新跑一次回测,对比"策略预期 vs 实际表现",写入 04-季度复盘。
-
实盘决策应写入
decision_log。回测结果支撑策略选型,实盘开始后,每次扣款都应通过 07-行为数据查询 写入decision_log,记录决策时的 PE 分位快照,后续用同一套查询接口做"决策命中率"复盘。
四、如何复现
4.1 前置条件
- 数据库已建库并灌入历史数据:
- 依赖已安装:
pandas(已在05-数据库/02-数据脚本/requirements.txt中声明)
4.2 运行回测
4.3 扩展回测
如需增加标的或调整策略参数,修改 backtest_dca.py:
- 增加标的:在
main()的default_targets列表中添加,前提是该指数在数据库中同时有完整日线与估值数据 - 调整倍数映射:修改
valuation_multiplier()函数的阈值与返回值 - 增加止盈逻辑:在
backtest_valuation()的循环中加入"累计收益超阈值则止盈"分支
相关文档
- 00-定投策略总览 - 定投策略的整体框架与资产配置
- 12-定投止盈止损具体策略 - 止盈止损规则
- 05-数据库/04-查询接口/06-定投决策查询 - 定投信号与回测函数的查询接口
- 05-数据库/01-数据方案设计/02-数据架构与表结构设计 - 表结构定义