编程学习网 > 编程语言 > Python > 一个 MACD 指标竟跑赢了买入持有策略?用 Python 带你复现 23 年回测
2026
04-21

一个 MACD 指标竟跑赢了买入持有策略?用 Python 带你复现 23 年回测


在量化交易的世界里,技术指标多如牛毛,但真正经得起长期回测检验的却寥寥无几。最近,一篇关于 MACD(Moving Average Convergence Divergence,移动平均收敛/发散指标)交叉策略的文章引起了广泛关注——作者仅用最经典的 MACD 默认参数,在 Nexstar Media Group(NXST)这只股票上进行了长达 23 年的回测,最终策略总回报率高达 7174%,而同期买入持有的回报率仅为 1760%

听起来不可思议?别急,这篇文章将带你一步步拆解这个策略的核心逻辑、Python 实现代码,以及作者本人都坦诚指出的那些"还不能下结论"的原因。

什么是 MACD?

MACD 由 Gerald Appel 在 20 世纪 70 年代末提出,至今仍是全球使用最广泛的动量指标之一。它的计算逻辑非常简单:

  1. 1. 用一条快速指数移动平均线(EMA)减去一条慢速指数移动平均线,得到 MACD 线;
  2. 2. 对 MACD 线再做一次 EMA 平滑,得到信号线(Signal Line);
  3. 3. 当 MACD 线从下方穿越信号线(金叉),视为买入信号;当 MACD 线从上方穿越信号线(死叉),视为卖出信号。

本文测试的参数是 Appel 最初发表的默认值:快速 EMA 为 12,慢速 EMA 为 26,信号线 EMA 为 9。

策略规则

整个策略只有两条规则:

  • • 入场:当 MACD 线上穿信号线,在下一个交易日的开盘价买入。
  • • 出场:当 MACD 线下穿信号线,在下一个交易日的开盘价卖出。

没有价格目标,没有止损,只看交叉信号。信号在收盘时计算,但在次日开盘时执行,这样做是为了避免"未来函数"(look-ahead bias),确保系统不会用到实际交易中无法获取的信息。

Python 实现代码

整个回测基于 vectorbt 和 yfinance 两个开源 Python 库。数据为 NXST 的日线 OHLCV 数据,来源于 Yahoo Finance,时间跨度从 2003 年 11 月至 2026 年 4 月。

第一步:获取数据


第二步:计算 MACD 并生成交易信号


第三步:执行回测


第四步:对比买入持有基准



	

回测结果一览

以下是 MACD 策略与买入持有策略的核心指标对比:

指标 MACD 策略 买入持有
总回报率 7174% 1760%
最大回撤 68% 97%
总交易次数 214 1
胜率 41%
利润因子 1.47
Sharpe 比率 0.77 0.62
Sortino 比率 1.26 1.00
平均盈利交易 +13.27%
平均亏损交易 -4.63%

亮点解读

最大回撤的改善最为显著。 买入持有 NXST 意味着你需要忍受 97% 的最大回撤——几乎血本无归。而 MACD 策略将这一数字降低到了 68%。虽然 68% 仍然很高,但"亏掉三分之二"和"亏掉全部"之间的差距,无论在财务上还是心理上都意义重大。

41% 的胜率不是缺陷,而是趋势跟踪策略的典型特征。 策略靠的是"亏损时亏得少,盈利时赚得多"——平均每笔盈利 13.27%,平均每笔亏损仅 4.63%。用作者的话说:

41% 的胜率不是 Bug,而是趋势跟踪的 Feature。策略靠"便宜地犯错、昂贵地正确"来赚钱。


为什么这个结果还不能直接用?

作者在文中坦诚地指出了几个重要的局限性,这也是所有量化学习者必须重视的:

1. 单一股票的幸存者偏差

NXST 是一只从 2003 年存活至今、且大幅上涨的股票。但 2003 年存在的股票中,还有数百家公司破产、退市或永久性地亏损了 90% 以上。在一只"幸存者"身上跑出好成绩,并不等于策略本身有效。

2. 参数拟合风险

12/26/9 是全世界被测试次数最多的 MACD 参数组合。正因如此,市场可能已经围绕这些参数进行了"适应"。而且这些参数在历史数据上表现最佳,可能只是噪音的结果,而非真正的优势。

3. 单一连续时间窗口

从 2003 年到 2026 年的回测恰好覆盖了美股长达数十年的牛市。策略受益于这个市场环境。真正的考验在于它能否在衰退、长期横盘、高波动震荡等不同市场状态下存活。


还需要做哪些验证?

作者提出了四个关键的后续测试:

步进优化(Walk-Forward Optimization)

将历史数据分成滚动的"样本内"和"样本外"窗口。仅在样本内优化参数,然后在样本外严格评估表现。如果样本外表现大幅下滑,说明样本内结果很可能过拟合。

蒙特卡洛模拟(Monte Carlo Simulation)

随机打乱历史交易的顺序,模拟数千条权益曲线。这揭示了可能结果的分布——包括历史路径恰好避开的最差序列。

参数敏感性分析(Parameter Sensitivity)

绘制收益热力图,观察快速 EMA、慢速 EMA 和信号线周期在测试值附近变化时的表现。真正的优势应该产生一个宽阔的正收益平台,而非一个被差结果包围的尖锐峰值。

市场状态分析(Regime Analysis)

将回测拆分为牛市、熊市、横盘震荡、高波动等子区间,分别观察策略表现。如果策略只在持续上涨中有效,那它本质上只是"带额外步骤的加杠杆做多"。


总结

这篇文章展示了一个极简的 MACD 交叉策略——没有滤波器、没有止损、没有任何复杂逻辑——在 NXST 上 23 年回测中取得了 72 倍的资金增长(扣除手续费和滑点后)。这一结果远超买入持有的表现,同时显著降低了最大回撤。

然而,作者自己也强调,这只是一个起点。在真正投入真金白银之前,步进优化、蒙特卡洛模拟、跨标的验证和参数敏感性分析是不可跳过的最低标准。

对于正在学习 Python 量化交易的你来说,这篇文章的价值在于:

  • • 它提供了一个完整可运行的回测框架,你可以直接替换股票代码来测试自己感兴趣的标的。
  • • 它展示了 vectorbt 和 yfinance 这两个实用库的基本用法。
  • • 更重要的是,它教会了你如何正确看待回测结果——一个漂亮的回测数字只是研究的开始,而非终点。

回测结束的地方,才是真正工作开始的地方。

以上就是“一个 MACD 指标竟跑赢了买入持有策略?用 Python 带你复现 23 年回测的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取