Integrating Zigzag directly into EA code - MT4

 

Hi


My EA has used the icustom function to bring in the ZigZag values that i need. However the optimization testing takes forever. In an attempt to speed the optimisation up, I believe the EA may work quicker if I integrate the Zigzag indicator into my EA directly. (I hope that is accurate)

 to that end i have been following this article to see if I could achieve this  -= https://www.mql5.com/en/articles/1456

I seem to have gotten a little lost in getting the arrays to work correctly.

I have the following code in int start()

//---- Checking whether the bars number is enough for further calculation
   if(Bars < ExtZZSwingTF) //external param to set the timeframe to run the zigzag
       return(0);
//---- INDICATOR BUFFERS EMULATION
   if(ArraySize(ZigzagBuffer) < Bars)
     {
       ArraySetAsSeries(ZigzagBuffer, false);
       ArraySetAsSeries(LowMapBuffer, false);
       ArraySetAsSeries(HighMapBuffer, false);
       //----  
       ArrayResize(ZigzagBuffer, Bars); 
       ArrayResize(LowMapBuffer, Bars); 
       ArrayResize(HighMapBuffer, Bars); 
       //----
       ArraySetAsSeries(ZigzagBuffer, true);
       ArraySetAsSeries(LowMapBuffer, true);
       ArraySetAsSeries(HighMapBuffer, true); 
     } 
//----+ INSERTION OF A STATIC INTEGER MEMORY VARIABLE
   static int IndCounted;

//----+ Insertion of integer variables and getting calculated bars
   int limit,i, MaxBar, bar, counted_bars = IndCounted;
//---- checking for possible errors
   if(counted_bars < 0)
       return(-1);
//---- the last calculated bar must be recalculated 
   if(counted_bars > 0) 
       counted_bars--;
//----+ REMEMBERING THE AMOUNT OF ALL BARS OF THE CHART
   IndCounted = Bars - 1;
//---- defining the number of the oldest bar, 
//     starting from which new bars will be recalculated
   limit = Bars - counted_bars - 1; 
//---- defining the number of the oldest bar, 
//     starting from which new bars will be recalculated
   MaxBar = Bars - 1 - (ExtZZSwingTF); 
