Download MetaTrader 5

Watch how to download trading robots for free

Interesting script?
So post a link to it -
let others appraise it

You liked the script? Try it in the MetaTrader 5 terminal

2012.07.20 14:07
Indicators

Ideal ZigZag - indicator for MetaTrader 5

| English Русский 中文 Español Deutsch 日本語 Português

Views:
10082
Rating:
votes: 49
idealzz.mq5 (7.33 KB)view
idealzzp.mq5 (7.33 KB)view

This is a simple but very fast zigzag.

No suspended or wrong peaks. Peaks retrieval has been time-optimized.

Ideal ZigZag

Advantages:

  1. The most expensive function in calculations is iBarShift. It totally replaces all cycles needed for peaks retrieval. Therefore, it has been replaced by ArrayBSearch. It means that the indicator will be more efficient than its MQL4 equivalent;
  2. All necessary data for each bar is accessible not only in every moment but also available to EA for any moment in history;
  3. No suspended picks;
  4. Efficient method to find peaks without searching the indicator values;
  5. Very fast;
  6. Works correctly at history insertions and when switching timeframes;
  7. Perfect for use in EAs.

Disadvantages:

  1. Memory requirements. ZigZag needs 2 buffers (one is not enough because of lags) for correct drawing, while 5 buffers are used here. In my opinion, this drawback is completely outshined by advantage #6. None of fast ZigZags can correctly process history insertions on two buffers.
  2. Additional lines are available. This is required to make the data visible to an Expert Advisor. These lines should never be visible.

Principle:

ZigZag is drawn by the channeling principle. The channel width can be defined in points (IdealZZ) or in percentage terms (IdealZZP)

Peaks retrieval:

input int ChannelWidth=100;

#property indicator_chart_window

datetime LastTime;
int ZZHandle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
   LastTime = 0;
   ZZHandle = iCustom(_Symbol, Period(), "IdealZZ", ChannelWidth);
  }
//+------------------------------------------------------------------+
//| GetValue                                                         |
//+------------------------------------------------------------------+
bool GetValue(double dir,int bar,int prevBar,double &peak,
             int &peakBar,datetime &peakTime,const datetime &T[])
  {
   if(dir<0)
     {
      double t[1];
      if(0>=CopyBuffer(ZZHandle,2,bar,1,t)) return false;
      int i= ArrayBsearch(T, (datetime)t[0]);

      if(i==prevBar)
        {
         if(0>=CopyBuffer(ZZHandle,2,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
        }

      double v[1];
      if(0>=CopyBuffer(ZZHandle,1,i,1,v)) return false;

      if(v[0]==EMPTY_VALUE)
        {
         if(0>=CopyBuffer(ZZHandle,2,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
         if(0>=CopyBuffer(ZZHandle,1,i,1,v)) return false;
        }

      peak=v[0];
      peakBar=i;
      peakTime=(datetime)t[0];
     }
   else if(dir>0)
     {
      double t[1];
      if(0>=CopyBuffer(ZZHandle,3,bar,1,t)) return false;
      int i= ArrayBsearch(T, (datetime)t[0]);

      if(i==prevBar)
        {
         if(0>=CopyBuffer(ZZHandle,3,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
        }

      double v[1];
      if(0>=CopyBuffer(ZZHandle,0,i,1,v)) return false;

      if(v[0]==EMPTY_VALUE)
        {
         if(0>=CopyBuffer(ZZHandle,3,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
         if(0>=CopyBuffer(ZZHandle,0,i,1,v)) return false;
        }

      peak=v[0];
      peakBar=i;
      peakTime=(datetime)t[0];
     }
   else
     {
      return(false);
     }

   return(true);
  }
//+------------------------------------------------------------------+
//| GetValue                                                         |
//+------------------------------------------------------------------+
void SetPt(string name,double price,datetime time)
  {
   ObjectCreate(0,name,OBJ_ARROW,0,time,price);
   ObjectSetInteger(0,name,OBJPROP_ARROWCODE,108);
   ObjectSetDouble(0,name,OBJPROP_PRICE,price);
   ObjectSetInteger(0,name,OBJPROP_TIME,time);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &T[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(LastTime==T[0]) return(rates_total);
   LastTime=T[0];

   ArraySetAsSeries(T,true);

   double dir_[1];
   if(0>=CopyBuffer(ZZHandle,4,1,1,dir_)) return rates_total;
   double dir=dir_[0];
   double rdir=-dir;

   if(dir==EMPTY_VALUE) return(rates_total);

   double v1,v2,v3,v4,v5;
   int    i1,i2,i3,i4,i5;
   datetime t1,t2,t3,t4,t5;

   if(
      GetValue(dir,1,0,v1,i1,t1,T) && 
      GetValue(rdir,i1,0,v2,i2,t2,T) && 
      GetValue(dir,i2,i1,v3,i3,t3,T) && 
      GetValue(rdir,i3,i2,v4,i4,t4,T) && 
      GetValue(dir,i4,i3,v5,i5,t5,T)
      )
     {
      SetPt("1",v1,t1);
      SetPt("2",v2,t2);
      SetPt("3",v3,t3);
      SetPt("4",v4,t4);
      SetPt("5",v5,t5);
      Print(v1,"   ",v2,"  ",v3,"  ",v4," ",v5," ",i1,"  ",i2,"  ",i3," ",i4," ",i5);
     }
   else
     {
      Print("Seems to be error available...");
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+

This example is an indicator that marks (one time per bar) first five peaks (including the current forming one).

Attention! The code may work incorrectly, if zero bar mode is enabled

Zero Bar Mode:

The mode can be enabled in DrawZeroBar variable code. It is disabled by default. It is not recommended to enable it, especially if the indicator is used in an Expert Advisor.

Enjoy using it. Please inform me of any revealed drawbacks.

Translated from Russian by MetaQuotes Software Corp.
Original code: https://www.mql5.com/ru/code/925

Accelerator Oscillator (AC) Accelerator Oscillator (AC)

The Acceleration/Deceleration Indicator (AC) measures acceleration and deceleration of the current driving force.

Average Directional Movement Index (ADX) Average Directional Movement Index (ADX)

The Average Directional Movement Index Indicator (ADX) helps to determine if there is a price trend.

Example of MACD Automated Example of MACD Automated

Code example of MACD automated with advanced money management function.

Pivot Star Pivot Star

Pivot indicator. Standard, Fibonacci, Camarilla, Woody's, Demark. Calculates pivot points from previous bar of chosen period (M5 - MN).