Erik Nayman 的绳索指标·综合运用
🪢

Erik Nayman 的绳索指标·综合运用

(3/3)· 把前两篇的原理和代码拼成可跑的EA,再教你榨干输入参数的最后一点边际

案例拆解新手友好 第 3/3 篇
很多人把绳索指标加载到图表就以为会用完了,却从没把多空力度比较逻辑接进下单判定。更常见的坑是EA跑起来后直接拿默认参数跑实盘,外汇贵金属杠杆高,参数错配可能让回测漂亮的资金曲线在活盘里迅速变形。

快慢双均线的分支计算写法

在自定义指标里同时挂快慢两条均线,常见做法是先按 method_MA_fast 走 switch,再按 method_MA_slow 走第二个 switch。快线分支里 SMA 用的是 SimpleMA(i,period_MA_fast,Buffer_calcLINE),而慢线同名调用却复用同一份 Buffer_calcLINE,只是周期参数换成 period_MA_slow。 注意 SMMA 在两处的索引处理不一样:快线分支写的是 SmoothedMA(i+period_MA_fast,...) ,慢线分支却是 SmoothedMA(i,...) 。这个偏移如果照搬,快线在图表前段可能比慢线少算 period_MA_fast 根bar,回测时价差信号会提前或滞后,外汇与贵金属品种杠杆高,这类偏移容易造成误判。 EMA 和 LWMA 两个分支都依赖上一根 i-1 的缓存值递归,首根 bar 之前 Buffer 未初始化时返回 0 是 default 分支的责任。开 MT5 把这段贴进 OnInit 之后的循环里,改一下 period_MA_fast=5、period_MA_slow=20,能直接看到两条线在 EURUSD 的 M15 上张合节奏。

MQL5 / C++
Buffer_MAfast[i]=SimpleMA(i,period_MA_fast,Buffer_calcLINE); class=class="str">"cmt">// 从库中 Include\MovingAverages.mqh 获取已计算的 SimpleMA i 索引数据, 基于 Buffer_calcLINE 数据缓存区和 period_MA_fast 周期
class="kw">break;
case MODE_EMA: class=class="str">"cmt">// 指数平均
   Buffer_MAfast[i]=ExponentialMA(i,period_MA_fast,Buffer_MAfast[i-class="num">1],Buffer_calcLINE);
   class="kw">break;
case MODE_SMMA: class=class="str">"cmt">// 平滑平均
   Buffer_MAfast[i]=SmoothedMA(i+period_MA_fast,period_MA_fast,Buffer_MAfast[i-class="num">1],Buffer_calcLINE);
   class="kw">break;
case MODE_LWMA: class=class="str">"cmt">// 线性加权平均
   Buffer_MAfast[i]=LinearWeightedMA(i+period_MA_fast,period_MA_fast,Buffer_calcLINE);
   class="kw">break;
class="kw">default: class="kw">return class="num">0;
      }
   }
   class=class="str">"cmt">//--- 基于 method_MA_slow 参数选择慢速均线计算方法
   if(draw_MA_slow)
   {
    class="kw">switch(method_MA_slow)
      {
      case MODE_SMA: class=class="str">"cmt">// 简单平均
         Buffer_MAslow[i]=SimpleMA(i,period_MA_slow,Buffer_calcLINE);
         class="kw">break;
      case MODE_EMA: class=class="str">"cmt">// 指数平均
         Buffer_MAslow[i]=ExponentialMA(i,period_MA_slow,Buffer_MAslow[i-class="num">1],Buffer_calcLINE);
         class="kw">break;
      case MODE_SMMA: class=class="str">"cmt">// 平滑平均
         Buffer_MAslow[i]=SmoothedMA(i,period_MA_slow,Buffer_MAslow[i-class="num">1],Buffer_calcLINE);
         class="kw">break;
      case MODE_LWMA: class=class="str">"cmt">// 线性加权平均
         Buffer_MAslow[i]=LinearWeightedMA(i,period_MA_slow,Buffer_calcLINE);
         class="kw">break;
      class="kw">default: class="kw">return class="num">0;
      }
   }

