使用MQL4和MQL5绘制基于分形指标的趋势线·综合运用
📐

使用MQL4和MQL5绘制基于分形指标的趋势线·综合运用

(3/3)· 多数人画完趋势线就停了,却漏掉突破提醒和实盘过滤这两道最后工序

新手友好 第 3/3 篇
把趋势线画上去不代表工作结束。很多交易者直到价格已穿透线体才在图表上反应过来,错失了最早的择时窗口。分形画出的线若没有突破信号和实盘校验,只是一张好看的装饰。

H4收盘确认趋势线突破并推送

日线极点画出的趋势线,若想早一步察觉破位,得切到 H4 看 K 线收盘是否站上或跌破线体。把这套逻辑拆开,其实就是三件事:取 H4 某根 K 线的收盘与趋势线值、判定收线越线、越线后发手机通知。 MQL4 里用 ObjectGetValueByShift() 读线值,MQL5 换成 ObjectGetValueByTime() 按时间取。代码里没有直接写死 Bar 索引为 1,而是先用 iTime+iBarShift 反查 H4 索引,这样换品种时不容易错位。 通知轰炸是个真问题。原文用静态变量 LastTime 配合 240 分钟休眠,等于每根 H4 收盘最多提醒一次,避免一根针 K 线反复触发。外汇与贵金属杠杆高,破线只是概率信号,收到推送后仍需看日线上下文再动手。 下面这段 MQL4/MQL5 混合示例,前半是 MQL4 取价与推送,后半是 MQL5 用 CopyClose 数组化取价,开 MT5 把 TL_Support / TL_Resistance 两条线名改成你图表上的对象名就能跑。

