学习如何基于 DeMarker 设计交易系统·进阶篇
把 DeMarker 拆成三套可跑的判定逻辑
做 DeMarker 交易系统前,先别急着写 EA。把思路落成蓝图,等于给 MT5 里的 iDeMarker 调用先定好输入和分支,后面编码只是填空。 第一套看强度:取当期 DeMarker 值与最近 5 根 K 线的均值比大小。当期 > 均值,图表注释「DeMarker 强劲」并打印两值;反之注释「DeMarker 疲软」。这套逻辑在 5 分钟图上对贵金属波动的钝化较明显,EURUSD 上反应更跟手。 第二套抓超买超卖:连续比三个数——当期值、0.70、0.30。≥0.70 注释「超买」并吐出数值,≤0.30 注释「超卖」。外汇与贵金属杠杆高,0.70/0.30 只是统计边界,反转概率大但不代表一定回头。 第三套找背离:比四个值。价格新高而 DeMarker 走低,打「看跌背离」并列出高低点与指标值;价格新低而指标走高,打「看涨背离」。实盘里背离信号在 H1 以上周期假突破更少,建议先开 MT5 用 EURUSD 的 H1 手动核对一次。
「把 DeMarker 跑成 MT5 自动信号」
想让 DeMarker 在 MT5 里自己报信号,先搭一个基础 EA:取指标当期值,往图表右上角写注释。下面这段代码就是地基,后面三种策略都只在它上面改条件。 [CODE] double deMarkerArray[]; ArraySetAsSeries(deMarkerArray,true); int deMarkerDef = iDeMarker(_Symbol,_Period,14); CopyBuffer(deMarkerDef,0,0,3,deMarkerArray); double deMarkerVal = NormalizeDouble(deMarkerArray[0],6); Comment("DeMarker Value is ",deMarkerVal); [/CODE] 逐行拆:第1行建 double 数组装小数;第2行 ArraySetAsSeries 打 AS_SERIES 标,让 [0] 永远是最新值;第3行 iDeMarker 拿句柄,品种用 _Symbol、周期用 _Period、均化周期写死 14;第4行 CopyBuffer 从缓冲区 0 复制 3 个值进数组;第5行 NormalizeDouble 保留 6 位小数定出当期值;第6行 Comment 把值喷到图表上。 策略一「强度」:在基础代码后,再取最后 5 个值算均值 deMarkerAvgVal,若当期值 > 均值,图表注释「DeMarker 强劲」,反之注「疲软」。外汇与贵金属杠杆高,信号仅描述概率倾斜,不构成方向保证。 策略二「超买超卖」:条件换成数值边界——当期 ≤0.30 注「超卖」,≥0.70 注「超买」,介于两者之间注「无信号」。0.30 / 0.70 是 DeMarker 经典阈值,实盘可据品种波动微调。 策略三「背离」:另开 MqlRates 数组存价格,比高低点同时比 DeMarker 前后值。看涨背离 = 价格新低而 DeMarker 抬高;看跌背离 = 价格新高而 DeMarker 走低。把 EA 拖上图,左上角即出「当期高点 / 前期高点 / 两期 DeMarker 值」四类数字,肉眼可复核。
class="type">class="kw">double deMarkerArray[]; ArraySetAsSeries(deMarkerArray,true); class="type">int deMarkerDef = iDeMarker(_Symbol,_Period,class="num">14); CopyBuffer(deMarkerDef,class="num">0,class="num">0,class="num">3,deMarkerArray); class="type">class="kw">double deMarkerVal = NormalizeDouble(deMarkerArray[class="num">0],class="num">6); Comment("DeMarker Value is ",deMarkerVal);
◍ 用前 5 根 K 线均值判 DeMarker 强弱
这段脚本在 OnTick 里取当前品种、当前周期的 DeMarker(14),把数组设为时间序列后拷贝最近 6 根缓冲值。deMarkerVal 是 0 号(最新)柱的值,Val1~Val5 则是前 5 根,精度统一压到 4 位小数。 强弱判定没有用固定阈值,而是拿最新值去比前 5 根的平均值:deMarkerAvgVal = (Val1+Val2+Val3+Val4+Val5)/5。若最新值大于均值,终端右下角提示 DeMarker is strong;反之提示 weak,并同时打印当前值与均值。 外汇与贵金属杠杆高,DeMarker 只是动能摆荡工具,强/弱信号仅代表近期买压或卖压倾向占优,不代表价格必然反转或延续。开 MT5 把下面代码挂 EURUSD 的 M15,跑几天就能看到强弱切换的频率。 别把均值当拐点:前 5 根均值只是平滑噪声,趋势市里最新值长期偏离均值属正常,盲目反手容易被扫。
class="type">void OnTick() { class="type">class="kw">double deMarkerArray[]; ArraySetAsSeries(deMarkerArray,true); class="type">int deMarkerDef = iDeMarker(_Symbol,_Period,class="num">14); CopyBuffer(deMarkerDef,class="num">0,class="num">0,class="num">6,deMarkerArray); class="type">class="kw">double deMarkerVal = NormalizeDouble(deMarkerArray[class="num">0],class="num">4); class="type">class="kw">double deMarkerVal1 = NormalizeDouble(deMarkerArray[class="num">1],class="num">4); class="type">class="kw">double deMarkerVal2 = NormalizeDouble(deMarkerArray[class="num">2],class="num">4); class="type">class="kw">double deMarkerVal3 = NormalizeDouble(deMarkerArray[class="num">3],class="num">4); class="type">class="kw">double deMarkerVal4 = NormalizeDouble(deMarkerArray[class="num">4],class="num">4); class="type">class="kw">double deMarkerVal5 = NormalizeDouble(deMarkerArray[class="num">5],class="num">4); class="type">class="kw">double deMarkerAvgVal = (deMarkerVal1+deMarkerVal2+deMarkerVal3+deMarkerVal4+deMarkerVal5)/class="num">5; if(deMarkerVal>deMarkerAvgVal) { Comment("DeMarker is strong","\n", "Current DeMarker Value is ",deMarkerVal,"\n", "AVG DeMarker Value is ",deMarkerAvgVal); } if(deMarkerVal<deMarkerAvgVal) { Comment("DeMarker is weak","\n", "Current DeMarker Value is ",deMarkerVal,"\n", "AVG DeMarker Value is ",deMarkerAvgVal); } }
用均值与阈值给 DeMarker 定强弱边界
把最近 5 根 K 线的 DeMarker 值各取到 4 位小数,再求简单平均,就得到一条随行情滑动的「中轴」。当实时 deMarkerVal 高于这条均值,价格动能倾向偏强;低于均值则倾向偏弱。这个对比不靠固定阈值,而是让市场自己说出「相对强弱」。 代码里先取数组第 3、4、5 号元素(按序列倒序即往前第 3~5 根)做 NormalizeDouble 到 4 位,再和前两根凑齐 5 根除以 5。注意这里用的精度是 4,而 OnTick 里实时值是 6 位,跨段比较时小数点位数不一致可能引入微小误差,实盘建议统一精度。 另一边,OnTick 中直接用 iDeMarker(_Symbol,_Period,14) 取 14 周期指标,CopyBuffer 拿 3 个值,实时值留 6 位小数。硬阈值写在 0.30 与 0.70:≤0.30 倾向超卖,≥0.70 倾向超买,中间段只回显数值不判断。外汇与贵金属杠杆高,DeMarker 仅作动能参考,反向刺穿阈值后延续原趋势的概率并不低。 把两段逻辑拼进同一个 EA,你能在 MT5 里同时看到「均值偏离」和「阈值状态」两组提示。先拿 EURUSD 的 M15 跑一周,记录 0.30 下方反弹与假突破的次数比,再决定是否把均值窗口从 5 改成 10。
class="type">class="kw">double deMarkerVal3 = NormalizeDouble(deMarkerArray[class="num">3],class="num">4); class="type">class="kw">double deMarkerVal4 = NormalizeDouble(deMarkerArray[class="num">4],class="num">4); class="type">class="kw">double deMarkerVal5 = NormalizeDouble(deMarkerArray[class="num">5],class="num">4); class="type">class="kw">double deMarkerAvgVal = (deMarkerVal1+deMarkerVal2+deMarkerVal3+deMarkerVal4+deMarkerVal5)/class="num">5; if(deMarkerVal>deMarkerAvgVal) { Comment("DeMarker is strong","\n", "Current DeMarker Value is ",deMarkerVal,"\n", "AVG DeMarker Value is ",deMarkerAvgVal); } if(deMarkerVal<deMarkerAvgVal) { Comment("DeMarker is weak","\n", "Current DeMarker Value is ",deMarkerVal,"\n", "AVG DeMarker Value is ",deMarkerAvgVal); } class="type">void OnTick() { class="type">class="kw">double deMarkerArray[]; ArraySetAsSeries(deMarkerArray,true); class="type">int deMarkerDef = iDeMarker(_Symbol,_Period,class="num">14); CopyBuffer(deMarkerDef,class="num">0,class="num">0,class="num">3,deMarkerArray); class="type">class="kw">double deMarkerVal = NormalizeDouble(deMarkerArray[class="num">0],class="num">6); if(deMarkerVal<=class="num">0.30) { Comment("Oversold","\n", "DeMarker Value is ",deMarkerVal); } if(deMarkerVal>=class="num">0.70) { Comment("Overbought","\n", "DeMarker Value is ",deMarkerVal); } if(deMarkerVal>class="num">0.30 && deMarkerVal<class="num">0.70) { Comment("DeMarker Value is ",deMarkerVal); } }