移动极小化极大:技术分析的新指标及其在 MQL5 中的实施·进阶篇
📘

移动极小化极大:技术分析的新指标及其在 MQL5 中的实施·进阶篇

第 2/2 篇

◍ 支撑阻力线的自动绘制逻辑

这段指标把上下轨缓冲区分开挂在独立子窗口,用两条 DRAW_LINE 分别染成 SeaGreen 与 BlueViolet,缓冲编号 0 和 1 各绑定 uSi、dSi 数据序列。PlotIndexSetInteger 里 PLOT_SHIFT 设为 -(m-1),意味着整条线向左位移 m-1 根 K 线,贴合 MiniMax 算法对局部极值的中位对齐习惯。 SR() 函数负责把「价格穿越均线」这件事变成图表上的水平线。向上情形遍历 i 从 n-2 到 0,当 uSi[i] < uSi_MA[i] 且前一柱 uSi[i+1] >= uSi_MA[i+1],判定为阻力成立,在 S[i] 价格画一条 LightSkyBlue 的不可选中背景线,终端同步 Print("Resistance at "+i)。 向下对称:dSi[i] < dSi_MA[i] 且 dSi[i+1] >= dSi_MA[i+1] 时画 Tomato 色支撑线。CopyClose 取 n+2*m 根收盘是为了确保循环边界不越界,cnt 仅作对象名后缀避免重名。 开 MT5 把这段塞进自定义指标,m 调成 5 看 EURUSD 小时图,外汇杠杆品种波动剧烈,水平线仅提示概率区域,不代表反转必现。

MQL5 / C++
for(i=class="num">0; i<n; i++) { class=class="str">"cmt">/* Print("i = "+i+" uSi = "+uSi[i]); */ result+=uSi[i]; }
Print("Result = "+ DoubleToString(result));
    class="macro">#class="kw">property indicator_separate_window
    class="macro">#class="kw">property indicator_buffers class="num">2
    class="macro">#class="kw">property indicator_plots class="num">2
    class="macro">#class="kw">property indicator_type1 DRAW_LINE
    class="macro">#class="kw">property indicator_type2 DRAW_LINE
    class="macro">#class="kw">property indicator_color1 SeaGreen
    class="macro">#class="kw">property indicator_color2 BlueViolet
    SetIndexBuffer(class="num">0,uSi,INDICATOR_DATA);
    SetIndexBuffer(class="num">1,dSi,INDICATOR_DATA);
    PlotIndexSetDouble(class="num">0,PLOT_EMPTY_VALUE,class="num">0.0);
    PlotIndexSetDouble(class="num">1,PLOT_EMPTY_VALUE,class="num">0.0);
    PlotIndexSetInteger(class="num">0,PLOT_SHIFT,-(m-class="num">1));
    PlotIndexSetInteger(class="num">1,PLOT_SHIFT,-(m-class="num">1));
class="type">void SR()
{
  class=class="str">"cmt">// if price goes through local maximum and crosses a moving average draw resistance
  class="type">int i, cnt=class="num">0;
  class="type">int rCnt=CopyClose(Symbol(),class="num">0,class="num">0,n+class="num">2*m,S);
  
  for (i=n-class="num">2; i>=class="num">0; i--)
  if (uSi[i]<uSi_MA[i] && uSi[i+class="num">1]>=uSi_MA[i+class="num">1])
  {
  Print("Resistance at " + i);
  CChartObjectHLine *line=new CChartObjectHLine();
  line.Create(class="num">0, "MiniMaxResistanceLine:"+IntegerToString(cnt), class="num">0, S[i]);
  line.Color(LightSkyBlue);
  line.Width(class="num">1);
  line.Background(true);
  line.Selectable(class="kw">false);
  cnt++;
  }
  class=class="str">"cmt">// if price goes through local minimum and crosses a moving average draw support
  for (i=n-class="num">2; i>=class="num">0; i--)
  if (dSi[i]<dSi_MA[i] && dSi[i+class="num">1]>=dSi_MA[i+class="num">1])
  {
  Print("Support at " + i);
  CChartObjectHLine *line=new CChartObjectHLine();
  line.Create(class="num">0, "MiniMaxSupportLine:"+IntegerToString(cnt), class="num">0, S[i]);
  line.Color(Tomato);
  line.Width(class="num">1);
  line.Background(true);
  line.Selectable(class="kw">false);
  cnt++;
  }
}

缓冲区与趋势着色段的落地写法

Moving Mini-Max 指标把 5 个缓冲区绑到独立子窗口:0/1 号存上下边界序列,2 号存颜色索引,3/4 号存上下箭头坐标。初始化时用 SetIndexBuffer 逐个挂接,类型分别是 INDICATOR_DATA 与 INDICATOR_COLOR_INDEX,少一个都会导致画图异常。 颜色索引段用三段 for 循环按 upind 与 dnind 的位置关系填 0 或 1,代表上涨/下跌区段;若 upind<dnind,则中间段标 1、两端标 0,反之对称处理。最后把两个极值点 trend[upind]、trend[dnind] 强制写成 2,对应黄颜色提醒,这是肉眼抓反转的第一信号。 箭头plot用 PlotIndexSetInteger 设 234/233 两个 Wingdings 码,分别对应下和上箭头;空值统一设 0.0 避免历史残留。外汇与贵金属波动大,该着色仅描述统计区段,不预示后续方向,实盘须自担高风险。