//---- initialization of zero
///////
   if (limit > MaxBar) 
     {
      while (counterZ<level && i<100)
        {
         res=ZigzagBuffer[i];
         if (res!=0) counterZ++;
         i++;
        }
      i--;
      limit=i;
      if (LowMapBuffer[i]!=0) 
        {
         curlow=LowMapBuffer[i];
         whatlookfor=1;
        
        }
      else
        {
         curhigh=HighMapBuffer[i];
         whatlookfor=-1;
         
        }
        limit = MaxBar;
     for(bar = Bars - 1; bar >= 0; bar--)  
        {
         ZigzagBuffer[i]=0.0;  
         LowMapBuffer[i]=0.0;
         HighMapBuffer[i]=0.0;
        }
     }
    
   for(shift=limit; shift>=0; shift--)
     {
      val=Low[iLowest(NULL,ExtZZSwingTF,MODE_LOW,ExtDepth,shift)];
      if(val==lastlow) val=0.0;
      else 
        { 
         lastlow=val; 
         if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=LowMapBuffer[shift+back];
               if((res!=0)&&(res>val)) LowMapBuffer[shift+back]=0.0; 
              }
           }
        } 
      if (Low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
      //--- high
      val=High[iHighest(NULL,ExtZZSwingTF,MODE_HIGH,ExtDepth,shift)];
      if(val==lasthigh) val=0.0;
      else 
        {
         lasthigh=val;
         if((val-High[shift])>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=HighMapBuffer[shift+back];
               if((res!=0)&&(res<val)) HighMapBuffer[shift+back]=0.0; 
              } 
           }
        }
      if (High[shift]==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
     }

   // final cutting 
   if (whatlookfor==0)
     {
      lastlow=0;
      lasthigh=0;  
     }
   else
     {
      lastlow=curlow;
      lasthigh=curhigh;
     }
   for (shift=limit;shift>=0;shift--)
     {
      res=0.0;
      switch(whatlookfor)
        {
         case 0: // look for peak or lawn 
            if (lastlow==0 && lasthigh==0)
              {
               if (HighMapBuffer[shift]!=0)
                 {
                  lasthigh=High[shift];
                  lasthighpos=shift;
                  whatlookfor=-1;
                  ZigzagBuffer[shift]=lasthigh;
                  res=1;
                  
                 }
               if (LowMapBuffer[shift]!=0)
                 {
                  lastlow=Low[shift];
                  lastlowpos=shift;
                  whatlookfor=1;
                  ZigzagBuffer[shift]=lastlow;
                  res=1;
                  
                 }
           
              }
             break;  
         case 1: // look for peak
            if (LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
              {
               ZigzagBuffer[lastlowpos]=0.0;
               lastlowpos=shift;
               lastlow=LowMapBuffer[shift];
               ZigzagBuffer[shift]=lastlow;
               res=1;
               
              }
            if (HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
              {
               lasthigh=HighMapBuffer[shift];          
               lasthighpos=shift;
               ZigzagBuffer[shift]=lasthigh;           
               whatlookfor=-1;
               res=1;
               Trend=UpTrend;
              
               
              }   
            break;               
         case -1: // look for lawn
            if (HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
              {
               ZigzagBuffer[lasthighpos]=0.0;
               lasthighpos=shift;
               lasthigh=HighMapBuffer[shift];
               ZigzagBuffer[shift]=lasthigh;
               
              }
            if (LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
              {
               lastlow=LowMapBuffer[shift];            
               lastlowpos=shift;
               ZigzagBuffer[shift]=lastlow;
               
               whatlookfor=1;
               Trend=DownTrend;
            
              }
              
             
          // Comment("\n",  "ZigzagBuffer[shift] = ", DoubleToStr(ZigzagBuffer[shift],5));
        
       
            break;               
         default: return; 
        }
         if (Trend == UpTrend)
              { LastSwingHigh= curhigh ;
              LastSwingLow= lastlow;
              
              }
              else if (Trend==DownTrend)
              { LastSwingHigh= lasthigh;
               LastSwingLow= curlow;
               
              }

any help much appreciated

Transferring an Indicator Code into an Expert Advisor Code. Indicator Structure
Transferring an Indicator Code into an Expert Advisor Code. Indicator Structure
  • www.mql5.com
I will repeat, that the above method is for EAs working only on closed bars, i.e. on all bars except the zero one! If you are seriously going to use your EA in real trading and trust it your money, you should carefully check all the details in your Expert Advisor, as well as the indicators with which the EA works. Moreover you should do it...
 

You only have to read the buffer(s) until you hit a value this value will be the previous pivot point.

Combine that with the current close and you have the last leg of ZigZag.

 
In future please post in the correct section
I will move this topic to the MQL4 and Metatrader 4 section.
 
simoncs: In an attempt to speed the optimisation up, I believe the EA may work quicker if I integrate the Zigzag indicator into my EA directly.
  1. Don't try to do that. There are no buffers, no IndicatorCounted() or prev_calculated. No way to know if older bars have changed or been added (history update.)

    Just get the value(s) of the indicator(s) into EA/indicator (using iCustom) and do what you want with it.

    You should encapsulate your iCustom calls to make your code self-documenting.
              Detailed explanation of iCustom - MQL4 programming forum #33 2017.05.23

    1. EAs : Don't do per tick that you can do per bar, or on open.
      If you are waiting for a level, don't reevaluate, wait until price reaches it (or a new bar starts and you recalculate.)
      If you are waiting for an order to open or close, only look when OrdersTotal (or MT5 equivalent) has changed.
                How to get backtesting faster ? - MT4 - MQL4 programming forum

    2. Indicators: Code it properly so it only recomputes bar zero (after the initial run.)
                How to do your lookbacks correctly.
      Or, reduce Tools → Options (control+O) → Charts → Max bars in chart to something reasonable (like 1K.)

 
William Roeder:
  1. Don't try to do that. There are no buffers, no IndicatorCounted() or prev_calculated. No way to know if older bars have changed or been added (history update.)

    Just get the value(s) of the indicator(s) into EA/indicator (using iCustom) and do what you want with it.

    You should encapsulate your iCustom calls to make your code self-documenting.
              Detailed explanation of iCustom - MQL4 programming forum #33 2017.05.23

    1. EAs : Don't do per tick that you can do per bar, or on open.
      If you are waiting for a level, don't reevaluate, wait until price reaches it (or a new bar starts and you recalculate.)
      If you are waiting for an order to open or close, only look when OrdersTotal (or MT5 equivalent) has changed.
                How to get backtesting faster ? - MT4 - MQL4 programming forum

    2. Indicators: Code it properly so it only recomputes bar zero (after the initial run.)
                How to do your lookbacks correctly.
      Or, reduce Tools → Options (control+O) → Charts → Max bars in chart to something reasonable (like 1K.)

ok thanks that makes more sense. i will investigate these options.

Reason: