MQL5交易策略自动化(第八部分):构建基于蝴蝶谐波形态的智能交易系统(EA)(基础篇)
📘

MQL5交易策略自动化(第八部分):构建基于蝴蝶谐波形态的智能交易系统(EA)(基础篇)

第 1/3 篇

用EA把蝴蝶形态交给机器盯

在 MT5 里做谐波交易,最耗人的是肉眼找点位。蝴蝶形态(Butterfly)对 XA、AB、BC、CD 四段的比例要求极严,靠手动量斐波那契容易漏单或迟疑。 把这套识别逻辑写成 EA,等于让终端在每根收盘价上重算一次潜在 D 点区域,只在形态完成且触发入场条件时弹单。外汇与贵金属杠杆高,形态失败率不低,任何信号都只是概率倾向,需配合止损。 原文示例里用 iCustom 调用谐波指标做条件判断,核心是先确认 AB=0.786×XA、BC 在 0.382~0.886 之间、CD=1.27~1.618×XA,才视为有效蝴蝶。开 MT5 加载对应指标,把下面代码段丢进 EA 的 OnTick 做验证最快。

MQL5 / C++
class="type">class="kw">double butterflyCheck()
{
   class="type">class="kw">double xa = iCustom(NULL,class="num">0,"Harmonics",class="num">0,class="num">0);
   class="type">class="kw">double ab = iCustom(NULL,class="num">0,"Harmonics",class="num">1,class="num">0);
   class="type">class="kw">double bc = iCustom(NULL,class="num">0,"Harmonics",class="num">2,class="num">0);
   class="type">class="kw">double cd = iCustom(NULL,class="num">0,"Harmonics",class="num">3,class="num">0);
   if(ab>class="num">0.78*xa && ab<class="num">0.79*xa && bc>class="num">0.382*xa && bc<class="num">0.886*xa && cd>class="num">1.27*xa && cd<class="num">1.618*xa)
      class="kw">return class="num">1;
   class="kw">return class="num">0;
}

◍ 从网格EA切到蝴蝶谐波的动机

上一系列我们用 MQL5 写过带动态手数缩放的网格 EA,核心目标是把风险暴露随浮亏平滑摊薄。这一篇把重心挪到蝴蝶谐波——它靠几个固定斐波那契比率锁定潜在反转区,属于典型的价格行为反转结构。 和网格不同,蝴蝶形态不靠加仓摊平,而是等价格走到 X、A、B、C、D 五点满足比率约束时,才视为转折概率升高。自动化之后,EA 负责把形态画出来并自动发单,交易者只盯形态是否有效。 本篇会依次走完四步:策略设计方案、MQL5 实现、回测、结论。跑完你本地会多出一个能识别蝴蝶并下单的 EA,直接挂 MT5 就能验证。

「蝴蝶形态的几何判定与EA识别路径」

蝴蝶形态靠五个枢轴点 X、A、B、C、D 锁定结构,分看跌与看涨两类。看跌走高是 X 高—A 低—B 高—C 低—D 高,且 D 必须高于 X;看涨反之,D 落在 X 下方。纯手工数浪容易漏,用 EA 在历史数据里扫才是正经做法。 识别按四段斐波那契约束走:XA 定参考距离;AB 回撤到 XA 的 78.6% 附近算合格,说明反转吃掉初始段大部分;BC 对 XA 回撤 38.2%–88.6%,留一段盘整;CD 最后延伸到 XA 的 127%–161.8%,到点即形态完成。外汇与贵金属杠杆高,形态失效是常态,这些条件只是概率过滤不是保本锁。 EA 确认形态后,会在图上画三角形和趋势线标出 XABCD,并按算出的入场、止损、止盈直接发单。开 MT5 接一组 EURUSD 日线回测,把 AB 容差从 78.6% 放宽到 80% 看信号数量变化,比看图文直观得多。

MT5里搭一个蝴蝶谐波识别与交易骨架

打开 MetaEditor,在导航器的「指标」目录点新建,生成文件后先声明全局变量并引入 Trade\Trade.mqh,实例化 obj_Trade 才能碰交易接口。输入参数里 PivotLeft / PivotRight 管转折点左右看几根K线,Tolerance 是谐波比率容差,LotSize 和 AllowTrading 分别管手数与开关。 转折点用 struct 存时间、价格、isHigh,塞进动态数组 pivots[] 当历史参照;g_patternFormationBar 和 g_lockedPatternX 用来锁形态、防同一模式重复发单。绘图侧写了 DrawTriangle、DrawTrendLine、DrawDottedLine、DrawTextEx 四个辅助函数,分别画三角形、趋势线、水平虚线和文字标签,把 XABCD 关键点与 TP 水平直接丢到图上。 OnTick 里用 static lastBarTime 比对 iTime 拿到的当前K线时间,相同就 return,保证每根K线只跑一次主逻辑。识别摆动高低点时用 ArrayResize 清空 pivots,Bars 取总数,for 循环从 end-1 到 start,拿 iHigh/iLow 跟 PivotLeft/PivotRight 邻根比,合格才写进结构体。ArrayPrint 出来的转折点序列,是后面提 XABCD 的原始素材。 蝴蝶验证取最近五个转折点,数量不够就清锁变量退出。看跌结构须是 X高→A低→B高→C低→D高;B 在 XA 的 0.786 回撤附近,BC 为 XA 的 0.382–0.886 倍,CD 扩展至 XA 的 1.27–1.618 倍且 D 高于 X。全满足才把 patternFound 置 true,看涨反过来比。 D.price 高于 X.price 判看跌(潜在做空倾向),低于则看涨(潜在做多倾向)。DrawTriangle 用 clrRed / clrBlue 填 XAB 与 BCD 两三角,DrawTrendLine 连 X-A、A-B、B-C、C-D、X-B、B-D 黑实线。标签用 SYMBOL_POINT 算偏移,高低点自动上下放,XB 中点写「看涨/看跌蝴蝶形态」。 入场用 SYMBOL_ASK(买)/ SYMBOL_BID(卖),以 C.price 为 TP3,区间三等分出 TP1/TP2,DrawDottedLine 画水平线。外汇与贵金属杠杆高、滑点跳空频繁,这类形态信号仅是概率倾向,实盘前务必在 MT5 策略测试器跑历史回测。 形态锁定模块用 Bars 取 currentBarIndex,g_patternFormationBar 为 -1 时记起始K线并存 g_lockedPatternX;同根K线反复更新算重绘,打印警告不交易。新K线推进后比 g_lockedPatternX 与当前 X 时间,匹配才确认有效。PositionSelect 无持仓且 AllowTrading 开,看涨用 obj_Trade.Buy、看跌用 obj_Trade.Sell,失败打 ResultRetcodeDescription。X 时间变了就清锁重认。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                     Copyright class="num">2025, Forex Algo-Trader, Allan. |
class=class="str">"cmt">//|                 "https://t.me/Forex_Algo_Trader" |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Forex Algo-Trader, Allan"

◍ 蝴蝶形态 EA 的骨架与参数设定

这套基于蝴蝶形态(Butterfly)逻辑的交易 EA,把枢轴点识别与下单动作拆得很清楚。它借助标准 Trade.mqh 库实例化 CTrade 对象,对外暴露 5 个输入参数:左侧/右侧枢轴回溯各 5 根 K 线(PivotLeft、PivotRight),形态容差 Tolerance 设为 0.10,即允许 XA 腿幅度 10% 的偏差,默认手数 0.01,并用 AllowTrading 总闸控制是否真的发单。 蝴蝶形态的多空结构完全由枢轴极性定义。看涨蝴蝶的 X 为摆动高点、A 为摆动低点、B 回抽高点、C 再探低点、D 最终高点;理想 B 位落在 A + 0.786*(X-A)。看跌则镜像:X 低点、A 高点、B 低点、C 高点、D 低点,理想 B = A - 0.786*(A-X)。枢轴用 struct 存时间、价格与 isHigh 标记,全量塞进动态数组 pivots[] 按时间排。 为避免重绘反复触发,代码用 g_patternFormationBar 与 g_lockedPatternX 锁死已成型形态——成型 K 线索引为 -1 表示当前无锁定。外汇与贵金属杠杆高、蝴蝶形态失效概率不低,实盘前务必在 MT5 策略测试器用历史数据验证容差与手数组合。 下方片段展示了头文件引用、参数声明与枢轴结构的写法,可直接复制到 MQ5 文件头部做基线。

MQL5 / C++
class="macro">#class="kw">property link      "https:class=class="str">"cmt">//t.me/Forex_Algo_Trader"
class="macro">#class="kw">property version   "class="num">1.00"
class="macro">#class="kw">property description "This EA trades based on Butterfly Strategy"
class="macro">#class="kw">property strict
class=class="str">"cmt">//--- Include the trading library for order functions
class="macro">#include <Trade\Trade.mqh>  class=class="str">"cmt">//--- Include Trade library
CTrade obj_Trade;  class=class="str">"cmt">//--- Instantiate a obj_Trade object
class=class="str">"cmt">//--- Input parameters for user configuration
input class="type">int     PivotLeft     = class="num">5;       class=class="str">"cmt">//--- Number of bars to the left for pivot check
input class="type">int     PivotRight    = class="num">5;       class=class="str">"cmt">//--- Number of bars to the right for pivot check
input class="type">class="kw">double  Tolerance     = class="num">0.10;    class=class="str">"cmt">//--- Allowed deviation(class="num">10% of XA move)
input class="type">class="kw">double  LotSize       = class="num">0.01;    class=class="str">"cmt">//--- Lot size for new orders
input class="type">bool    AllowTrading  = true;    class=class="str">"cmt">//--- Enable or disable trading
class=class="str">"cmt">//---------------------------------------------------------------------------
class=class="str">"cmt">//--- Butterfly pattern definition:
class=class="str">"cmt">//
class=class="str">"cmt">//--- Bullish Butterfly:
class=class="str">"cmt">//---   Pivots(X-A-B-C-D): X swing high, A swing low, B swing high, C swing low, D swing high.
class=class="str">"cmt">//---   Normally XA > class="num">0; Ideal B = A + class="num">0.786*(X-A); Legs within specified ranges.
class=class="str">"cmt">//
class=class="str">"cmt">//--- Bearish Butterfly:
class=class="str">"cmt">//---   Pivots(X-A-B-C-D): X swing low, A swing high, B swing low, C swing high, D swing low.
class=class="str">"cmt">//---   Normally XA > class="num">0; Ideal B = A - class="num">0.786*(A-X); Legs within specified ranges.
class=class="str">"cmt">//---------------------------------------------------------------------------
class=class="str">"cmt">//--- Structure for a pivot point
class="kw">struct Pivot {
   class="type">class="kw">datetime time;   class=class="str">"cmt">//--- Bar time of the pivot
   class="type">class="kw">double   price;  class=class="str">"cmt">//--- Pivot price(High for swing high, low for swing low)
   class="type">bool     isHigh; class=class="str">"cmt">//--- True if swing high; false if swing low
};
class=class="str">"cmt">//--- Global dynamic array for storing pivots in chronological order
Pivot pivots[];  class=class="str">"cmt">//--- Declare a dynamic array to hold identified pivot points
class=class="str">"cmt">//--- Global variables to lock in a pattern(avoid trading on repaint)
class="type">int     g_patternFormationBar = -class="num">1;    class=class="str">"cmt">//--- Bar index where the pattern was formed(-class="num">1 means none)
class="type">class="kw">datetime g_lockedPatternX     = class="num">0;     class=class="str">"cmt">//--- The key X pivot time for the locked pattern

「把三角与趋势线封装成可复用画图函数」

在 MT5 自定义指标或 EA 里反复手写 ObjectCreate 会很拖累可读性,把图形绘制收拢成几个 helper 函数是更稳的做法。下面这段逻辑把三角形、趋势线、水平虚线各自独立成函数,调用时只传坐标和样式参数即可。 三角形函数接收三个时间-价格点 (t1,p1)、(t2,p2)、(t3,p3),用 OBJ_TRIANGLE 创建后依次设颜色、实线、线宽、是否填充、是否背景。外汇与贵金属图表波动剧烈,填充三角若设 OBJPROP_BACK=true 可能盖住 K 线,建议回测时先保持 back=0 观察层级。 趋势线函数只连两点,style 参数开放给调用方传 STYLE_SOLID 或 STYLE_DASH 等;水平虚线函数则固定两端价格相等、强制 STYLE_DOT,适合标 pivot 位。开 MT5 按 F4 粘入这些函数,改 p1/p2 数值就能直接验证渲染位置是否符合预期。

MQL5 / C++
if(ObjectCreate(class="num">0, name, OBJ_TRIANGLE, class="num">0, t1, p1, t2, p2, t3, p3)) {
      class=class="str">"cmt">//--- Set the triangle&class="macro">#x27;s class="type">class="kw">color
      ObjectSetInteger(class="num">0, name, OBJPROP_COLOR, cl);
      class=class="str">"cmt">//--- Set the triangle&class="macro">#x27;s line style to solid
      ObjectSetInteger(class="num">0, name, OBJPROP_STYLE, STYLE_SOLID);
      class=class="str">"cmt">//--- Set the line width of the triangle
      ObjectSetInteger(class="num">0, name, OBJPROP_WIDTH, width);
      class=class="str">"cmt">//--- Determine if the triangle should be filled
      ObjectSetInteger(class="num">0, name, OBJPROP_FILL, fill);
      class=class="str">"cmt">//--- Set whether the object is drawn in the background
      ObjectSetInteger(class="num">0, name, OBJPROP_BACK, back);
   }
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Helper: Draw a trend line                                      |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void DrawTrendLine(class="type">class="kw">string name, class="type">class="kw">datetime t1, class="type">class="kw">double p1, class="type">class="kw">datetime t2, class="type">class="kw">double p2, class="type">class="kw">color cl, class="type">int width, class="type">int style) {
   class=class="str">"cmt">//--- Create a trend line object connecting two points
   if(ObjectCreate(class="num">0, name, OBJ_TREND, class="num">0, t1, p1, t2, p2)) {
      class=class="str">"cmt">//--- Set the trend line&class="macro">#x27;s class="type">class="kw">color
      ObjectSetInteger(class="num">0, name, OBJPROP_COLOR, cl);
      class=class="str">"cmt">//--- Set the trend line&class="macro">#x27;s style(solid, dotted, etc.)
      ObjectSetInteger(class="num">0, name, OBJPROP_STYLE, style);
      class=class="str">"cmt">//--- Set the width of the trend line
      ObjectSetInteger(class="num">0, name, OBJPROP_WIDTH, width);
   }
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Helper: Draw a dotted trend line                               |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void DrawDottedLine(class="type">class="kw">string name, class="type">class="kw">datetime t1, class="type">class="kw">double p, class="type">class="kw">datetime t2, class="type">class="kw">color lineColor) {
   class=class="str">"cmt">//--- Create a horizontal trend line at a fixed price level with dotted style
   if(ObjectCreate(class="num">0, name, OBJ_TREND, class="num">0, t1, p, t2, p)) {
      class=class="str">"cmt">//--- Set the dotted line&class="macro">#x27;s class="type">class="kw">color
      ObjectSetInteger(class="num">0, name, OBJPROP_COLOR, lineColor);
      class=class="str">"cmt">//--- Set the line style to dotted
      ObjectSetInteger(class="num">0, name, OBJPROP_STYLE, STYLE_DOT);
      class=class="str">"cmt">//--- Set the line width to class="num">1

常见问题

可以把形态识别逻辑写成EA,让其在K线收盘后自动扫描X、A、B、C、D点比例,命中即报警或下单,省去肉眼刷图。
网格靠加仓摊平,遇单边易爆仓;蝴蝶谐波按几何比例找反转区,止损位明确,更适配波段与贵金属的高波动环境。
小布盯盘的AIGC已内置形态诊断,打开对应品种页即可看到实时蝴蝶识别与概率提示,不用自己写EA也能先验证形态有效性。
常见判定为B回撤XA的78.6%内,D拓展XA的127%~161.8%;EA里可设容差±3%避免硬卡数值错过信号。
把画线逻辑包成带颜色、时点参数的函数,每次识别到形态只传坐标调用,既能复用也方便切换品种调试。