MQL5 / C++
class="macro">#class="kw">property copyright   "Copyright class="num">2011, Investeo.pl"
class="macro">#class="kw">property link         "http:class=class="str">"cmt">//Investeo.pl"
class="macro">#class="kw">property description "Moving Mini-Max indicator"
class="macro">#class="kw">property description "proposed by Z.K. Silagadze"
class="macro">#class="kw">property description "from Budker Institute of Nuclear Physics"
class="macro">#class="kw">property description "and Novosibirsk State University"
class="macro">#class="kw">property description "Original paper can be downloaded from:"
class="macro">#class="kw">property description "http:class=class="str">"cmt">//arxiv.org/abs/class="num">0802.0984"
class="macro">#class="kw">property version     "class="num">0.6"
class="macro">#class="kw">property indicator_separate_window
class="macro">#class="kw">property indicator_buffers class="num">5
class="macro">#class="kw">property indicator_plots class="num">3
class="macro">#class="kw">property indicator_type1 DRAW_COLOR_HISTOGRAM2
class="macro">#class="kw">property indicator_type2 DRAW_ARROW
class="macro">#class="kw">property indicator_type3 DRAW_ARROW
class="macro">#class="kw">property indicator_color1 Chartreuse, OrangeRed, Yellow
class="macro">#class="kw">property indicator_color2 RoyalBlue
class="macro">#class="kw">property indicator_color3 RoyalBlue
class="macro">#class="kw">property indicator_width1 class="num">5
class="macro">#class="kw">property indicator_width2 class="num">4
class="macro">#class="kw">property indicator_width3 class="num">4
   SetIndexBuffer(class="num">0,uSi,INDICATOR_DATA);
   SetIndexBuffer(class="num">1,dSi,INDICATOR_DATA);
   SetIndexBuffer(class="num">2,trend,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(class="num">3,upArrows,INDICATOR_DATA);
   SetIndexBuffer(class="num">4,dnArrows,INDICATOR_DATA);

   PlotIndexSetDouble(class="num">0,PLOT_EMPTY_VALUE,class="num">0.0);
   PlotIndexSetDouble(class="num">1,PLOT_EMPTY_VALUE,class="num">0.0);
   PlotIndexSetDouble(class="num">2,PLOT_EMPTY_VALUE,class="num">0.0);

   PlotIndexSetInteger(class="num">1,PLOT_ARROW,class="num">234);
   PlotIndexSetInteger(class="num">2,PLOT_ARROW,class="num">233);
   if (upind<dnind)
   {
      for (i=class="num">0; i<upind; i++) trend[i]=class="num">0;
      for (i=upind; i<dnind; i++) trend[i]=class="num">1;
      for (i=dnind; i<n; i++) trend[i]=class="num">0 ;
   } else
   {
      for (i=class="num">0; i<dnind; i++) trend[i]=class="num">1;
      for (i=dnind; i<upind; i++) trend[i]=class="num">0;
      for (i=upind; i<n; i++) trend[i]=class="num">1;
   }

   trend[upind] = class="num">2;
   trend[dnind] = class="num">2;

「这套指标还能往哪拓」

这一节把新指标的数学底层和 MQL5 落地方式讲清了,随附源码可直接在 MT5 里加载跑一遍,验证信号生成逻辑是否和你的盘感对得上。 原文数学推导参考了 Z.K. Silagadze 的论文(arXiv:0802.0984),但代码实现是独立写的,读者下载后改一个平滑周期参数就能看不同品种的反应。 外汇与贵金属波动受杠杆和消息面影响,指标仅作概率参考,实盘前务必用历史数据回测。后续若有机会,会再拆几个同类指标的实现差异,方便你横向比对。

◍ 把这条线请下神坛

移动极小化极大指标在回测图上看似精准,社区里 Siarhei Kudrytski 在 2024 年 12 月的实测指出:历史记录漂亮,实盘有时猜对方向有时猜错,猜错时箭头直接移除重画,本质就是重绘。Munir 早在此前就警告过,重绘指标里没有可用信号,反而可能藏风险。 从 G.Gamov 的衰变理论到 Silagadze 的极小化极大思路,学术骨架没错,但 MT5 实盘里的表现得靠你自己跑一遍验证。外汇与贵金属杠杆高、滑点狠,这类自适应线只能当概率参考,别当成进场圣旨。 真要试,把 movingminimax.mq5 拖进 MT5 指标区,先在非指数品种上跑,看它重画频率再决定信不信。

常见问题

看线被价格触碰的次数与最近一次触碰的时间,触碰多且近期仍有效的线优先级更高,可手动隐藏触碰少于3次的线。
不是错,是极小化极大算法对每个新K线重算边界。把回溯窗口调大、平滑系数调高可让着色更稳定。
可以,小布盯盘的AIGC会按品种自动跑这套识别逻辑,打开对应页面就能看到当日有效线与触碰统计,不用自己写代码。
贵金属波动大,建议把极小化窗口从默认20调到35,阻力缓冲设为ATR的1.2倍,避免假突破频繁重绘。
回测用闭合K线算历史极值,实盘含未收线波动。把指标设为仅用已收盘K线计算,能缩小两者偏差。