您应当知道的 MQL5 向导技术(第 57 部分):搭配移动平均和随机振荡器的监督训练·综合运用
📘

您应当知道的 MQL5 向导技术(第 57 部分):搭配移动平均和随机振荡器的监督训练·综合运用

第 3/3 篇

◍ 极端随机拐点配均线方向的实盘失效点

形态-7 的思路是用随机振荡器 %K 跌到 10 以下出现 n 形转向、或涨过 90 出现 u 形逆转,再叠加上下倾斜均线来定多空。买入要求价格站上向上均线且随机从极端低位翻上,卖出则要求价格跌破向下均线且随机从 90 以上翻下。 把这套逻辑写成 MQL5 后跑前向漫游测试,结果并不乐观:模型只下了空头单,全年没能通过一年期前向验证。输出是 0.0~1.0 的标量,所有预测都低于 0.5,说明网络几乎把信号全判成非多头。 单侧交易加全面看空,在外汇和贵金属这种高波动品种上尤其危险,很容易在趋势反转时被反复打脸。原文也提到,用更大数据集重训才可能纠偏,小样本下这个形态先当反面教材看。 下面这段是映射代码,逐行看逻辑比读文字快:先确认索引 7 且三类缓冲区都取到足够数据;随后四个 _v 分别装「价格站上多头均线」「随机低位 n 形」「随机高位 u 形」「价格跌破空头均线」的 0/1 标记。

MQL5 / C++
else if(Index == class="num">7)
{  if(C.GetData(T, class="num">2, _c) >= class="num">2 && CopyBuffer(M.Handle(), class="num">0, T, class="num">2, _ma) >= class="num">2 && CopyBuffer(S.Handle(), class="num">0, T, class="num">3, _sto_k) >= class="num">3)
   {  _v[class="num">0] = ((_ma[class="num">0] > _ma[class="num">1] && _c[class="num">0] > _ma[class="num">0]) ? class="num">1.0f : class="num">0.0f);
      _v[class="num">1] = ((_sto_k[class="num">0] > _sto_k[class="num">1] && _sto_k[class="num">1] < _sto_k[class="num">2] && _sto_k[class="num">2] <= class="num">10.0) ? class="num">1.0f : class="num">0.0f);
      _v[class="num">2] = ((_sto_k[class="num">0] < _sto_k[class="num">1] && _sto_k[class="num">1] > _sto_k[class="num">2] && _sto_k[class="num">2] >= class="num">90.0) ? class="num">1.0f : class="num">0.0f);
      _v[class="num">3] = ((_ma[class="num">0] < _ma[class="num">1] && _c[class="num">0] < _ma[class="num">0]) ? class="num">1.0f : class="num">0.0f);
   }
}

随机与均线双条件如何喂给形态网络

把随机振荡器 50 阈值突破和价格穿越均线两个动作拆开看,比硬等两者同根同根收盘要实用。形态-8 的输入向量现在更可能登记至少一组看涨或看跌条件,对训练收敛和部署时的适应性都有帮助——因为即便只有一个指标先亮信号,网络也能给出预测倾向,而不是完全沉默。 前向漫游测试里这套组合能走通,概率上算鼓舞,但别急着上实盘。测试用了目标价了结、没挂止损;止损不保证离场价,但完全没有应对失败交易的策略肯定不行。训练窗口是最近一年、测试放次年,周期偏短,更长周期加高品质经纪商点差数据才更稳。外汇和贵金属杠杆高,这类未带风控的回测结果只作方法验证。 下面这段 MT5 逻辑是形态-8 在索引处的判定内核,注意它把均线和随机的上下穿分成了四个独立标记位:

MQL5 / C++
<span class="keyword">else</span> <span class="keyword">if</span>(Index == <span class="number">class="num">8</span>)
{&nbsp;&nbsp;<span class="keyword">if</span>(C.GetData(T, <span class="number">class="num">2</span>, _c) &gt;= <span class="number">class="num">2</span> &amp;&amp; <span class="functions">CopyBuffer</span>(M.Handle(), <span class="number">class="num">0</span>, T, <span class="number">class="num">2</span>, _ma) &gt;= <span class="number">class="num">2</span> &amp;&amp; <span class="functions">CopyBuffer</span>(S.Handle(), <span class="number">class="num">0</span>, T, <span class="number">class="num">2</span>, _sto_k) &gt;= <span class="number">class="num">2</span> &amp;&amp; <span class="functions">CopyBuffer</span>(S.Handle(), <span class="number">class="num">1</span>, T, <span class="number">class="num">2</span>, _sto_d) &gt;= <span class="number">class="num">2</span>)
&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;_v[<span class="number">class="num">0</span>] = ((_c[<span class="number">class="num">1</span>] &lt; _ma[<span class="number">class="num">1</span>] &amp;&amp; _c[<span class="number">class="num">0</span>] &gt; _ma[<span class="number">class="num">0</span>]) ? <span class="number">class="num">1.0</span>f : <span class="number">class="num">0.0</span>f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _v[<span class="number">class="num">1</span>] = ((_sto_k[<span class="number">class="num">1</span>] &lt; <span class="number">class="num">50.0</span> &amp;&amp; _sto_k[<span class="number">class="num">0</span>] &gt; <span class="number">class="num">50.0</span>) ? <span class="number">class="num">1.0</span>f : <span class="number">class="num">0.0</span>f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _v[<span class="number">class="num">2</span>] = ((_sto_k[<span class="number">class="num">1</span>] &gt; <span class="number">class="num">50.0</span> &amp;&amp; _sto_k[<span class="number">class="num">0</span>] &lt; <span class="number">class="num">50.0</span>) ? <span class="number">class="num">1.0</span>f : <span class="number">class="num">0.0</span>f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _v[<span class="number">class="num">3</span>] = ((_c[<span class="number">class="num">1</span>] &gt; _ma[<span class="number">class="num">1</span>] &amp;&amp; _c[<span class="number">class="num">0</span>] &lt; _ma[<span class="number">class="num">0</span>]) ? <span class="number">class="num">1.0</span>f : <span class="number">class="num">0.0</span>f);
&nbsp;&nbsp;&nbsp;}
}

「均线黏合配随机破位这条线索」

低波动阶段往往先于行情启动,把一条短周期与一条长周期均线在较宽窗口里挤到一块,就能先嗅到这种安静。等随机振荡器的动量从一侧猛穿中线,突破的时点才可能浮现:短均线压在长均线之上、随机K线由45下方弹到55上方,偏多概率更大;反过来短均线在长均线之下、随机由55上方摔到45下方,则偏空倾向更强。 这套识别逻辑在回测网里被标为形态-9,它能双向开仓,但前向漫游测试显示没有明显分腿优势。等权口径下它不值得优先深挖,不过你若愿意多跑几轮样本外检验,结论可能随品种和周期变动。 下面这段判定代码可直接塞进 MT5 自定义指标里验证,重点看四个向量的赋值条件。 别把中线阈值当死规矩 随机穿50只是原文思路的简化,代码实际用了45/55缓冲带过滤毛刺。EURUSD 这类高杠杆贵金属以外品种也适用,但外汇与贵金属波动突变频繁,实盘前先用策略测试器跑三个月 tick 数据。

MQL5 / C++
<span class="keyword">else</span> <span class="keyword">if</span>(Index == <span class="number">class="num">9</span>)
{&nbsp;&nbsp;<span class="keyword">if</span>(<span class="functions">CopyBuffer</span>(M.Handle(), <span class="number">class="num">0</span>, T, <span class="number">class="num">3</span>, _ma) &gt;= <span class="number">class="num">3</span> &amp;&amp; <span class="functions">CopyBuffer</span>(M_LAG.Handle(), <span class="number">class="num">0</span>, T, <span class="number">class="num">3</span>, _ma_lag) &gt;= <span class="number">class="num">3</span> &amp;&amp; <span class="functions">CopyBuffer</span>(S.Handle(), <span class="number">class="num">0</span>, T, <span class="number">class="num">2</span>, _sto_k) &gt;= <span class="number">class="num">2</span>)
&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;_v[<span class="number">class="num">0</span>] = ((_ma_lag[<span class="number">class="num">0</span>] &lt; _ma[<span class="number">class="num">0</span>] &amp;&amp; <span class="functions">fabs</span>(<span class="functions">fabs</span>(_ma_lag[<span class="number">class="num">2</span>] - _ma[<span class="number">class="num">2</span>]) - <span class="functions">fabs</span>(_ma_lag[<span class="number">class="num">0</span>] - _ma[<span class="number">class="num">0</span>])) &lt;= <span class="functions">fabs</span>(_ma[<span class="number">class="num">2</span>] - _ma[<span class="number">class="num">0</span>])) ? <span class="number">class="num">1.0</span>f : <span class="number">class="num">0.0</span>f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _v[<span class="number">class="num">1</span>] = ((_sto_k[<span class="number">class="num">1</span>] &lt;= <span class="number">class="num">45.0</span> &amp;&amp; _sto_k[<span class="number">class="num">0</span>] &gt;= <span class="number">class="num">55.0</span>) ? <span class="number">class="num">1.0</span>f : <span class="number">class="num">0.0</span>f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _v[<span class="number">class="num">2</span>] = ((_sto_k[<span class="number">class="num">1</span>] &gt;= <span class="number">class="num">55.0</span> &amp;&amp; _sto_k[<span class="number">class="num">0</span>] &lt;= <span class="number">class="num">45.0</span>) ? <span class="number">class="num">1.0</span>f : <span class="number">class="num">0.0</span>f);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _v[<span class="number">class="num">3</span>] = ((_ma_lag[<span class="number">class="num">0</span>] &gt; _ma[<span class="number">class="num">0</span>] &amp;&amp; <span class="functions">fabs</span>(<span class="functions">fabs</span>(_ma_lag[<span class="number">class="num">2</span>] - _ma[<span class="number">class="num">2</span>]) - <span class="functions">fabs</span>(_ma_lag[<span class="number">class="num">0</span>] - _ma[<span class="number">class="num">0</span>])) &lt;= <span class="functions">fabs</span>(_ma[<span class="number">class="num">2</span>] - _ma[<span class="number">class="num">0</span>])) ? <span class="number">class="num">1.0</span>f : <span class="number">class="num">0.0</span>f);
&nbsp;&nbsp;&nbsp;}
}

◍ 把工具请下神坛

我们没有把多种形态强行揉成一个统一系统,前几篇也提过,这种拼凑对交易者的形态功底要求极高,不同信号还可能互相抵消订单。即便用 Magic Number 分开跟踪,账户保证金的硬约束依然会把策略卡死。 随文给出了 10 个 ONNX 网络文件(57_0 到 57_9.onnx,单个约 263–265 KB)以及 SignalWZ_57.mqh、57_X.mqh、wz_57.mq5 等配套文件,直接在 MT5 向导里挂上就能跑形态推理,但外汇与贵金属杠杆高、回撤可能超预期,请先用模拟盘验证。 下一篇打算用强化学习在现有形态网络上继续叠层,不过那属于另一摊事。眼下你能做的,是把这堆文件下进终端,调一个 Magic Number 看看多形态并行时保证金怎么被吞掉。

常见问题

极端随机拐点配均线方向在黏合段失效概率高,建议先过滤均线发散度再入场,别只看随机死叉。
按时间轴对齐两指标状态打标签,只抽取同时满足方向+超买超卖的K线作为正样本,其余丢弃。
可以,小布能按你设定的均线周期与随机参数实时监控品种,黏合破位时直接推送提醒,免去手动刷图。
贵金属高波动下假破位多,建议叠加成交量或波幅门槛,单纯双条件胜率偏低,属高风险用法。
它只是概率过滤器而非预测器,实盘需配合仓位与止损,盲目信指标容易在震荡段连续磨损。