◍ 把缓冲数组调成时间序列再清掉当前柱

指标里做完初始化后,绘图前必须把三个缓冲数组按时间序列排好,否则最新价会跑到数组尾巴上,画线错位。 ArraySetAsSeries 对 Buffer_calcLINE、Buffer_MAfast、Buffer_MAslow 都传 true,MT5 里索引 0 就恒为当前柱。 紧接着把三个缓冲的 [0] 位赋 EMPTY_VALUE,意思是这一根还没算完,避免旧值残留造成伪信号。外汇与贵金属波动大,这种未计算位不清,重绘时可能闪现错误箭头。 最后用 _tm_prev=time[0] 记住已处理柱时间,并返回 rates_total 给系统,下一帧从这个数继续算,不重复跑全历史。

MQL5 / C++
   }
   class=class="str">"cmt">//--- 为绘图, 启用索引作为时间序列
   ArraySetAsSeries(Buffer_calcLINE,true);
   ArraySetAsSeries(Buffer_MAfast,true);
   ArraySetAsSeries(Buffer_MAslow,true);
   class=class="str">"cmt">//--- 当前柱线的均线清零, 即, 未计算
   Buffer_MAfast[class="num">0]=EMPTY_VALUE;
   Buffer_MAslow[class="num">0]=EMPTY_VALUE;
   Buffer_calcLINE[class="num">0]=EMPTY_VALUE;
   }
   class=class="str">"cmt">//--- 记住最后已计算的柱线时间
   _tm_prev=time[class="num">0];
 }
class=class="str">"cmt">//--- 返回 prev_calculated 值用于下次调用
   prev_rates_total=rates_total;
   class="kw">return(rates_total);
}

「绳索指标 EA 的开平仓信号骨架」

把 RopebyEricNaiman 指标接进 EA,核心思路是用 trade_mode 变量切换四种开仓逻辑:主线穿零轴、主线变色(灰转绿买/灰转红卖)、主线穿快线 MAfast、双均线交叉。平仓不跟开仓绑死,单独提供 4 个布尔开关,默认 close1(穿零轴平买)和 close4(双均线死叉平买)为 true,close2/close3 为 false,实盘里按品种波动调可能更顺。 EA 里 OnInit 做句柄与变量初始化,OnTick 调度开平仓;Check_Indi_Open 负责把指标缓冲拉进来扫信号,Check_Indi_Close 按四种平仓设置迭代。Copy_indi_Buffer 封装了 CopyBuffer,TakeLastOpenTime 比对柱线开盘时间,避免一根 K 线重复开仓——外汇和贵金属杠杆高,这种重复触发在滑点行情里容易把风险敞口放歪。 下面这段输入与开仓判断是 EA 的硬骨头。平仓设置里 close1/close4 默认开,意味着穿零轴和双线死叉都会成为买单退出条件;Check_Indi_Open 的 case 0 取缓冲 4 的前两根已完成柱,若 _arr_ind_1[0]>0 且 [1]<=0 返回 0(买),反之 [0]<0 且 [1]>=0 返回 1(卖),当前未收线那根不参与。

MQL5 / C++
class=class="str">"cmt">//---  平仓设置
class="kw">input class="type">class="kw">string section_5="___ 平仓设置";
class=class="str">"cmt">//--- 当主线下穿零轴时买单平仓
class="kw">input class="type">bool close1=true; class=class="str">"cmt">// 主线与零轴交叉平仓
class=class="str">"cmt">//--- 当颜色转为与开仓颜色相反时平仓, 当变为红色时买单平仓
class="kw">input class="type">bool close2=class="kw">false; class=class="str">"cmt">// 平仓主线颜色
class=class="str">"cmt">//--- 在主线与均线交汇时平仓, 当主线下穿均线时买单平仓
class="kw">input class="type">bool close3=class="kw">false; class=class="str">"cmt">// 主线与 MAfast 交叉时平仓
class=class="str">"cmt">//---  两条均线交汇时平仓, 快速均线下穿慢速均线时买单平仓
class="kw">input class="type">bool close4=true; class=class="str">"cmt">// 两条均线交叉时平仓
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Check_Indi_Open                                                    |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int Check_Indi_Open()
  {
   class=class="str">"cmt">//--- 声明获取指标数据的数组
   class="type">int copy=class="num">0;
   class="type">class="kw">double _arr_ind_1[];
   class="type">class="kw">double mafast[];
   class="type">class="kw">double mainline[];
   class="type">class="kw">double maslow[];
   class=class="str">"cmt">//--- 使用 class="kw">switch 函数并基于外部变量参数 trade_mode 来选择开仓方法
   class="kw">switch((class="type">int)trade_mode)
     {
      case class="num">0:
        class=class="str">"cmt">//--- 指标的主线在最后两根柱线上进行比较, 排除当前那根
        copy=Copy_indi_Buffer(RbEN_handle,class="num">4,class="num">1,class="num">2,_arr_ind_1,"RbEN");
        if(copy!=class="num">2) class="kw">return class="num">4;
        if(_arr_ind_1[class="num">0]!=EMPTY_VALUE && _arr_ind_1[class="num">1]!=EMPTY_VALUE &&
           _arr_ind_1[class="num">0]>class="num">0 && _arr_ind_1[class="num">1]<=class="num">0)
          {
           class="kw">return class="num">0;
          }
        if(_arr_ind_1[class="num">0]!=EMPTY_VALUE && _arr_ind_1[class="num">1]!=EMPTY_VALUE &&
           _arr_ind_1[class="num">0]<class="num">0 && _arr_ind_1[class="num">1]>=class="num">0)
          {
           class="kw">return class="num">1;
          }
        class="kw">break;
      case class="num">1:
        class=class="str">"cmt">//--- 从指标的第 class="num">5 个缓存区获取指标最后两根柱线的颜色索引, 排除当前那根
        copy=Copy_indi_Buffer(RbEN_handle,class="num">5,class="num">1,class="num">2,_arr_ind_1,"RbEN");
        if(copy!=class="num">2) class="kw">return class="num">5;

状态机里如何判指标穿越

在 EA 的信号判定里,用 switch-case 把不同指标逻辑拆开是常见做法。下面这段针对 RbEN 指标做了三种情形的返回:情形 1 看 _arr_ind_1 数组当前根与前一根是否从非零变零(返回 0)或从非 1 变 1(返回 1),情形 2 与 3 则拉取指标缓冲区做均线交叉判定。 情形 2 里先取 buffer 6(mafast)和 buffer 4(mainline),各取从索引 1 开始的两根,排除正在形成的当前柱。若 mainline[0] > mafast[0] 且 mainline[1] <= mafast[1],视为上穿返回 0;反向则返回 1。 情形 3 把 buffer 7(maslow)替下 mainline 做同样结构的快线慢线比较,copy 失败分别返回 8 或 9。开 MT5 把这段塞进你的信号函数,把 RbEN_handle 换成实际指标句柄,就能直接验证交叉信号触发点。外汇与贵金属波动剧烈,这类穿越信号仅作概率参考,实盘须控仓。

MQL5 / C++
if(_arr_ind_1[class="num">0]!=EMPTY_VALUE && _arr_ind_1[class="num">1]!=EMPTY_VALUE &&
      _arr_ind_1[class="num">0]==class="num">0 && _arr_ind_1[class="num">1]!=class="num">0)
      {
        class="kw">return class="num">0;
      }
    if(_arr_ind_1[class="num">0]!=EMPTY_VALUE && _arr_ind_1[class="num">1]!=EMPTY_VALUE &&
      _arr_ind_1[class="num">0]==class="num">1 && _arr_ind_1[class="num">1]!=class="num">1)
      {
        class="kw">return class="num">1;
      }
    class="kw">break;
  case class="num">2:
    class=class="str">"cmt">//--- 接收并比较最后两根柱线的 mafast(指标主线的均线) 和 mainline(指标主线) 的数值, 排除当前那根。
    copy=Copy_indi_Buffer(RbEN_handle,class="num">6,class="num">1,class="num">2,mafast,"RbEN");
    if(copy!=class="num">2) class="kw">return class="num">6;
    copy=Copy_indi_Buffer(RbEN_handle,class="num">4,class="num">1,class="num">2,mainline,"RbEN");
    if(copy!=class="num">2) class="kw">return class="num">7;
    if(mafast[class="num">0]!=EMPTY_VALUE && mafast[class="num">1]!=EMPTY_VALUE &&
      mainline[class="num">0]!=EMPTY_VALUE && mainline[class="num">1]!=EMPTY_VALUE &&
      mainline[class="num">0]>mafast[class="num">0] && mainline[class="num">1]<=mafast[class="num">1])
      {
        class="kw">return class="num">0;
      }
    if(mafast[class="num">0]!=EMPTY_VALUE && mafast[class="num">1]!=EMPTY_VALUE &&
      mainline[class="num">0]!=EMPTY_VALUE && mainline[class="num">1]!=EMPTY_VALUE &&
      mainline[class="num">0]<mafast[class="num">0] && mainline[class="num">1]>=mafast[class="num">1])
      {
        class="kw">return class="num">1;
      }
    class="kw">break;
  case class="num">3:
    class=class="str">"cmt">//--- 接收并比较最后两根柱线的 mafast(指标主线的快速均线) 和 maslow(指标主线的快速均线) 的数值, 排除当前那根。
    copy=Copy_indi_Buffer(RbEN_handle,class="num">6,class="num">1,class="num">2,mafast,"RbEN");
    if(copy!=class="num">2) class="kw">return class="num">8;
    copy=Copy_indi_Buffer(RbEN_handle,class="num">7,class="num">1,class="num">2,maslow,"RbEN");
    if(copy!=class="num">2) class="kw">return class="num">9;

◍ 快慢均线死叉活叉与指标平仓判定

这段逻辑把双均线交叉和自定义指标 RbEN 的平仓信号揉在一个函数里返回整数码,0 代表平多、1 代表平空,调用层拿到码直接下单。注意它刻意跳过当前柱(索引 1 和 2 而非 0 和 1),只用已闭合的两根柱确认,能过滤掉实时价格波动造成的假交叉。 先看双均线分支:mafast 与 maslow 必须四个值都不是 EMPTY_VALUE,否则不判。maslow[0]<mafast[0] 且 maslow[1]>=mafast[1] 说明慢线从上方穿到下方,快线转强,返回 0 倾向平掉空单;反过来 maslow[0]>mafast[0] 且 maslow[1]<=mafast[1] 则是金叉形态,返回 1 倾向平掉多单。 平仓函数 Check_Indi_Close 里,close1 开关打开时会从 RbEN 的第 4 号缓冲区拷 2 根历史值。若拷贝数不等于 2 直接返回 4 报错;否则看 _arr_ind_1[0]>0 且 [1]<=0 为线上穿零轴返回 0,[0]<0 且 [1]>=0 为线下穿零轴返回 1,并在 _str_close 写死“主线与零轴交叉平仓”方便日志排查。 close2 分支则从同一指标第 5 号缓冲区取颜色索引,同样排除当前柱取两根;拷贝失败返回 5。这种把‘均线交叉’和‘零轴交叉’分开关控制的结构,实盘里可以只开一个过滤噪音,外汇与贵金属波动大、滑点高,信号确认慢半根柱往往少亏几个点。

MQL5 / C++
if(mafast[class="num">0]!=EMPTY_VALUE && mafast[class="num">1]!=EMPTY_VALUE &&
      maslow[class="num">0]!=EMPTY_VALUE && maslow[class="num">1]!=EMPTY_VALUE &&
      maslow[class="num">0]<mafast[class="num">0] && maslow[class="num">1]>=mafast[class="num">1])
      {
         class="kw">return class="num">0;
      }
   if(mafast[class="num">0]!=EMPTY_VALUE && mafast[class="num">1]!=EMPTY_VALUE &&
      maslow[class="num">0]!=EMPTY_VALUE && maslow[class="num">1]!=EMPTY_VALUE &&
      maslow[class="num">0]>mafast[class="num">0] && maslow[class="num">1]<=mafast[class="num">1])
      {
         class="kw">return class="num">1;
      }
      class="kw">break;
   class="kw">default: class="kw">return class="num">3;
   }
class=class="str">"cmt">//---
   class="kw">return class="num">2;
   }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Check_Indi_Close                                                  |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int Check_Indi_Close()
  {
   class=class="str">"cmt">//--- 声明获取指标数据的数组
   class="type">int copy=class="num">0;
   class="type">class="kw">double _arr_ind_1[];
   class="type">class="kw">double mafast[];
   class="type">class="kw">double mainline[];
   class="type">class="kw">double maslow[];
   _str_close="";
   class=class="str">"cmt">//--- 接收并比较最后两根柱线的零轴和主线数值, 排除当前那根。
   if(close1)
     {
      copy=Copy_indi_Buffer(RbEN_handle,class="num">4,class="num">1,class="num">2,_arr_ind_1,"RbEN");
      if(copy!=class="num">2) class="kw">return class="num">4;
      _str_close="主线与零轴交叉平仓";
      if(_arr_ind_1[class="num">0]!=EMPTY_VALUE && _arr_ind_1[class="num">1]!=EMPTY_VALUE &&
         _arr_ind_1[class="num">0]>class="num">0 && _arr_ind_1[class="num">1]<=class="num">0)
        {
         class="kw">return class="num">0;
        }
      if(_arr_ind_1[class="num">0]!=EMPTY_VALUE && _arr_ind_1[class="num">1]!=EMPTY_VALUE &&
         _arr_ind_1[class="num">0]<class="num">0 && _arr_ind_1[class="num">1]>=class="num">0)
        {
         class="kw">return class="num">1;
        }
     }
   class=class="str">"cmt">//--- 从指标的第 class="num">5 个缓存区获取指标最后两根柱线的颜色索引, 排除当前那根
   if(close2)
     {
      copy=Copy_indi_Buffer(RbEN_handle,class="num">5,class="num">1,class="num">2,_arr_ind_1,"RbEN");
      if(copy!=class="num">2) class="kw">return class="num">5;

「平仓信号的三种交叉判定」

平仓逻辑里最容易被忽略的是「排除当前柱」这件事。上面这段把索引 1 当作上一根已闭合柱、索引 0 当作次上一根,从缓冲区拷 2 根而不是 1 根,就是为了避开实时价格波动造成的假交叉。 第一种判定看指标主线自身状态跳变:当 _arr_ind_1[0]==0 且 _arr_ind_1[1]!=0 时返回 0(平多),_arr_ind_1[0]==1 且 _arr_ind_1[1]!=1 时返回 1(平空)。这里 EMPTY_VALUE 的双重校验是必须的,否则在指标加载初期会误触发。 第二种走主线与 MAfast 的交叉:mainline[0]>mafast[0] 且 mainline[1]<=mafast[1] 判平多,反过来 mainline[0]<mafast[0] 且 mainline[1]>=mafast[1] 判平空。Copy_indi_Buffer 的返回值若不等于 2 直接 return 错误码 6 或 7,说明拷 buffer 失败就别硬算。 第三种是 mafast 与 maslow 两条均线互叉,逻辑同第二种但 buffer 编号换到 7。错误码 8、9 分别对应两次拷贝失败。外汇与贵金属杠杆高,这类交叉平仓在滑点行情中可能比信号慢 1~2 个点,实盘前建议在 MT5 策略测试器用 2023 年 XAUUSD 的 M15 跑一遍看成交偏移。

MQL5 / C++
_str_close="主线平仓颜色";
if(_arr_ind_1[class="num">0]!=EMPTY_VALUE && _arr_ind_1[class="num">1]!=EMPTY_VALUE &&
   _arr_ind_1[class="num">0]==class="num">0 && _arr_ind_1[class="num">1]!=class="num">0)
  {
   class="kw">return class="num">0;
  }
if(_arr_ind_1[class="num">0]!=EMPTY_VALUE && _arr_ind_1[class="num">1]!=EMPTY_VALUE &&
   _arr_ind_1[class="num">0]==class="num">1 && _arr_ind_1[class="num">1]!=class="num">1)
  {
   class="kw">return class="num">1;
  }
 }
 class=class="str">"cmt">//--- 接收并比较最后两根柱线的 mafast(指标主线的均线) 和 mainline(指标主线) 的数值, 排除当前那根。
 if(close3)
 {
  copy=Copy_indi_Buffer(RbEN_handle,class="num">6,class="num">1,class="num">2,mafast,"RbEN");
  if(copy!=class="num">2) class="kw">return class="num">6;
  copy=Copy_indi_Buffer(RbEN_handle,class="num">4,class="num">1,class="num">2,mainline,"RbEN");
  if(copy!=class="num">2) class="kw">return class="num">7;
  _str_close="主线与 MAfast 交叉平仓";
  if(mafast[class="num">0]!=EMPTY_VALUE && mafast[class="num">1]!=EMPTY_VALUE &&
     mainline[class="num">0]!=EMPTY_VALUE && mainline[class="num">1]!=EMPTY_VALUE &&
     mainline[class="num">0]>mafast[class="num">0] && mainline[class="num">1]<=mafast[class="num">1])
   {
    class="kw">return class="num">0;
   }
  if(mafast[class="num">0]!=EMPTY_VALUE && mafast[class="num">1]!=EMPTY_VALUE &&
     mainline[class="num">0]!=EMPTY_VALUE && mainline[class="num">1]!=EMPTY_VALUE &&
     mainline[class="num">0]<mafast[class="num">0] && mainline[class="num">1]>=mafast[class="num">1])
   {
    class="kw">return class="num">1;
   }
 }
 class=class="str">"cmt">//--- 接收并比较最后两根柱线的 mafast(指标主线的快速均线) 和 maslow(指标主线的快速均线) 的数值, 排除当前那根。
 if(close4)
 {
  copy=Copy_indi_Buffer(RbEN_handle,class="num">6,class="num">1,class="num">2,mafast,"RbEN");
  if(copy!=class="num">2) class="kw">return class="num">8;
  copy=Copy_indi_Buffer(RbEN_handle,class="num">7,class="num">1,class="num">2,maslow,"RbEN");
  if(copy!=class="num">2) class="kw">return class="num">9;
  _str_close="两条均线交叉平仓";
  if(mafast[class="num">0]!=EMPTY_VALUE && mafast[class="num">1]!=EMPTY_VALUE &&
     maslow[class="num">0]!=EMPTY_VALUE && maslow[class="num">1]!=EMPTY_VALUE &&

快慢均线死叉活叉的返回值判定

这段逻辑只干一件事:用两根均线(慢线 maslow 与快线 mafast)的当前根与前一根位置关系,给行情状态打标签。当前慢线低于快线、且前一根慢线大于等于快线,意味着快线刚从上方穿越下来,判定为死叉信号,直接 return 0。 反之若四根数值均非 EMPTY_VALUE,且慢线由下往上穿过快线(当前 maslow>mafast 而前一根 maslow<=mafast),则返回 1,对应活叉。EMPTY_VALUE 的过滤很关键,避免在指标未初始化或数据缺口时误触发。 都不满足时落到函数末尾 return 2,通常表示无明确交叉、处于纠缠或等待状态。把这段塞进 MT5 的自定义指标里,切换 EURUSD 的 M15 图,肉眼对照 K 线拐点和 return 值变化,能验证信号延迟大约在一根 bar 以内。外汇与贵金属杠杆高,信号仅作概率参考,实盘须控仓。

MQL5 / C++
   maslow[class="num">0]<mafast[class="num">0] && maslow[class="num">1]>=mafast[class="num">1])
   {
    class="kw">return class="num">0;
   }
   if(mafast[class="num">0]!=EMPTY_VALUE && mafast[class="num">1]!=EMPTY_VALUE &&
    maslow[class="num">0]!=EMPTY_VALUE && maslow[class="num">1]!=EMPTY_VALUE &&
    maslow[class="num">0]>mafast[class="num">0] && maslow[class="num">1]<=mafast[class="num">1])
   {
    class="kw">return class="num">1;
   }
   }
class=class="str">"cmt">//---
   class="kw">return class="num">2;
   }

◍ EURUSD H1 十年样本下的四种开仓逻辑调参

在把智能交易程序丢进实盘前,先把核心输入参数跑一遍优化。这里用 EURUSD H1、2005–2015 共十年数据,遗传算法跑全样本,四种开仓类型各自独立优化,不混在一起。 第一种是主线穿越零轴平仓:上穿开买、下穿开卖。StopLoss 与 TakeProfit 均从 0 到 10000 以 50 步进(各 201 步),_period 从 1 到 200 以 1 步进,close1 布尔开关。总通过组合数 16,160,400,结果落在 optimization.zip 的 test1 目录。 第二种看主线颜色切换:灰变绿买、灰变红卖。参数网格与第一种完全一致,总通过同样为 16,160,400,最佳结果在 test2 目录。 第三种引入快线 MA:主线上穿快 MA 买、下穿卖。比前两类多一个 period_MA_fast(1–300,300 步),总通过跳到 4,848,120,000,存于 test3 目录。 第四种是双 MA 交叉:快线上穿慢线买、下穿卖。在第三类基础上再加 period_MA_slow(1–400,400 步),总通过暴增至 1,939,248,000,000,对应 test4 目录。外汇与贵金属品种波动剧烈,这类大网格优化仅代表历史样本拟合,实盘失效概率不低,须以 MT5 自带优化器自行复核。

