交易中不同类型移动平均线的比较·进阶篇
📊

交易中不同类型移动平均线的比较·进阶篇

(2/3)· 七类均线的实战差异不止在公式,EA 回测才见真章

偏理论 第 2/3 篇
很多人把 EMA 当成万能均线,却没注意它的衍生指标在趋势反转时的滞后幅度能差出数根 K 线。本篇接上篇基础分类,直接带你看 EMA 系指标怎么写进交易规则,再用 EA 跑出可比结果。

「EMA 衍生指标的横盘与趋势表现差异」

EMA 本身只是基础,真正在 MT5 里能直接调用的,往往是其衍生族:AMA、DEMA、TEMA、FRAMA、VIDYA、NRMA。它们都用 EMA 做内核,但在噪声处理和滞后上有明显分化。 以周期 12 的同源测试为例(收盘价计算,偏移 0):DEMA 与 TEMA 对价格跟随更紧,趋势中几乎贴着 K 线走;但横盘时这类双重/三重平滑反而容易抖出假信号。AMA、FRAMA、VIDYA、NRMA 在震荡段摆动极小,对毛刺不反应,代价是反转确认慢半拍。 图例里同参数摆在一起能看到:TEMA 和 FRAMA 在方向切换时反应最快,普通 EMA 居中,NRMA 横盘几乎是一条水平线——它不在 MT5 标准包内,要另装。外汇与贵金属杠杆高,横盘假信号触发频繁,实盘前务必在策略测试器里跑一遍上述参数对照。 下一步用同一套入场离场逻辑,挨个替换这些指标看净值曲线差异,比只看图形更有参考价值。

用增长因子卡住指标交叉的虚实

测试指标时,最忌讳把每一次线体交叉都当信号。这里用一套极简规则把噪音过滤掉:阳线实体上穿指标线只是初步买讯,必须再满足指标当前值减前一值大于预设 Growth 因子(指标上涨动能),才真正开多;阴线实体下穿指标线只是初步卖讯,要前一值减当前值大于 Growth(指标下跌动能)才开空。 离场比入场更机械:碰止盈或止损立刻走;若持多单,等指标线再次与阴线实体交叉就平;持空单则等与阳线实体交叉。图例 3、4 分别给了买、卖各一例,交叉点叠加 Growth 阈值的位置一目了然。 MT5 导航器里的移动平均线 EA 就是这类结构的现成参照,把 Growth 从默认 0 调成 0.5 或 1.0,能在 EURUSD 的 M15 上明显看出假交叉被砍掉的概率变化。外汇与贵金属杠杆高,回测通过不等于实盘能扛住滑点。

◍ 用实体穿越均线触发多空与平仓

这套 EA 把进场和离场都压在一根新 K 线开盘后判断,不盯每个 tick,只在柱线切换时跑 CheckForOpen 和 CheckForClose,避免盘中噪声反复触发。指标端可在 MA(含简单、指数、平滑、线性加权)、DEMA、TEMA、FRAMA、AMA、VIDYA、NRMA 里挑一个,并单独设 Growth 因子(GFactor)控制穿越阈值。 离场逻辑先看实体与指标线的关系:前一根 K 线开盘在 ma[0] 上方、收盘在下方,记为阴线实体下穿,清掉 BuyCross 并置 SellCross;反过来阳线实体上穿则清 SellCross 置 BuyCross。真正发信号还要叠一层——ma[0] 与 ma[1] 的差值必须超过 GFactor,下跌超阈值才给 SELL,上升超阈值才给 BUY。 已有持仓时,平仓不看 GFactor,只看实体反穿:买仓遇到阴线实体下穿指标线、卖仓遇到阳线实体上穿,就直接 PositionClose。代码里还卡了 Bars(_Symbol,_Period)>100 和 TERMINAL_TRADE_ALLOWED,历史不足 100 根柱或终端禁交易都不会平。外汇和贵金属杠杆高,这类穿越策略在震荡段可能连续假突破,上 MT5 用复盘历史先跑一遍 Growth 因子灵敏度再挂实盘。

MQL5 / C++
<span class="keyword">if</span>(rt[<span class="number">class="num">0</span>].open&gt;ma[<span class="number">class="num">0</span>] &amp;&amp; rt[<span class="number">class="num">0</span>].close&lt;ma[<span class="number">class="num">0</span>])               <span class="comment">class=class="str">"cmt">////检查阴线实体的交叉</span>
     {
      <span class="keyword">if</span>(BuyCross)
         BuyCross=<span class="macro">class="kw">false</span>;<span class="comment">                                   class=class="str">"cmt">//删除买入先决条件 (如果之前有阳线实体与指标线交叉)</span>
      SellCross=<span class="macro">true</span>;                                      <span class="comment">class=class="str">"cmt">//设置卖出交易先决条件</span>
     }
   <span class="keyword">else</span>
   <span class="keyword">if</span>(rt[<span class="number">class="num">0</span>].open&lt;ma[<span class="number">class="num">0</span>] &amp;&amp; rt[<span class="number">class="num">0</span>].close&gt;ma[<span class="number">class="num">0</span>])               <span class="comment">class=class="str">"cmt">//检查阳线实体的交叉</span>
     {
      <span class="keyword">if</span>(SellCross)
         SellCross=<span class="macro">class="kw">false</span>;<span class="comment">                                 class=class="str">"cmt">//删除买入先决条件 (如果之前有阴线实体与指标线交叉)</span>
      BuyCross=<span class="macro">true</span>;<span class="comment">                                      class=class="str">"cmt">//设置买入交易先决条件</span>
     }
   <span class="keyword">if</span>(SellCross &amp;&amp; ma[<span class="number">class="num">0</span>]&gt;ma[<span class="number">class="num">1</span>] &amp;&amp; ma[<span class="number">class="num">0</span>]-ma[<span class="number">class="num">1</span>]&gt;GFactor)
     {
      signal=<span class="macro">ORDER_TYPE_SELL</span>;                             <span class="comment">class=class="str">"cmt">//如果指标下跌则卖出条件发生</span>
      SellCross=<span class="macro">class="kw">false</span>;                                    <span class="comment">class=class="str">"cmt">//删除卖出先决条件</span>
     }
   <span class="keyword">else</span>
   <span class="keyword">if</span>(BuyCross &amp;&amp; ma[<span class="number">class="num">1</span>]&gt;ma[<span class="number">class="num">0</span>] &amp;&amp; ma[<span class="number">class="num">1</span>]-ma[<span class="number">class="num">0</span>]&gt;GFactor)
     {
      signal=<span class="macro">ORDER_TYPE_BUY</span>;                             <span class="comment">class=class="str">"cmt">// 如果指标上升则买入条件发生</span>
      BuyCross=<span class="macro">class="kw">false</span>;<span class="comment">                                    class=class="str">"cmt">//删除买入先决条件</span>
     }
   <span class="keyword">class="type">bool</span> signal=<span class="macro">class="kw">false</span>;
   <span class="keyword">class="type">long</span> type=<span class="functions">PositionGetInteger</span>(<span class="macro">POSITION_TYPE</span>);
   <span class="keyword">if</span>(type==(<span class="keyword">class="type">long</span>)<span class="macro">POSITION_TYPE_BUY</span> &amp;&amp; rt[<span class="number">class="num">0</span>].open&gt;ma[<span class="number">class="num">0</span>] &amp;&amp; rt[<span class="number">class="num">0</span>].close&lt;ma[<span class="number">class="num">0</span>])<span class="comment">       class=class="str">"cmt">//如果持仓为买入且 </span>
                                                                             <span class="comment">       class=class="str">"cmt">//指标线与阴线实体交叉 </span>
      signal=<span class="macro">true</span>;                                                                  <span class="comment">class=class="str">"cmt">//信号为平仓</span>
   <span class="keyword">if</span>(type==(<span class="keyword">class="type">long</span>)<span class="macro">POSITION_TYPE_SELL</span> &amp;&amp; rt[<span class="number">class="num">0</span>].open&lt;ma[<span class="number">class="num">0</span>] &amp;&amp; rt[<span class="number">class="num">0</span>].close&gt;ma[<span class="number">class="num">0</span>])      <span class="comment">class=class="str">"cmt">//如果持仓为卖出且</span>
                                                                                    <span class="comment">class=class="str">"cmt">//指标线与阳线实体交叉  </span>
      signal=<span class="macro">true</span>;                                                                  <span class="comment">class=class="str">"cmt">//信号为平仓</span>
   <span class="keyword">if</span>(signal)
     {
      <span class="keyword">if</span>(<span class="functions">TerminalInfoInteger</span>(<span class="macro">TERMINAL_TRADE_ALLOWED</span>) &amp;&amp; <span class="predefines">Bars</span>(<span class="predefines">_Symbol</span>,<span class="predefines">_Period</span>)&gt;<span class="number">class="num">100</span>)
         ExtTrade.PositionClose(<span class="predefines">_Symbol</span>,<span class="number">class="num">3</span>);                                         <span class="comment">class=class="str">"cmt">//平仓</span>
     }

「六组均线的回测实况与币种差异」

回测框架固定在六个直盘:EURUSD、GBPUSD、USDJPY、USDCAD、AUDUSD,统一 H1 周期,止盈 80 点、止损 50 点、0.1 手、本金 10000 美元、1:100 杠杆、5 位小数,MetaQuotes-Demo 全分笔报价,区间 2016.01.01–2017.09.09。指标周期搜 5–50(步长 1),Growth 因子 0.0001–0.0001(增量 0.001),VIDYA 额外搜 EMA 与 CMO 周期,NRMA 搜 Fact 参数,全部按收盘价计算无偏移。 EURUSD 里 TEMA(周期 44、Growth 0.0002)拿了总计净利 1842.81 与恢复因子 5.31 双高,但盈利因子 1.35 并非第一;NRMA(周期 15)盈利因子 1.42、锋锐 0.14 更均衡。自适应 MA 最差:净利 1024.19、恢复因子仅 1.63、最大余额回撤 5.41%。常规化汇总(含回撤取负)排前三的是 TEMA 2.88787、NRMA 2.81897、DEMA 1.76413。 切到 GBPUSD 格局反转:VIDYA(EMA 35、CMO 7、Growth 0.0004)四项常规化全 1,含回撤汇总 3.70001 遥遥领先;NRMA 与 SMA 次之。脆弱的是分形自适应 MA,交易 819 次净利才 651.54、恢复因子 0.85,常规化含回撤 -1.7463。 USDJPY 上平滑方法 MA(周期 33、Growth 0.0008)恢复因子冲到 5.15、净利 1702.94,加权 MA 净利 1892.24 最高但回撤 3.88%;自适应 MA 仍偏肉,恢复因子 2.56、回撤 5.13%。外汇与贵金属杠杆交易回撤失控可能直接爆仓,以上数字仅代表历史样本,换品种或时段结论可能翻盘。 开 MT5 把 Growth 因子上限从 0.0001 放宽到 0.001 重跑一遍,EURUSD 的加权 MA 与 NRMA 参数平原或许能挖出更肥的锋锐比率,但先拿 demo 账户验证再谈实盘。

把回测监控交给小布
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到不同均线在实时行情里的贴合度,你专注策略调参。

常见问题

差异主要体现在对价格突变的响应速度,具体偏差幅度依赖周期参数与品种波动率,回测中可观察到数根 K 线的滞后区别。
可以,小布盯盘的品种页内置了多类均线的实时叠加与偏离提示,省去手动切指标的时间。
倾向用跨周期样本外验证,避免在单一行情段调出漂亮曲线,外汇贵金属高风险,参数鲁棒性比峰值收益重要。
没有绝对优劣,不同均线在趋势和震荡市表现概率分化,可能 EMA 在趋势中更敏锐,而 SMMA 在横盘更少假信号。