Значения индикатора Zigzag MQL5

 

Пожалуйста, может кто объяснить как получить значения зигзага?
Я уже все перепробовал, и в английской и в русской ветках форума спрашивал, но нормального ответа так никто и не дал.
Я пробовал получать значения из разных буферов, я крутил все возможные параметры в iCustom, он должен выдавать либо 0, либо цену на который отрисован зигзаг, но я получаю только рандомные очень маленькие числа или огромные.

Что еще мне сделать?

#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

input int      ExtDepth=12;
input int      ExtDeviation=5;
input int      ExtBackstep=3;
int zz_handle;
double zz[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   zz_handle=iCustom(_Symbol,PERIOD_CURRENT,"ZigZag",ExtDepth,ExtDeviation,ExtBackstep);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   CopyBuffer(zz_handle,0,0,10,zz);
   ArraySetAsSeries(zz,true);
   Comment(zz[1]);
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

1. Получение данных через iCustom:

//+------------------------------------------------------------------+
//| Get value of buffers for the iCustom                             |
//|  the buffer numbers are the following:                           |
//+------------------------------------------------------------------+
double iCustomGet(int handle,const int buffer,const int index)
  {
   double Custom[1];
//--- reset error code 
   ResetLastError();
//--- fill a part of the iCustom array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(handle,buffer,index,1,Custom)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iCustom indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(0.0);
     }
   return(Custom[0]);
  }
 

2. Получение данных High и Low:

//+------------------------------------------------------------------+ 
//| Get the High for specified bar index                             | 
//+------------------------------------------------------------------+ 
double iHigh(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=m_symbol.Name();
   if(timeframe==0)
      timeframe=Period();
   double High[1];
   double high=0.0;
   int copied=CopyHigh(symbol,timeframe,index,1,High);
   if(copied>0)
      high=High[0];
   return(high);
  }
//+------------------------------------------------------------------+ 
//| Get Low for specified bar index                                  | 
//+------------------------------------------------------------------+ 
double iLow(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=m_symbol.Name();
   if(timeframe==0)
      timeframe=Period();
   double Low[1];
   double low=0.0;
   int copied=CopyLow(symbol,timeframe,index,1,Low);
   if(copied>0)
      low=Low[0];
   return(low);
  }
 

3. Пусть ищем от бара с индексом "0" (самого правого бара на графике) до бара с индексом "100":

   int candle=0;
   double ZigZag=0.0;

   while(candle<100)
     {
      ZigZag=iCustomGet(handle_iCustom,0,candle);
      if(ZigZag!=0.0) // found zigzag
         break;
      candle++;
     }

Здесь в строке "0" - это номер буфера:

      ZigZag=iCustomGet(handle_iCustom,0,candle);

Далее, если в пределах 100 баров обнаружили ЗигЗаг (то есть переменная "ZigZag" не равна нулю) останавливаем поиск - значит мы обнаружили излом ЗигЗага.

 

4. Остаётся определить: найденный излом - это high или low.

   double high=iHigh(candle);
   double low=iLow(candle);
   if(high==0.0 || low==0.0)
      return;

   if(CompareDoubles(ZigZag,high,m_symbol.Digits()))
      Signal=1;
   else if(CompareDoubles(ZigZag,low,m_symbol.Digits()))
      Signal=2;

 и сама функция сравнения:

//+------------------------------------------------------------------+
//| Compare doubles                                                  |
//+------------------------------------------------------------------+
bool CompareDoubles(double number1,double number2,int digits)
  {
   if(NormalizeDouble(number1-number2,digits)==0)
      return(true);
   else
      return(false);
  }
 

Эм, как это работает, если здесь даже имя индикатора нигде не упомянуто?

 
RomanRott:

Эм, как это работает, если здесь даже имя индикатора нигде не упомянуто?


Как это нигде, а тут:

int OnInit()
  {
//--- indicator buffers mapping
   zz_handle=iCustom(_Symbol,PERIOD_CURRENT,"ZigZag",ExtDepth,ExtDeviation,ExtBackstep);

//---
   return(INIT_SUCCEEDED);
  }
 
RomanRott:

Эм, как это работает, если здесь даже имя индикатора нигде не упомянуто?

Я Вам набросал кубики. Из этих кубиков Вам нужно собрать домик :) 

Начните с того, что выделенное удалите из своего кода:

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   CopyBuffer(zz_handle,0,0,10,zz);
   ArraySetAsSeries(zz,true);
   Comment(zz[1]);
   return(rates_total);
  }
 
Vladimir Karputov:

Я Вам набросал кубики. Из этих кубиков Вам нужно собрать домик :) 

Начните с того, что выделенное удалите из своего кода:


Кубики нужно набрасывать по шагам - в своих сообщениях я пронумеровал шаги: от 1 до 4.

 
Evgeny Belyaev:

Как это нигде, а тут:


а, я думал это независимо от моего кода

 
Vladimir Karputov:

Кубики нужно набрасывать по шагам - в своих сообщениях я пронумеровал шаги: от 1 до 4.


ну мне хотя бы получить просто значения, потом уже определю high/low
Вот написал я код, теперь он постоянно показывает 0

input int      ExtDepth=12;
input int      ExtDeviation=5;
input int      ExtBackstep=3;
int zz_handle;
double zz[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   
   zz_handle=iCustom(_Symbol,PERIOD_CURRENT,"ZigZag",ExtDepth,ExtDeviation,ExtBackstep);
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int candle=0;
   double ZigZag=0.0;

   while(candle<100)
     {
      ZigZag=iCustomGet(zz_handle,0,candle);
      if(ZigZag!=0.0) // found zigzag
         break;
      candle++;
     }
   Comment(ZigZag);



   return(rates_total);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}

double iCustomGet(int handle,const int buffer,const int index)
{
   double Custom[1];
   ResetLastError();
   if(CopyBuffer(handle,buffer,index,1,Custom)<0)
     {
      PrintFormat("Failed to copy data from the iCustom indicator, error code %d",GetLastError());
      return(0.0);
     }
   return(Custom[0]);
}
Причина обращения: