📘 本章重点
- 理解MACD指标的本质:通过两条EMA的差值与信号线的交叉,捕捉趋势的启动与衰竭
- 掌握MACD三大信号体系:金叉/死叉、零轴穿越、背离
- 学会区分MACD在不同市场环境下的表现差异
- 了解MACD策略的改进方向与组合过滤方法
⚠️ 本章难点
- 理解MACD“滞后性”的本质——均线类指标天然滞后,信号出现时趋势可能已走了一段
- 区分“零轴上方金叉”与“零轴下方金叉”的不同含义
- 掌握背离信号的识别方法及其在趋势反转预判中的价值
- 认识MACD策略在震荡市中的致命缺陷——频繁的假信号
⏱️ 预估学习时间
- 40~55分钟
一、策略简述与一句话定性
一句话定性:MACD策略是一种基于“均线聚散”原理的趋势跟踪与动量识别策略——通过短期与长期指数移动平均线(EMA)的差值(DIF)及其信号线(DEA)的交叉,捕捉价格趋势的启动、延续与衰竭,并据此发出买卖信号。
MACD的全称是Moving Average Convergence Divergence,中文译为“指数平滑异同移动平均线”或“移动平均线聚散指标”。它由美国技术分析大师杰拉尔德·阿佩尔(Gerald Appel) 于1977年左右发明,1979年正式向公众推出。在技术分析领域,MACD与RSI、布林带齐名,是最常用的动量指标之一。
MACD的设计初衷,是阿佩尔在寻找一个“信号清晰、不会产生太多假信号、且易于维护”的指标。它通过测量两条不同速度的移动平均线之间的“距离”——即聚散程度——来判断市场的动量变化。
如果说双均线交叉策略(第一.05)是“两条均线谁在上谁在下”的二元判断,那MACD就是它的“升级版”——它不仅告诉你谁在上谁在下(金叉/死叉),还告诉你趋势的强度在增强还是减弱(柱状图的变化),以及趋势是否处于强势区域(零轴上下)。MACD = 双均线 + 动量测量。
老陈点评:
从量化研究的角度看,MACD的本质是一个“动量滤波器”——它用EMA的差值来度量价格的短期动量,再用EMA对动量本身做平滑,最后用差值(柱状图)来度量动量的变化率。这种“二阶滤波”的设计,让MACD既能跟踪趋势,又能感知动量的加速度。但滤波越精细,延迟就越大——这是MACD永远无法摆脱的宿命。
老王补充:
MACD是我入行用的第一个指标——金叉买入、死叉卖出,简单直接。但后来我发现,这种“机械式”操作在震荡市里就是一台“稳定亏损机”。MACD最大的价值不是金叉死叉,而是背离。 价格创新高但MACD没跟上——这才是MACD真正值钱的地方。
理解MACD的类比:仪表盘
如果你把价格走势想象成开车,那么MACD就是车上的仪表盘——它不告诉你“该往哪开”(那是导航仪的事,对应的是基本面分析或宏观预判),它只告诉你“现在这辆车跑得怎么样”。
- DIF快线 = 车速表(显示当前速度的方向和大小)。
- DEA慢线(信号线) = 平均车速(把忽快忽慢的速度做了个平滑处理)。
- 柱状图(Histogram) = 发动机加速度(车速表与平均车速的差距,显示你是在猛踩油门还是溜车减速)。
实战场景映射:
- 金叉(DIF上穿DEA) = 当前车速超过了平均车速,说明你在加速(趋势启动)。
- 零轴上方金叉 = 不仅你在加速,而且当前平均车速已经很快了(80km/h以上),说明你在高速上超车(顺势做多,胜率高)。
- 顶背离(价格新高,DIF未新高) = 车速虽然冲到了120km/h的新高,但发动机转速(加速度)反而比上一次冲120时低了。老司机都知道,这说明车没后劲了,接下来大概率要松油门减速(趋势即将反转)。
为什么是仪表盘而不是导航仪? 因为MACD有“滞后性”——你看到车速从100降到80,车其实已经往前又开了几百米。MACD改变方向时,价格也已经走了一段。你不能怪仪表盘(MACD)不准,你只能接受物理惯性(市场趋势)的存在。MACD是用来“确认车况”的,不是用来“预测路况”的。
⚠️ MACD第一原则:先看市场状态,再看MACD信号
MACD在趋势市中是好用工具,在震荡市中是一台稳定的亏损机器。当DIF和DEA在零轴附近反复缠绕、频繁交叉时,说明市场没有明确方向——此时任何金叉死叉都不可信。
如何判断? 看ADX——当ADX < 20时,暂停使用MACD的金叉死叉信号。或者看布林带宽度——当带宽持续收窄时,市场即将选择方向,MACD的假信号会增多。
二、策略的使用范围与条件
| 维度 | 适用范围与条件 | 说明 |
|---|---|---|
| 适用市场 | 股票、ETF、期货、外汇、加密货币 | 适用于任何有趋势特征的市场 |
| 品种要求 | 流动性好、价格连续 | 流动性差的品种EMA计算不稳定 |
| 交易机制 | 双向(做多/做空)或单向(仅做多)均可 | A股单向市场中可只保留做多信号 |
| 适用周期 | 日线、周线最佳;小时线次之 | MACD在周线级别信号更可靠,日线和小时线假信号较多 |
| 资金门槛 | 极低 | 单品种即可运行 |
| 不适合的市场状态 | 窄幅震荡、横盘整理 | 快线和慢线频繁交叉,假信号“满天飞” |
加密货币市场的调整:由于加密货币7×24小时交易,传统的“日线”概念被弱化。建议使用4小时或1小时K线,并相应调整参数(如(6,13,5)用于短线交易)。
适用品种举例:
- 宽基指数(沪深300、标普500)及其ETF
- 流动性好的大盘股
- 主流加密货币(比特币、以太坊)
失效案例:在2015年8月至2016年5月A股熔断后的震荡修复期,沪深300指数在3000-3700点区间反复震荡,MACD在此期间产生了超过10次金叉/死叉交替,信号几乎每周都在反转,简单跟随策略的最大回撤可达10%-20%。
老陈点评:
MACD策略的适用性本质上取决于市场是否具有“趋势-震荡”的可区分性。在趋势市中,MACD的金叉/死叉信号具有正期望;在震荡市中,这些信号的期望为负。因此,使用MACD的第一原则不是“怎么用”,而是“什么时候用”。 你可以用ADX或布林带宽度来辅助判断市场状态。
三、因子拆解与原理
MACD的设计思想:二阶滤波
MACD的精妙之处在于它做了两次滤波:
- 第一次滤波:用EMA对价格做平滑,得到DIF(快线与慢线的差值)——这告诉你“趋势的方向和强度”
- 第二次滤波:用EMA对DIF再做平滑,得到DEA(信号线)——这告诉你“动量的趋势”
而柱状图(DIF – DEA)则是动量的加速度——它告诉你动量是在加速还是减速。
类比:如果把价格比作汽车的位置,DIF就是速度,DEA是速度的移动平均,柱状图就是加速度。MACD不仅告诉你车往哪个方向开(DIF正负),还告诉你加速还是减速(柱状图变化)——这就是它比普通双均线更强大的地方。
3.1 三个核心因子
MACD指标由三部分构成:
| 因子 | 全称 | 计算公式 | 含义 |
|---|---|---|---|
| DIF线(快线) | 差离值 | DIF = EMA₁₂(Close) – EMA₂₆(Close) | 短期与长期均线的“距离”,反映动量方向 |
| DEA线(慢线/信号线) | DIF的平滑值 | DEA = EMA₉(DIF) | DIF的9日EMA,起平滑和确认作用 |
| 柱状图(Histogram) | 动能柱 | Histogram = DIF – DEA | DIF与DEA的差值,反映动量的加速度 |
计算步骤:
- 计算12日EMA:EMA₁₂ = 今日收盘价 × 2/13 + 昨日EMA₁₂ × 11/13
- 计算26日EMA:EMA₂₆ = 今日收盘价 × 2/27 + 昨日EMA₂₆ × 25/27
- 计算DIF:DIF = EMA₁₂ – EMA₂₆
- 计算DEA:DEA = DIF的9日EMA(平滑系数 = 2/10)
- 计算柱状图:柱状图 = DIF – DEA
柱状图(Histogram)由Thomas Aspray于1986年开发,用于直观显示DIF与DEA的差值,反映动量的加速度。阿佩尔最初的MACD只有DIF和DEA两条线,没有柱状图。如今我们使用的MACD,实际上是阿佩尔 + Aspray的联合贡献。
默认参数(12,26,9)是阿佩尔在1970年代设定的,其中12和26可能源于当时六天交易周的时代背景(12天≈两周,26天≈一个月),而9的来历则众说纷纭。不同市场可以调整参数——更快的(6,19,9)适合短线,更慢的(24,52,18)适合长线。但建议新手先用默认值,以便与其他交易者的分析进行比较。
老王补充:
阿佩尔自己都不只用一套参数——这给了我很大的启发。很多人把MACD(12,26,9)当成“圣旨”,但其实这只是阿佩尔在1970年代的一个选择。参数不是信仰,是工具。 我自己的经验是:趋势强的品种用短参数(更灵敏),趋势弱的品种用长参数(更稳定)。
3.2 三大信号体系
信号一:金叉与死叉(最常用)
| 信号 | 触发条件 | 含义 | 操作建议 |
|---|---|---|---|
| 金叉(Golden Cross) | DIF从下方上穿DEA | 短期动量开始超越长期动量,趋势可能向上启动 | 买入/做多 |
| 死叉(Death Cross) | DIF从上方下穿DEA | 短期动量开始弱于长期动量,趋势可能向下反转 | 卖出/做空 |
金叉/死叉的位置决定信号质量:
| 位置 | 金叉含义 | 死叉含义 |
|---|---|---|
| 零轴上方 | 上升趋势中的加速信号(可靠性较高) | 上升趋势中的回调信号(可能是买入机会) |
| 零轴下方 | 下跌趋势中的反弹信号(可能是假突破) | 下跌趋势中的加速信号(可靠性较高) |
| 零轴附近 | 趋势可能从震荡转向上涨 | 趋势可能从震荡转向下跌 |
为什么零轴上方金叉更可靠?
零轴是DIF=0的位置,即EMA₁₂ = EMA₂₆——短期均线与长期均线重合。当DIF>0(零轴上方)时,说明短期均线已经在长期均线之上,市场已经处于多头区域。此时出现的金叉,是上升趋势中的再次确认,胜率更高。
而当DIF<0(零轴下方)时,市场仍处于空头区域。此时的金叉可能只是下跌趋势中的反弹,很容易被后续的下跌吞没。
一句话总结:零轴上方金叉 = 顺势做多(胜率高);零轴下方金叉 = 逆势抄底(风险大)。
信号二:零轴穿越
| 信号 | 触发条件 | 含义 |
|---|---|---|
| 上穿零轴 | DIF从负值变为正值 | 短期均线从下方上穿长期均线,市场进入多头区域 |
| 下穿零轴 | DIF从正值变为负值 | 短期均线从上方下穿长期均线,市场进入空头区域 |
零轴穿越本质上就是双均线策略的“金叉/死叉”——当DIF>0时,意味着EMA₁₂ > EMA₂₆,即短期均线在长期均线之上。
信号三:背离——MACD最具价值的信号
背离是指价格走势与MACD指标走势出现不一致的情况,预示当前趋势可能即将反转。
| 背离类型 | 价格表现 | MACD表现 | 含义 |
|---|---|---|---|
| 顶背离 | 价格创出新高 | DIF或柱状图未同步创新高 | 上涨动能衰竭,可能即将下跌 |
| 底背离 | 价格创出新低 | DIF或柱状图未同步创新低 | 下跌动能衰竭,可能即将反弹 |
如何识别底背离(以做多为例):
- 找到最近的两个价格低点:低点A(更早)和低点B(更近),且低点B < 低点A(价格创新低)
- 找到对应的两个DIF(或柱状图)低点:DIF_A和DIF_B
- 如果DIF_B > DIF_A(DIF未创新低),则形成底背离
关键细节:两个低点之间必须有一段明显的反弹,否则无法确认“低点”的有效性。通常要求两个低点之间至少间隔5-10根K线。另外,多周期同时出现背离(如日线和周线同时底背离),信号的可靠性会大幅提升。
老陈点评:
背离是MACD指标中唯一具有“前瞻性”的信号——金叉和死叉都是“已经发生”的事情(滞后),而背离告诉你“可能即将发生”的事情(领先)。但背离的识别需要一定的经验——什么样的“未创新高”才算有效背离?通常要求两次高点之间有一段明显的回调,且MACD的峰值差距足够明显。多周期同时出现背离(如日线和周线同时顶背离),信号的可靠性会大幅提升。
3.3 因子的优缺点
| 优点 | 缺点 |
|---|---|
| 逻辑清晰,信号体系完整(交叉、零轴、背离) | 严重滞后——金叉出现时行情可能已走了一段 |
| 适用范围广,几乎所有交易软件都内置 | 在震荡市中频繁产生假信号,胜率极低 |
| 柱状图提供动量加速度信息,优于纯双均线 | 参数(12,26,9)是历史惯例,不一定适合所有品种 |
| 背离信号具有前瞻性,可用于预警反转 | 需要结合市场环境判断,单独使用效果有限 |
老王补充:
MACD最坑的地方在于它的“滞后性”——你看到的金叉,是已经发生的事情。有交易员开玩笑说:“MACD金叉出现时,趋势已经走了80%;死叉出现时,剩下的20%可能就是你亏的那部分。” 这话有点夸张,但背后的道理是真实的——MACD是确认工具,不是预测工具。想抓趋势启动,别指望MACD;想确认趋势还在,MACD是好帮手。
四、仓位、买卖点与风险管理
4.1 入场信号
标准版(金叉/死叉) :
| 方向 | 触发条件 | 操作 |
|---|---|---|
| 做多 | DIF上穿DEA(金叉) | 次日开盘买入 |
| 做空 | DIF下穿DEA(死叉) | 次日开盘卖出/做空 |
进阶版(零轴过滤) :
| 方向 | 触发条件 | 操作 |
|---|---|---|
| 做多(增强) | DIF上穿DEA 且 DIF>0 且 DEA>0 | 只在多头区域做多,过滤底部反弹的假信号 |
| 做空(增强) | DIF下穿DEA 且 DIF<0 且 DEA<0 | 只在空头区域做空,过滤顶部回调的假信号 |
进阶版(多周期确认) :
| 方向 | 触发条件 | 操作 |
|---|---|---|
| 做多 | 周线MACD金叉(定方向)+ 日线MACD金叉(找入场点) | 周线定趋势方向,日线找具体入场时机 |
| 做空 | 周线MACD死叉 + 日线MACD死叉 | 同上,方向相反 |
进阶版(背离信号) :
| 方向 | 触发条件 | 操作 |
|---|---|---|
| 底背离做多 | 价格创新低,但DIF或柱状图未创新低 | 确认背离后买入,止损设在前低下方 |
| 顶背离做空 | 价格创新高,但DIF或柱状图未创新高 | 确认背离后卖出/做空,止损设在前高上方 |
老陈点评:
多周期确认策略(周线定方向、日线找入场点)在量化回测中已被验证有效——有回测显示这种复合框架可以将胜率提升10个百分点以上。背后的逻辑很简单:周线MACD告诉你“大趋势是什么”,日线MACD告诉你“什么时候上车”。用大周期过滤噪音,用小周期寻找时机——这是MACD策略最实用的改进思路之一。
4.2 仓位管理
MACD策略的仓位管理相对简单:
- 固定比例仓位:每笔交易投入总资金的5%-10%
- 信号强度调整:零轴上方金叉可适当加仓,零轴下方金叉减仓或观望
- 多周期确认加仓:周线和日线信号共振时,可提高仓位
4.3 止损设计
| 止损方式 | 设定方法 | 适用场景 |
|---|---|---|
| 固定比例止损 | 入场价下方3%-5%(做多) | 简单通用 |
| 前低/前高止损 | 做多时止损设在近期低点下方 | 结合价格形态 |
| 信号反转止损 | 金叉买入后出现死叉即平仓 | 逻辑自洽,但可能止损较晚 |
| ATR倍数止损 | 入场价 ± 1.5×ATR | 自适应波动率 |
4.4 止盈设计
| 出场方式 | 触发条件 | 说明 |
|---|---|---|
| 死叉/金叉止盈 | 出现反向交叉信号 | 最常用,与入场逻辑对称 |
| 固定盈亏比 | 止损的1.5-2倍 | 简单有效 |
| 柱状图衰竭止盈 | 柱状图开始缩短(动能减弱) | 提前锁定部分利润 |
| 零轴穿越止盈 | DIF穿越零轴 | 趋势可能转变 |
4.5 策略在失效时的应对
- 震荡市过滤器:当ADX < 20时,暂停MACD策略,等待趋势明朗
- 连续亏损预警:连续3笔亏损后暂停交易,重新评估市场状态
- 参数调整:在趋势较强的市场中可适当缩短参数(如9, 21, 7),在震荡市场中可加长参数(如19, 39, 13)
五、策略的来历、设计者与趣闻
MACD由杰拉尔德·阿佩尔(Gerald Appel) 于1977年左右发明,1979年正式向公众推出。阿佩尔是一位美国技术分析大师、投资顾问和作家。他于1973年创立了投资通讯《Systems & Forecasts》,至今仍在出版(截至2019年已连续出版46年)。他还创立了Signalert资产管理公司,在2012年退休前为客户管理资金超过35年。阿佩尔撰写了17本投资书籍(截至2019年),其中两本被《股票交易者年鉴》评为“年度投资书籍”。
注:部分资料显示阿佩尔曾与Fred Hitschler共同开发该指标,但阿佩尔被公认为主要发明人。
柱状图的诞生:阿佩尔最初的MACD只有DIF和DEA两条线,并没有柱状图。1986年,技术分析师Thomas Aspray开发了柱状图(Histogram)——即DIF与DEA的差值——用于更直观地观察动量的加速度。1988年,Aspray在《Technical Analysis of Stocks & Commodities》杂志上正式发表了这一改进。这一改进让MACD的信号体系更加完整。如今我们使用的MACD,实际上是阿佩尔 + Aspray的联合贡献。
趣闻:阿佩尔本人在2003年的采访中透露,MACD最初的发明时间大约是1977年,但“这些年来我使用它的方式已经发生了变化”。他还提到一个重要的实战心得:“买入应该比卖出稍微容易一些”——因为市场的上涨方式与下跌方式不同。这个观察背后是金融市场的“慢牛快熊”特征——上涨往往缓慢而持久,下跌往往快速而剧烈。
另一个有趣的事实:MACD虽然是阿佩尔最著名的贡献,但他本人对MACD的使用并不拘泥于(12,26,9)这一套默认参数。他主张不同时间框架使用不同参数,而不是一套参数打天下。在2003年的采访中,阿佩尔明确说:“We use different time frames for different sets of parameters for buying and selling. It works better when you don’t use one parameter.”
老陈点评:
阿佩尔说“买入比卖出稍微容易一些”,这本质上是对市场非对称性的观察。在量化策略中,这可以体现为:做多信号的条件可以比做空信号稍微宽松一些,或者做多的仓位可以比做空稍微大一些。但这种“非对称”需要基于对具体品种历史数据的统计验证,不能盲目套用。
老王补充:
阿佩尔自己都不只用一套参数——这给了我很大的启发。很多人把MACD(12,26,9)当成“圣旨”,但其实这只是阿佩尔在1970年代的一个选择。参数不是信仰,是工具。
风险提示:MACD信号可以被制造
MACD的金叉/死叉信号有一个“先天缺陷”——它们完全由收盘价决定。给定过去一段时间的价格数据,你可以精确计算出“要让明天出现金叉,今天的收盘价需要达到多少”。这意味着:拥有足够资金的市场参与者,可以在尾盘用少量筹码将价格推到特定位置,制造出一个“教科书级的金叉”或“死叉”。
制造金叉的数学原理
已知今日的EMA₁₂和EMA₂₆历史值,明天的金叉条件为:
DIF_{t+1} > DEA_{t+1}
其中:
EMA₁₂(t+1) = P(t+1) × 2/13 + EMA₁₂(t) × 11/13
EMA₂₆(t+1) = P(t+1) × 2/27 + EMA₂₆(t) × 25/27
DIF(t+1) = EMA₁₂(t+1) - EMA₂₆(t+1)
DEA(t+1) = DIF(t+1) × 2/10 + DEA(t) × 8/10
将所有公式代入金叉条件DIF(t+1) > DEA(t+1),可得到一个关于P(t+1)的一元不等式。解这个不等式,即可得到“制造金叉所需的最低收盘价”。
实战意义
如果你看到某只股票在尾盘突然拉升,刚好让MACD在收盘时形成金叉,而全天其他时段并无异常放量——这可能是人为制造的信号,而非真实趋势的启动。依赖MACD信号的量化程序或散户跟风买入后,次日主力高位派发,代价惨重。
这不是阴谋论,这是MACD作为“滞后指标”的数学必然。 当一个信号可以被精确计算和人为制造时,它就不再是一个完全可靠的交易依据。
老王补充:
我早年吃过这个亏。某次尾盘看到一只股票MACD“完美金叉”,追进去,第二天直接低开低走,一查——前一天尾盘最后一分钟,一笔大单把价格拉高了2%,刚好让MACD翻红。从那以后,我给自己定了一条铁律:尾盘拉升形成的金叉,一律不追。 等第二天开盘看半小时确认,再决定是否入场。
六、Python回测示例
以下代码演示MACD金叉/死叉策略在沪深300指数上的回测。采用标准版(金叉买入、死叉卖出),包含固定比例止损止盈。
import pandas as pd
import numpy as np
import yfinance as yf
from datetime import datetime
# 若yfinance无法获取数据,可使用akshare或聚宽数据源
def macd_strategy(data,
fast=12, # 短期EMA周期
slow=26, # 长期EMA周期
signal=9, # 信号线周期
stop_loss_pct=0.05, # 止损比例
take_profit_pct=0.10, # 止盈比例
use_zero_filter=False # 是否使用零轴过滤
):
"""
MACD金叉/死叉策略(带固定止损止盈)
参数:
data: 必须包含 'Close', 'Open' 列
fast: 快线EMA周期
slow: 慢线EMA周期
signal: 信号线EMA周期
stop_loss_pct: 止损比例
take_profit_pct: 止盈比例
use_zero_filter: 是否启用零轴过滤(仅在零轴上方做多,零轴下方做空)
返回:添加了持仓和净值的DataFrame
"""
df = data.copy()
# 1. 计算EMA
df['EMA_fast'] = df['Close'].ewm(span=fast, adjust=False).mean()
df['EMA_slow'] = df['Close'].ewm(span=slow, adjust=False).mean()
# 2. 计算DIF和DEA
df['DIF'] = df['EMA_fast'] - df['EMA_slow']
df['DEA'] = df['DIF'].ewm(span=signal, adjust=False).mean()
df['Histogram'] = df['DIF'] - df['DEA']
# 3. 生成信号
# 金叉:DIF从下方上穿DEA
df['Golden_Cross'] = (df['DIF'] > df['DEA']) & (df['DIF'].shift(1) <= df['DEA'].shift(1))
# 死叉:DIF从上方下穿DEA
df['Death_Cross'] = (df['DIF'] < df['DEA']) & (df['DIF'].shift(1) >= df['DEA'].shift(1))
# 零轴过滤
if use_zero_filter:
df['Long_Signal'] = df['Golden_Cross'] & (df['DIF'] > 0) & (df['DEA'] > 0)
df['Short_Signal'] = df['Death_Cross'] & (df['DIF'] < 0) & (df['DEA'] < 0)
else:
df['Long_Signal'] = df['Golden_Cross']
df['Short_Signal'] = df['Death_Cross']
# 4. 模拟持仓(次日开盘入场)
df['Position'] = 0
df['Entry_Price'] = np.nan
position = 0
entry_price = 0.0
for i in range(1, len(df) - 1): # 留出最后一天
if position != 0:
# 计算盈亏
if position == 1:
pnl = (df['Close'].iloc[i] - entry_price) / entry_price
else:
pnl = (entry_price - df['Close'].iloc[i]) / entry_price
# 止损或止盈
if pnl <= -stop_loss_pct or pnl >= take_profit_pct:
position = 0
entry_price = 0.0
# 反向信号平仓
elif position == 1 and df['Short_Signal'].iloc[i]:
position = 0
entry_price = 0.0
elif position == -1 and df['Long_Signal'].iloc[i]:
position = 0
entry_price = 0.0
else:
# 检查入场信号(次日开盘入场)
if df['Long_Signal'].iloc[i]:
position = 1
entry_price = df['Open'].iloc[i+1] # 次日开盘入场
elif df['Short_Signal'].iloc[i]:
position = -1
entry_price = df['Open'].iloc[i+1] # 次日开盘入场
df.loc[df.index[i], 'Position'] = position
if position != 0:
df.loc[df.index[i], 'Entry_Price'] = entry_price
# 5. 计算收益率和净值
df['Returns'] = df['Position'].shift(1) * (df['Close'] - df['Close'].shift(1)) / df['Close'].shift(1)
df['Net_Value'] = (1 + df['Returns']).cumprod()
# 6. 统计指标
total_return = (df['Net_Value'].iloc[-1] - 1) * 100
max_drawdown = ((df['Net_Value'].cummax() - df['Net_Value']) / df['Net_Value'].cummax()).max() * 100
# 统计交易次数(精确计数)
position_changes = df['Position'].diff()
trade_count = 0
for val in position_changes:
if val != 0:
trade_count += 1
trade_count = trade_count // 2 # 完整的一买一卖算一笔
print(f"总收益率:{total_return:.2f}%")
print(f"最大回撤:{max_drawdown:.2f}%")
print(f"交易次数:{trade_count}")
return df
if __name__ == "__main__":
# 下载沪深300指数数据
df_300 = yf.download('000300.SS', start='2020-01-01', end='2025-01-01')
# 运行策略(标准版)
result = macd_strategy(df_300, fast=12, slow=26, signal=9)
print(result[['Close', 'DIF', 'DEA', 'Position', 'Net_Value']].tail(10))
参数敏感性测试框架:
# 简单参数遍历示例(可用于优化参数选择)
# 注意:遍历多个参数组合时,警惕过拟合风险
# 建议在遍历后使用样本外数据进行验证
# 参数范围
fast_range = [8, 12, 16]
slow_range = [20, 26, 32]
signal_range = [6, 9, 12]
best_sharpe = -999
best_params = None
for f in fast_range:
for s in slow_range:
for sig in signal_range:
if f >= s: # 快线周期必须小于慢线周期
continue
result = macd_strategy(df_300, fast=f, slow=s, signal=sig)
# 计算夏普比率(简化版)
sharpe = result['Returns'].mean() / result['Returns'].std() * np.sqrt(252)
if sharpe > best_sharpe:
best_sharpe = sharpe
best_params = (f, s, sig)
print(f"最优参数组合:fast={best_params[0]}, slow={best_params[1]}, signal={best_params[2]}")
print(f"夏普比率:{best_sharpe:.2f}")
回测结果简要解读(以实际运行为准):
- 在2020年3月疫情暴跌后的反弹中,MACD在4月初出现金叉,捕获了后续的主要涨幅
- 在2021-2022年的震荡行情中,金叉死叉频繁交替,策略可能多次小亏
- 零轴过滤版可以过滤掉部分底部反弹的假金叉,但也可能错过一些V型反转
- 建议读者尝试不同参数组合和多周期确认版本
代码说明:
本代码为简化版MACD策略,采用金叉买入、死叉卖出的核心逻辑。入场使用次日开盘价,更贴近实盘。实际应用中,可以加入零轴过滤、多周期确认、背离检测等增强逻辑。
关于背离检测的参考实现:
背离检测的完整代码较为复杂,需要识别局部极值点。以下是一个简化的实现思路:# 1. 使用scipy.signal的find_peaks函数找到价格和DIF的局部极值点 # 2. 比较最近两个价格低点/高点与对应的DIF低点/高点 # 3. 如果价格创新高/低而DIF未创新高/低,标记为背离 # 完整实现建议参考专业量化平台的示例代码
关于多周期确认的实现思路:
# 多周期确认:周线定方向,日线找入场点 # 1. 计算周线MACD,判断方向(DIF>0为多头,DIF<0为空头) # 2. 在日线级别上,只有在周线方向一致时才开仓 # 3. 例如:周线DIF>0且日线出现金叉 → 做多(双重确认)
老陈点评:
回测时要注意:MACD策略的收益对参数选择相当敏感。在沪深300上,(12,26,9)未必是最优参数。建议做参数敏感性测试——在合理范围内(如快线8-16、慢线20-32、信号线6-12)遍历参数组合,观察收益的稳定性。如果某个参数组合的收益远高于其他组合,那很可能是过拟合。
老王补充:
实盘中,MACD策略最大的问题是执行延迟。信号是收盘价计算的,你只能在第二天开盘执行。如果第二天开盘跳空,你的实际成交价可能与回测假设差距很大。建议在回测中加入0.1%-0.2%的滑点成本,看看策略是否还能盈利。
七、本章小结与思考题
小结
| 项目 | 核心要点 |
|---|---|
| 策略类型 | 趋势跟踪 + 动量识别,基于均线聚散 |
| 核心公式 | DIF = EMA₁₂ – EMA₂₆;DEA = EMA₉(DIF);柱状图 = DIF – DEA |
| 三大信号 | 金叉/死叉(买卖点)、零轴穿越(多空区域)、背离(反转预警) |
| 核心优势 | 信号体系完整,适用范围广,几乎所有交易软件都内置 |
| 最大风险 | 滞后性和震荡市中的假信号 |
| 资金门槛 | 极低,单品种即可运行 |
| 改进方向 | 零轴过滤、多周期确认、背离增强、市场状态过滤 |
MACD策略是双均线交叉策略的“升级版”——它用EMA的差值(DIF)替代了双均线的直接比较,增加了信号线(DEA)来确认信号,还用柱状图来度量动量的加速度。MACD = 双均线 + 动量测量 + 信号确认。
但升级不等于完美。MACD继承了双均线的所有缺点——滞后性、震荡市假信号——同时还增加了一个新的挑战:参数更多,过拟合的风险更高。
老陈总结:
MACD最值得学习的不是它的金叉死叉,而是它的设计思想——用差值来度量动量,用平滑来确认信号,用柱状图来感知加速度。这套“二阶滤波”的框架,可以应用到很多其他量化场景中。学会MACD的数学结构,比记住它的买卖点更有价值。
老王总结:
如果你问我MACD能不能赚钱,我的答案是:能,但别指望靠金叉死叉赚钱。 真正让我赚钱的MACD用法是背离——在日线级别出现底背离时买入,在顶背离时卖出。至于金叉死叉,我用它们来确认趋势方向,而不是找买卖点。MACD是工具,不是圣杯。
💡 思考题
- MACD的金叉/死叉与双均线策略(第一.05)的金叉/死叉本质上有什么异同?MACD的优势在哪里?
- 为什么零轴上方出现的金叉比零轴下方的金叉更可靠?请从EMA₁₂和EMA₂₆的位置关系来解释。
- 假设你在日线级别看到一个底背离信号(价格创新低但MACD未创新低),但周线级别MACD仍然在零轴下方。你会怎么做?为什么?
- MACD的滞后性是其先天缺陷。你认为有没有可能通过调整参数来“治愈”滞后性?如果不可能,你如何在一个策略中“管理”滞后性带来的风险?
- (展望题) 随着机器学习模型在量化交易中的普及,像MACD这样的经典技术指标是否会逐渐被淘汰?请从“可解释性”“计算成本”“市场适应性”三个角度给出你的判断。
八、引用/参考出处
- 百度百科 MACD趋向指标:https://baike.baidu.com/item/MACD趋向指标/394464
- 百度百科 MACD指标: https://baike.baidu.com/item/MACD指标/6271283
- Technical Analysis of Stocks & Commodities – Interview: Gerald Appel & The MACD:https://traders.com/Documentation/Feedbk_docs/2003/09/Abstracts_new/Interview/interview.html
图书(元信息):
- Gerald Appel, Technical Analysis: Power Tools for Active Investors, FT Press, 2005.
- 史蒂夫·尼森,《日本蜡烛图技术》,地震出版社,2008。





















暂无评论内容