使用MQL4和MQL5绘制基于分形指标的趋势线·综合运用
(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 两条线名改成你图表上的对象名就能跑。
<b><span class="comment">class=class="str">"cmt">// class="num">1. 获取趋势线的价格参数 </span></b> <span class="comment">class=class="str">"cmt">//--- 确定索引为1的K线的收盘价</span> <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> <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> <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> <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图上趋势线的价格 </span> <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> <span class="keyword">class="type">bool</span> breakdown=(Price_Close_H4<Price_Support_H4); <span class="comment">class=class="str">"cmt">//--- 突破阻力线</span> <span class="keyword">class="type">bool</span> breakup=(Price_Close_H4>Price_Resistance_H4); <b><span class="comment">class=class="str">"cmt">// class="num">3. 发送推送消息</span></b> <span class="keyword">if</span>(breakdown==<span class="macro">true</span>) { <span class="comment">class=class="str">"cmt">//---每4小时只发送一次通知</span> <span class="keyword">class="type">int</span> SleepMinutes=<span class="number">class="num">240</span>; <span class="keyword">class="kw">static</span> <span class="keyword">class="type">int</span> LastTime=<span class="number">class="num">0</span>; <span class="keyword">if</span>(<span class="functions">TimeCurrent</span>()>LastTime+SleepMinutes*<span class="number">class="num">60</span>) { LastTime=<span class="functions">TimeCurrent</span>(); <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>); } } <span class="keyword">if</span>(breakup==<span class="macro">true</span>) { <span class="comment">class=class="str">"cmt">//---每4小时只发送一次通知</span> SleepMinutes=<span class="number">class="num">240</span>; LastTime=<span class="number">class="num">0</span>; <span class="keyword">if</span>(<span class="functions">TimeCurrent</span>()>LastTime+SleepMinutes*<span class="number">class="num">60</span>) { LastTime=<span class="functions">TimeCurrent</span>(); <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>); } } <b><span class="comment">class=class="str">"cmt">// class="num">1. 获取趋势线的价格参数</span></b> <span class="keyword">class="type">class="kw">double</span> Close[]; <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> <span class="functions">ArraySetAsSeries</span>(Close,<span class="macro">true</span>); <span class="comment">class=class="str">"cmt">//---</span> <span class="keyword">class="type">class="kw">datetime</span> Close_time[]; <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> <span class="functions">ArraySetAsSeries</span>(Close_time,<span class="macro">true</span>); <span class="comment">class=class="str">"cmt">//---</span> <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>]); <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> <span class="keyword">class="type">bool</span> breakdown=(Close[<span class="number">class="num">1</span>]<Price_Support_H4); <span class="keyword">class="type">bool</span> breakup=(Close[<span class="number">class="num">1</span>]>Price_Resistance_H4); <b><span class="comment">class=class="str">"cmt">// class="num">3. 发送推送消息</span></b> <span class="keyword">if</span>(breakdown==<span class="macro">true</span>) { <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 里试推送频率的变化。
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 只作辅助,实盘前务必在策略测试器跑足样本。 把注释写顺、逻辑做简,剩下的交给小布盯盘跑样本——你能验证的,永远比想当然的多。