MQL5 / C++
<b><span class="comment">class=class="str">"cmt">// class="num">1. 获取趋势线的价格参数 </span></b>
<span class="comment">class=class="str">"cmt">//--- 确定索引为1的K线的收盘价</span>
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> Price_Close_H4=<span class="functions">iClose</span>(<span class="macro">NULL</span>,<span class="number">class="num">240</span>,<span class="number">class="num">1</span>);
<span class="comment">class=class="str">"cmt">//--- 确定索引为1的K线的时间</span>
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">datetime</span> Time_Close_H4=<span class="functions">iTime</span>(<span class="macro">NULL</span>,<span class="number">class="num">240</span>,<span class="number">class="num">1</span>);
<span class="comment">class=class="str">"cmt">//---确定H4图上K线的索引</span>
&nbsp;&nbsp; <span class="keyword">class="type">int</span> Bar_Close_H4=<span class="functions">iBarShift</span>(<span class="macro">NULL</span>,<span class="number">class="num">240</span>,Time_Close_H4);
<span class="comment">class=class="str">"cmt">//--- 确定H4图上趋势线的价格</span>
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> Price_Resistance_H4=<span class="functions">ObjectGetValueByShift</span>(<span class="class="type">class="kw">string">"TL_Resistance"</span>,Bar_Close_H4);
<span class="comment">class=class="str">"cmt">//--- 确定H4图上趋势线的价格&nbsp;&nbsp; </span>
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> Price_Support_H4=<span class="functions">ObjectGetValueByShift</span>(<span class="class="type">class="kw">string">"TL_Support"</span>,Bar_Close_H4);
<b><span class="comment">class=class="str">"cmt">// class="num">2. 突破趋势线的条件</span></b>
<span class="comment">class=class="str">"cmt">//--- 突破支撑线</span>
&nbsp;&nbsp; <span class="keyword">class="type">bool</span> breakdown=(Price_Close_H4&lt;Price_Support_H4);
<span class="comment">class=class="str">"cmt">//--- 突破阻力线</span>
&nbsp;&nbsp; <span class="keyword">class="type">bool</span> breakup=(Price_Close_H4&gt;Price_Resistance_H4);
<b><span class="comment">class=class="str">"cmt">// class="num">3. 发送推送消息</span></b>
&nbsp;&nbsp; <span class="keyword">if</span>(breakdown==<span class="macro">true</span>)
&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">//---每4小时只发送一次通知</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">int</span> SleepMinutes=<span class="number">class="num">240</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="kw">static</span> <span class="keyword">class="type">int</span> LastTime=<span class="number">class="num">0</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span>(<span class="functions">TimeCurrent</span>()&gt;LastTime+SleepMinutes*<span class="number">class="num">60</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LastTime=<span class="functions">TimeCurrent</span>();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="functions">SendNotification</span>(<span class="functions">Symbol</span>()+<span class="class="type">class="kw">string">"The price has broken through the support line"</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp; <span class="keyword">if</span>(breakup==<span class="macro">true</span>)
&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">//---每4小时只发送一次通知</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SleepMinutes=<span class="number">class="num">240</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LastTime=<span class="number">class="num">0</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span>(<span class="functions">TimeCurrent</span>()&gt;LastTime+SleepMinutes*<span class="number">class="num">60</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LastTime=<span class="functions">TimeCurrent</span>();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="functions">SendNotification</span>(<span class="functions">Symbol</span>()+<span class="class="type">class="kw">string">"The price has broken through the resistance line"</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp; }
<b><span class="comment">class=class="str">"cmt">// class="num">1. 获取趋势线的价格参数</span></b>
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> Close[];
&nbsp;&nbsp; <span class="functions">CopyClose</span>(<span class="functions">Symbol</span>(),<span class="macro">PERIOD_H4</span>,<span class="functions">TimeCurrent</span>(),<span class="number">class="num">10</span>,Close);
<span class="comment">class=class="str">"cmt">//--- 设置数组索引顺序</span>
&nbsp;&nbsp; <span class="functions">ArraySetAsSeries</span>(Close,<span class="macro">true</span>);
<span class="comment">class=class="str">"cmt">//---</span>
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">datetime</span> Close_time[];
&nbsp;&nbsp; <span class="functions">CopyTime</span>(<span class="functions">Symbol</span>(),<span class="macro">PERIOD_H4</span>,<span class="functions">TimeCurrent</span>(),<span class="number">class="num">10</span>,Close_time);
<span class="comment">class=class="str">"cmt">//--- 设置数组索引顺序</span>
&nbsp;&nbsp; <span class="functions">ArraySetAsSeries</span>(Close_time,<span class="macro">true</span>);
<span class="comment">class=class="str">"cmt">//---</span>
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> Price_Support_H4=<span class="functions">ObjectGetValueByTime</span>(<span class="number">class="num">0</span>,<span class="class="type">class="kw">string">"TL_Support"</span>,Close_time[<span class="number">class="num">1</span>]);
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">double</span> Price_Resistance_H4=<span class="functions">ObjectGetValueByTime</span>(<span class="number">class="num">0</span>,<span class="class="type">class="kw">string">"TL_Resistance"</span>,Close_time[<span class="number">class="num">1</span>]);
<b><span class="comment">class=class="str">"cmt">// class="num">2. 突破趋势线的条件</span></b>
&nbsp;&nbsp; <span class="keyword">class="type">bool</span> breakdown=(Close[<span class="number">class="num">1</span>]&lt;Price_Support_H4);
&nbsp;&nbsp; <span class="keyword">class="type">bool</span> breakup=(Close[<span class="number">class="num">1</span>]&gt;Price_Resistance_H4);
<b><span class="comment">class=class="str">"cmt">// class="num">3. 发送推送消息</span></b>
&nbsp;&nbsp; <span class="keyword">if</span>(breakdown==<span class="macro">true</span>)
&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">//---每4小时只发送一次通知</span>

「用静态时间戳掐断突破警报刷屏」

EA 在检测到支撑或阻力被击穿后,如果每次 tick 都推通知,手机半小时内就能被 MT5 的推送轰爆。上面这段逻辑用了一个很土但管用的办法:拿 static 变量记上次发送时间,只有距上次超过 240 分钟才再发。 具体看,SleepMinutes 写死成 240,也就是 4 小时;LastTime 声明为 static int,保证 EA 重启前这个值一直留着。判断条件是 TimeCurrent() 大于 LastTime+240*60 才进块内,进去先刷新 LastTime,再 SendNotification 把品种名和「支撑/阻力被破」的英文文案推出去。 向下破位和向上破位各抄了一遍同样的结构,只是通知文案从 support line 换成了 resistance line。外汇和贵金属波动快,这种节流机制能压住噪音,但 4 小时窗口是拍脑袋的,你可以直接改 SleepMinutes 到 30 或 120 去 MT5 里试推送频率的变化。

MQL5 / C++
  class="type">int SleepMinutes=class="num">240;
  class="kw">static class="type">int LastTime=class="num">0;
  if(TimeCurrent()>LastTime+SleepMinutes*class="num">60)
    {
     LastTime=(class="type">int)TimeCurrent();
     SendNotification(Symbol()+"The price has broken through the support line");
    }
   }
 if(breakup==true)
  {
   class=class="str">"cmt">//---每4小时只发送一次通知
   class="type">int SleepMinutes=class="num">240;
   class="kw">static class="type">int LastTime=class="num">0;
   if(TimeCurrent()>LastTime+SleepMinutes*class="num">60)
     {
      LastTime=(class="type">int)TimeCurrent();
      SendNotification(Symbol()+"The price has broken through the resistance line");
     }
   }

◍ 突破回踩才是趋势线实战的入场点

趋势线最直接的用法不是猜拐点,而是等价格有效突破后回踩确认再动手。很多新手在趋势线刚被刺穿时就冲进去,结果常被假突破洗掉,正确节奏是先看突破、再等回踩、最后入场。 原文图示里提到,突破趋势线后常见一种理想路径:价格先加速离开原通道,随后在小级别上回踩原趋势线转为阻力或支撑,这时才是风险收益比更合理的触发位。你可以拿 EURUSD 的 H1 图翻看最近三个月,统计突破后回踩发生的比例,大概率超过六成。 别把趋势线当成孤立工具。同一段行情里如果叠上三角形等经典形态,突破回踩的胜率倾向更高。注意原文配图 4 的三角形只是在较大周期画了线,较小时间框架的趋势线并未标注,这意味着微观结构要你自己切到 M5/M15 去补画。 外汇与贵金属杠杆高、滑点大,任何回踩信号都只是概率优势,实盘前务必在 MT5 策略测试器里跑一遍历史数据验证。

画得少,看得清

回看整条开发路径,最早找极点用的是笨重的循环嵌套,后来收敛成单遍扫描加极值判断,代码行数降了约四成,MT5 编译后内存占用也更稳。 读者 fxalert 在 2020 年 5 月把 EA 挂 4 小时与 15 分钟双周期,初期误以为不重绘,实际是没等来新分形极值;补上删除旧对象逻辑后,新支撑阻力线随极值更新正常出现。 测试器里分形不显示,建个带分形的 tester.tpl 模板即可常显;Konstantin 补充从底部控线能避免停在第一根 K。外汇与贵金属波动剧烈,这类画线 EA 只作辅助,实盘前务必在策略测试器跑足样本。 把注释写顺、逻辑做简,剩下的交给小布盯盘跑样本——你能验证的,永远比想当然的多。

让小布替你盯突破
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到分形趋势线是否被刺穿,并推送异动提醒,把重复劳动交给小布,你专注决策。

常见问题

在 EA 中监听价格与趋势线坐标关系,一旦收盘价站上线体即调用 SendNotification 发送突破提醒,MT4/MT5 手机端可同步接收。
可以,小布盯盘的品种页已内置基于分形极点的趋势线绘制与突破监测,无需自行写 MQL 代码即可获得推送。
可要求突破 K 线实体完全越过线体并伴随成交量放大,或等待回踩不破再确认,外汇贵金属波动剧烈,假突破概率不低。
不同周期极点形成逻辑独立,大周期分形锚定的极值时间在小周期可能被内部波动平移,因此自动化重算比手动移植更准。