「把工具请下神坛」

回测优化跑下来,这套基于多空活力静态评估的逻辑确实能跑通,而且智能交易程序没挂任何资金管理的花活,纯靠指标信号过滤和触发。作者用的核心思路是在固定周期里量化多头和空头的动能,把它同时当过滤器与开仓依据,小范围实盘已经显出基本工作能力。 附件里 ropebyericnaiman.mq5(52.61 KB)和 earopebyericnaiman.mq5(40.7 KB)是可直接在 MT5 打开的源码,想验证的人把 optimization.zip(2230.41 KB)解压丢进终端测一遍就行。外汇和贵金属杠杆高、滑点跳空频繁,这类纯逻辑策略只解决方向判定,仓位和止损仍需自己兜底,别把 ea 当印钞壳。 它本质只是把 Eric Naiman 那套价格速率判趋势的想法落成了代码,你能改周期也能换活力算法。工具下神坛之后,剩下的是你愿不愿意动手调参、跑历史、看它什么时候失灵。

把回测巡检交给小布
这些诊断小布盯盘的AIGC已内置,打开对应品种页即可看到绳索多空力度的实时拉锯与EA信号偏离提示,你只管判断该不该手动干预。

常见问题

静态上谁的数值高谁主导市场;动态上比相邻周期的差值变化,四个组合对应多头增长、多头下降、空头下降、空头增长,综合看方向和强度。
主要是把指标缓冲区的值用iCustom取进EA,再把力度比较逻辑写成下单条件,原文第二章给了实际实现框架。
可以,把优化后的输入参数填进品种页的自定义指标配置,小布会按新阈值刷新多空力度预警,省去你手动重算。
倾向用覆盖至少两段不同波动特征的历史段做交叉验证,单纯最大化某一段回测收益的参数在活盘里失效概率更高。
静态看谁强,动态看强弱在加速还是衰减,两者错位时常是趋势拐头的早期信号,具体公式见第一章例程。