我没写一行代码,让 AI 跑了 8 年纳斯达克回测:5 个策略,2 个反直觉结论
两句话先抛出来:
- 胜率 100% 的策略,年化只比闭眼买多 2 个点。
- "跌了才买"听起来很聪明,回测下来年化只比"每月固定买"多 0.2 个点。
这篇文章有两条线:
- 财经线:8 年纳指 + 5 个策略 + 反直觉数据
- AI 工具线:我是怎么靠一份"人话需求文档" + 几句"开始干",让 AI 在 30 分钟内跑完整套回测的
不卖课、不带链接、不构成投资建议。先放总表给急性子的人看。
| 策略 | 总收益 | 年化 | 最大回撤 | 交易次数 | 胜率 |
|---|---|---|---|---|---|
| A: All-in 一次性满仓 | 244.37% | 16.82% | -36.40% | 1 | 100% |
| B: 每月定投 $100 | 117.96%¹ | 19.04% (IRR) | -27.23% | 96 | 100% |
| C: 200 日均线右侧交易 | 231.26% | 16.25% | -22.70% | 15 | 40% |
| D: 200MA + 3x 杠杆推演 | 1878.80% | 45.55% | -56.39% | 15 | 40% |
| E: 单日跌 >2% 才买(同口径 vs B) | 116.17%¹ | 19.24% (IRR) | -27.04% | 60 | 98% |
¹ B/E 的"总收益"= (期末市值 − 总投入) / 总投入,与其他策略口径不同,应主要看 IRR。
〇、为什么写这一篇
我是个想搞清楚"定投到底比 All-in 强不强"的普通人。问题是我懒,不想 pip install pandas、不想注册 yfinance、不想 debug strftime。
于是这次我一行代码没敲,全程在 IDE 里和一个 AI Agent 说人话,让它拉了 8 年纳斯达克综合指数日线、跑了 4 个策略的完整回测、输出了一份带胜率/回撤/IRR 的 Markdown 报告。
总耗时大概 30 分钟,期间我做的事就是打字、看结果、提下一个需求。
前半段讲怎么做的(AI 工作流),后半段讲做出了什么(回测结论)。
一、工具栈:三件套,没有一件是付费的
1.1 我用了什么
| 角色 | 用了什么 | 干了什么 |
|---|---|---|
| Agent / 编辑器 | CodeBuddy IDE(Agent 模式) | 跑命令、写脚本、读文件、生成报告 |
| 大模型 | Claude Opus 4.7(在 CodeBuddy 里切的模型) | 理解需求、写代码、解释结果 |
| 数据接口 | westock-data(一个 CLI Skill) | 拉 K 线数据 |
分工很简单:我把"做什么"丢给 AI,AI 自己决定用哪个数据、写什么代码。我只负责验收和提下一个需求。
1.2 为什么是 westock-data,而不是 yfinance / Tushare
这是这次的关键工具,多花两段讲清楚——它有它的好,也有它的坑。
能用的地方:不用注册账号、不用 API key,装好 Skill 即用;一套命令行同时覆盖 A 股/港股/美股/指数/ETF/财务/宏观;输出直接是 Markdown 表格,给 AI 解析的成本几乎为零;数据源是腾讯自选股的接口,行情、K 线、财务三表、资金流向、技术指标、机构评级、新闻公告都有。
坑也得说清楚:
- K 线单次最多 2000 条——这就是为什么样本只能从 2018 年 6 月开始,而不是 2000 年起。日线满打满算约 8 年。
- 美股复权选项相对粗糙(指数本身不分红影响不大,个股要小心)
- 数据源是商业接口,不适合学术级研究,但做"对策略量级有个直觉"够了
- 风险事件、龙虎榜、筹码分布只支持 A 股
search和minute(分时)不支持批量
一句话:个人投研够用,学术研究不够。要回测 1971 年以来的纳指,请换 yfinance 或 Stooq。
1.3 这套工作流的"成本"
| 维度 | 传统做法 | 这次的做法 |
|---|---|---|
| 写代码 | 1~2 小时(解析、回测、画表) | 0 行 |
| 找数据 | 注册 API、配 token、调试 | 1 句话 |
| 出报告 | 自己写 Markdown 排版 | AI 直接产出 |
| 总时间 | 半天 | ~30 分钟 |
| 钱 | 0~99 元(API/订阅) | 0 |
二、我是怎么"提示"AI 的
这一节是给同样想用 AI 干活的朋友看的。没有提示词模板,只有一份白话需求文档。
2.1 我的"需求文档"长这样(58 行原文)
我没用任何 prompt 模板。就是在编辑器里把"我想要什么"写成一份人能看懂的需求文档,存成 回测需求.md,然后丢给 AI 一句:
"用项目已有的工具、数据完成回测需求"
数据源
· 标的:纳斯达克指数
· 周期:日线,尽可能长
· 工具:westock-data
需要跑的数据(基础统计)
1. 区间涨幅:总涨幅、年化收益率
2. 最大回撤:幅度、发生时间、对应前高
3. 单日跌幅分布:>2%、>3%、>4%、>5% 的次数和占比
4. 前 10 大单日暴跌:日期、跌幅
策略模拟(均以一个完整投资区间为准,不考虑税费和滑点)
策略 A:All-in 一次性买入
策略 B:定投(每月 1 日买入 $100)
策略 C:右侧交易(200 日均线)
策略 D:右侧交易 + 3 倍做多
输出格式
不要 JSON,用可读的 Markdown 表格 + 文字结论。
最后加一个四策略对比总表。
不需要的内容
· 不要画图(我没有视觉工具)
· 不要 Monte Carlo / 随机模拟
· 不要分红再投资计算
· 不要税费/手续费
· 不要在结论里给投资建议——只给数据
就这么白话。
2.2 我总结的 3 个"提示词要点"
不是 prompt 模板,是方法论。写多了你会发现,prompt 工程的核心从来不是用什么花哨咒语。
先把"不要什么"写出来。 我明确写了:不要画图、不要 Monte Carlo、不要分红再投资、不要税费、不要给投资建议。这一段直接砍掉了 50% 会被 AI 自作主张加进去的内容。AI 默认会"帮你想周到",这种好心常常是过度设计。列负面清单比列正面需求更省事。
指定输出格式比指定内容更重要。 我写了"不要 JSON,用 Markdown 表格",还给了一张最终总表的模板。AI 直接照着填,没有任何排版上的来回拉锯。
数据口径写死,不留歧义。 "不考虑税费和滑点"——这种话让 AI 不会反复来回问"请问您要不要加 commission?""分红是否再投?"。
2.3 中途我做了什么"补丁"
第一版报告出来后,我看了一眼总表,发现只有策略 C 写了胜率,A/B/D 都没写。
我没改需求文档,也没说「请帮我在 A、B、D 也加上胜率,注意 A 是单笔买入持有,所以胜率定义为……」。我就回了一句:
"把胜率也加进去"
5 个汉字。然后 AI 自己想清楚了每个策略的胜率口径:
| 策略 | 它怎么定义胜率 |
|---|---|
| A 单笔买入持有 | "末值 > 买入价"视为 1 胜 → 100% |
| B 96 次定投 | 每笔买入价 vs 末日收盘价逐批判定 → 96/96 = 100% |
| C 200MA 多段持仓 | 每段开仓→平仓收盘价比较 → 6/15 = 40% |
| D 3x 杠杆版 C | 同样的持仓段,用 3x 复利重算单段收益判定 → 40% |
它还主动在表格下方加了一段口径注释——A=单笔买入持有视末值正负;B=每月定投按"买入价 vs 末日收盘"逐批判定;C=200MA 每段开仓→平仓的收盘价比较;D=与 C 同样的持仓段,但用 3x 日复利重算单段收益判定。
过去你用 Tushare + Jupyter,是你写好每一步代码;现在你用 Agent,是你想清楚要什么。
后面所有数字都来自 AI 生成的那份 90 行 Python 脚本(纯标准库,零第三方依赖)。
三、先看市场本身有多"癫"
3.1 8 年的基本盘
| 指标 | 数值 |
|---|---|
| 区间 | 2018-06-07 ~ 2026-05-21(约 8 年,2000 个交易日) |
| 起点收盘 | 7635 |
| 终点收盘 | 26293 |
| 总涨幅 | 244.37% |
| 年化 (CAGR) | 16.82% |
过去 8 年,闭着眼买都赢。但是——
3.2 中间你要扛住一次"-36.40% 的 13 个月"
| 项目 | 数值 |
|---|---|
| 最大回撤 | -36.40% |
| 前高 | 2021-11-19(16057 点) |
| 谷底 | 2022-12-28(10213 点) |
| 回到前高 | 2024-02-29 |
从顶到底花了 13 个月,从底回到前高又花了 14 个月。整整 27 个月账户上的数字都不太对。
3.3 单日跌幅分布
| 阈值 | 次数 | 占比 |
|---|---|---|
| 单日跌 > 2% | 150 天 | 7.50% |
| 单日跌 > 3% | 58 天 | 2.90% |
| 单日跌 > 4% | 23 天 | 1.15% |
| 单日跌 > 5% | 7 天 | 0.35% |
前 3 大单日暴跌清一色是 2020 年疫情周:
| 日期 | 跌幅 |
|---|---|
| 2020-03-16 | -12.32% |
| 2020-03-12 | -9.43% |
| 2020-03-09 | -7.29% |
一周吃满了近 8 年最惨 Top3。后面 2025-04 那一周(中美关税波动期)的两天 -5.97% 和 -5.82% 也在 Top10 里。
这一节的作用是给后面策略的"心理成本"一个锚:8 年里,你要忍 7 次单日 -5%、150 次 -2% 以上、外加一次长达 27 个月的折返跑。
四、四个策略,逐个拆
4.1 策略 A:All-in 一次性买入——最懒,但不一定最差
第一天满仓,持有到最后一天。
| 指标 | 数值 |
|---|---|
| 初始资金 | $10,000 |
| 期末市值 | $34,437 |
| 总收益率 | 244.37% |
| 年化 | 16.82% |
| 最大回撤 | -36.40% |
| 交易次数 | 1 |
2018 年那个夏天闭眼买,2026 年账户翻 3.4 倍。
代价是:2022 年那一年,你要看着账户从 $16000 跌到 $10000 还不动手。问问自己:能熬过 13 个月持续阴跌不打开账户吗?
4.2 策略 B:每月定投 $100——胜率 100%,但年化只多 2 个点
每个月遇到的第一个交易日买入 $100。
| 指标 | 数值 |
|---|---|
| 总投入(96 个月) | $9,600 |
| 期末市值 | $20,924 |
| 总收益率(盈利/本金) | 117.96% |
| 年化 IRR | 19.04% |
| 最大回撤 | -27.23% |
| 胜率 | 100%(96/96) |
两个反直觉点:
胜率 100%——96 次买入价格全部低于末日收盘价,因为是大牛市末段。但年化 IRR 19.04%,只比 All-in 的 16.82% 多 2.2 个百分点。
为什么?定投本质是在涨的过程中持续摊高成本——钱进入市场的平均时间晚了一半,时间杠杆短了一半。
那定投的真正优势是什么?回撤从 -36% 降到 -27%。换算到账户体感,就是 2022 年那一年看到的浮亏小了将近 1/3。
所以定投不是为了多赚,是为了让你睡得着。
4.3 策略 C:200 日均线右侧交易——胜率 40%,但收益追平 All-in
收盘 > 200 日均线就满仓持有,跌破就全部清仓持现金。T 日收盘判断,T 日收盘成交。
| 指标 | 数值 |
|---|---|
| 期末市值 | $33,126 |
| 总收益率 | 231.26% |
| 年化 | 16.25% |
| 最大回撤 | -22.70% |
| 交易次数 | 15 |
| 胜率 | 40.00% |
全文最反直觉的数据:胜率只有 40%,但收益几乎追平 All-in,最大回撤从 -36% 砍到 -22.70%。
为什么胜率这么低还能赢?看 15 笔交易里赚最多的 3 笔:
| 时间段 | 单笔收益 |
|---|---|
| 2020-04-22 → 2022-01-18 | +70.76% |
| 2023-10-31 → 2025-03-03 | +42.79% |
| 2025-05-12 → 2026-03-13 | +18.16% |
剩下 12 笔大多是 -1%~-3% 的小亏损(伪信号),还有几笔 +5%~+16% 的小赚。9 次小亏 + 6 次盈利,其中 2 次大赚。不指望"次次对",指望"对的时候吃肉"。关键是它躲过了 2022 年那段 -36% 的熊市——9 月跌破 MA 就清仓了。
趋势策略里,胜率不重要,赔率才重要。看到量化策略胜率 40% 就觉得"这不是赌博吗",恭喜,你和大多数人一样掉进了胜率陷阱。
4.4 策略 D:200MA + 3x 杠杆推演(TQQQ)——年化 45%,但你不一定扛得住
在策略 C 的"满仓"区间,用日收益 × 3 复利模拟(推演 TQQQ)。
| 指标 | 数值 |
|---|---|
| 期末净值 | $197,879 |
| 总收益率 | 1878.80% |
| 年化 | 45.55% |
| 最大回撤 | -56.39% |
| 是否触发 -80% 爆仓 | 否 |
| 胜率 | 40% |
$10,000 → $197,879,年化 45.5%。数字很性感,但这是上限,不是真实 TQQQ:波动率衰减没建模(3x ETF 每日重置,震荡市持续吃本金)、融资成本没算(实际 TQQQ 内含 SOFR + 几十 bp 的隐性融资费)、再平衡误差没算。即便砍半,它的实际收益仍然是 4 个策略里最高的。
代价是:2020 年 2 月到 4 月,账户回撤 -56.39%。$10,000 在 2 个月内变成 $4,360。你要在那个时刻不平仓,不卖飞,不打开手机刷新闻。
实操上 90% 的人在这种回撤里会自己止损跑路。这个 1878% 的数字,99% 的人是吃不到的。
4.5 策略 E:单日跌 >2% 才买——逢低买入听着聪明,实际呢?
这条策略是写文章过程中我自己冒出来的念头,模拟一个读者反应:
"前面统计里看到 8 年有 150 天跌幅超过 2%。我能不能不要每月固定时间买,专门挑这种大跌日买?是不是收益会更高?"
听起来很直觉对吧。毕竟"逢低买入"是投资圈最经典的口号之一。
我跑了 3 个变体,核心对比留给 E3(与策略 B 完全同口径,月度预算 $100,差别只在"何时投出去"):
| 变体 | 策略 | 总投入 | 终值 | 年化 IRR | 最大回撤 | 买入次数 |
|---|---|---|---|---|---|---|
| 基线 | B 每月固定 | $9,600 | $20,924 | 19.04% | -27.23% | 96 |
| 同口径对比 | E3 跌了才买(现金桶) | $9,600 | $20,752 | 19.24% | -27.04% | 60 |
| 参考 | E1 跌了才买(每次 $63) | $9,450 | $21,830 | 20.15% | -20.21% | 150 |
| 参考 | E2 跌了才买(每次 $100) | $15,000 | $34,651 | 20.15% | -20.21% | 150 |
E3 的玩法:每月把 $100 放进一个"现金桶"等着,只要某天单日跌幅 > 2%,就把当前桶里所有钱一次性砸进去。这样保证 8 年总投入 = B 的 $9,600,唯一变量是"何时投出去"。
结果让我自己也愣了一下:E3 的 IRR 是 19.24%,B 的 IRR 是 19.04%,差 0.20 个百分点。把"机械地每月 1 号买"换成"专门挑暴跌日买",8 年下来年化只多赚 0.2 个点。最大回撤:-27.04% vs -27.23%,只少了 0.19 个百分点。
为什么"逢低买入"不香?三个原因:
- 8 年只有 150 个">2% 跌幅日",平均 19 次/年,但你 8 年要等的钱总共就 $9600。两种方式最终都把钱投进了同一个长期上涨的市场。
- 暴跌日和"市场底部"不是一回事——单日跌 2% 的日子绝大多数不在阶段底部。2020-03-09 暴跌 7.29%,第二天还跌;2022 年从 -36% 跌到底之前,路上一连暴跌过 4 次。
- 机会成本:拿着现金等暴跌的时候,市场可能已经默默涨了 6%。错过 6% 的上涨,比抄到 2% 的底要贵。
E1/E2 看起来更香(IRR 20.15%、MDD -20.21%),但它们和 B 不是同一个游戏:E1 的 8 年总投入 $9,450 不固定;E2 最后投了 $15,000,比 B 多投了 56% 的本金。本金更多、终值更大,但 IRR 和 E1 完全相同,只是规模放大。"E1/E2 看起来好"是因为偷偷加大了本金投入或挪动了时点,不是"逢低"这个动作本身的功劳。同口径的 E3 几乎跑不出 B 的水平。
顺便戳破一个流行说法:「定投不如逢低买入」——8 年里它们的差距,比一次 5% 的单日波动还小。
附带一个发现:E3 只交易 60 次(B 是 96 次),节省了一半的交易频次。如果你的券商有交易成本/最低手续费,E3 反而可能略胜。但这是"少交易"的功劳,不是"逢低"的功劳。
五、五策略对比总表 + 反直觉解读
| 策略 | 总收益 | 年化 | 最大回撤 | 交易次数 | 胜率 |
|---|---|---|---|---|---|
| A: All-in | 244.37% | 16.82% | -36.40% | 1 | 100% |
| B: 月度定投 | 117.96%¹ | 19.04% (IRR) | -27.23% | 96 | 100% |
| C: 200MA 右侧 | 231.26% | 16.25% | -22.70% | 15 | 40% |
| D: 200MA + 3x | 1878.80% | 45.55% | -56.39% | 15 | 40% |
| E3: 跌 >2% 才买(同口径 vs B) | 116.17%¹ | 19.24% (IRR) | -27.04% | 60 | 98% |
- 胜率是心理护城河,不等于赚钱能力。A、B、E 胜率都接近 100%,但年化彼此差距只有 1~2 个点;C 的胜率 40%,但年化追平 A、回撤砍半。
- 最浅回撤归 200MA:全场最低 -22.70%,比 All-in 少 14 个百分点。这部分省下来的浮亏,换算成账户体感是很大的。
- 最高年化不等于最佳策略。D 的 -56% 回撤会让 90% 的人提前跑路,纸面收益不是你能拿到的真实收益。
- "逢低买入"不是免费午餐。E3 用了 8 年时间,只比 B 多赚 0.2 个百分点,真正的差异来自"少交易了 38%"——这是纪律奖,不是择时奖。
- 样本只有 8 年,且全程偏多头。没经历 2000 互联网泡沫(-78%)、2008 金融危机(-55%)这种长熊;200MA 在长震荡市会被反复打脸。
六、必须坦白的局限
知乎不写这段会被怼到自闭。
- 样本期太短——只有 8 年,且全程是大牛市背景。换到 2000-2010 这十年,200MA 是输给 All-in 的。
- 3x 模拟是上限——衰减、融资、再平衡误差都没建模。实际 TQQQ 的长期收益会偏离理论值 30%~50%。
- 不计税费/滑点/分红再投——美股长期股息约 1.5%/年,复利 8 年差距会拉大。频繁交易(C/D 各 15 次)的实际成本被低估。
- "过去 ≠ 未来"——同一个 200MA,2018-2026 跑赢 All-in,不代表 2026-2034 也跑赢。
- AI + westock-data 的天然限制:腾讯自选股的指数数据在 2018 年部分日期 volume 字段为 0,策略 C/D 不依赖成交量所以无影响,但其它策略要警惕。AI 不会主动质疑数据,你给它什么它就跑什么,数据脏了它不知道,人工要做最后一道质检。跑"5 个策略 + 基础统计"很顺,但要做参数寻优、Walk-forward、组合优化,仍然得写正经代码。
七、双线收尾
给财经党读者:
策略没有最好,只有最贴你性格的那一种。你能扛多深的回撤,决定了你能用多激进的策略。
在按下任何一个买入键之前,先问自己:
- 你能在 13 个月持续阴跌里不打开账户吗?(决定能不能用 A)
- 你是觉得"不亏就好",还是"想跑赢指数"?(决定 B 还是 C)
- 你能接受账户两个月内腰斩吗?(决定要不要碰 D)
- 你愿意为了多赚 0.2 个点的年化,多花 8 年精力盯着每日跌幅吗?(决定 B 还是 E)
给 AI 工具党读者:
真正打开 AI 协作生产力的不是更牛的提示词模板,是把人话需求写清楚的能力。
这次什么模板都没用:58 行白话需求文档 + 一句"开始干",活就完成了。中途想加新指标?"把胜率也加进去",5 个汉字。想加一个新策略?"单日跌幅超过 2% 就定投一份,跑一下",一句话。
AI Agent 时代,最稀缺的技能不是 prompt engineering,是 product thinking:把模糊的"我想看看"翻译成具体的指标和口径,把"我不要什么"列得比"我要什么"更清楚,把验收标准前置成输出格式。
附:本文用到的工具与数据
- 数据源:westock-data(腾讯自选股 CLI)
- 大模型:Claude Opus 4.7(在 CodeBuddy IDE 里切换)
- 代码量:1 个 90 行 Python 脚本(纯标准库,零依赖),全部由 AI 生成
- 总耗时:约 30 分钟(含一次"加胜率"的迭代)
- 总花费:0 元
本文不构成任何投资建议。回测基于历史数据,结果不代表未来表现。