Странная работа iLowest в индикаторе

 
Пишу индикатор. Не буду вдаваться в подробности для чего, потому что в урезанной версии, которую я выложил ниже, это не нужно. Основная суть в следующем. Индикатор должен находить локальные минимумы. К примеру если из 10 подряд идущих свечей средняя (5-я) имеет минимальный минимум мы её отмечаем. Но индикатор неправильно ищет минимальную свечу. Указывая то на следующую, то вообще в молоко. Помогите разобраться!
//+------------------------------------------------------------------+
//|                                                        lines.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_label1  "DOWN-trend"
#property indicator_type1   DRAW_SECTION
#property indicator_color1  Green
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
input int nPeriod=10;
input int Limit=15;
///---- int Widners Oscilator
double SectionBuffer1[];
int cnt, nCurBar=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---- Output in Char
   SetIndexBuffer(0,SectionBuffer1, INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   
//---
   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 limit=Limit;
   if(rates_total-nPeriod<limit) limit=rates_total-nPeriod;
   for(nCurBar=rates_total-limit-nPeriod; nCurBar<rates_total-nPeriod; nCurBar++)
   {
      Print(time[nCurBar+(nPeriod-1)/2], " ", low[nCurBar+(nPeriod-1)/2], " ", 
      time[rates_total-iLowest(NULL,0,MODE_LOW,nPeriod,rates_total-nCurBar-nPeriod)], " ",
      low[rates_total-iLowest(NULL,0,MODE_LOW,nPeriod,rates_total-nCurBar-nPeriod)]);
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 
TraSer:
Пишу индикатор. Не буду вдаваться в подробности для чего, потому что в урезанной версии, которую я выложил ниже, это не нужно. Основная суть в следующем. Индикатор должен находить локальные минимумы. К примеру если из 10 подряд идущих свечей средняя (5-я) имеет минимальный минимум мы её отмечаем. Но индикатор неправильно ищет минимальную свечу. Указывая то на следующую, то вообще в молоко. Помогите разобраться!

iLowest Возвращает индекс наименьшего найденного значения (смещение относительно текущего бара) соответствующего графика.

А текущий бар имеет индекс rates_total-1

 
TraSer:
Пишу индикатор. Не буду вдаваться в подробности для чего, потому что в урезанной версии, которую я выложил ниже, это не нужно. Основная суть в следующем. Индикатор должен находить локальные минимумы. К примеру если из 10 подряд идущих свечей средняя (5-я) имеет минимальный минимум мы её отмечаем. Но индикатор неправильно ищет минимальную свечу. Указывая то на следующую, то вообще в молоко. Помогите разобраться!

Вот вариант, который работает онлайн - на истории не работает. Пример:

//+------------------------------------------------------------------+
//|                                                        lines.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.000"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_label1  "DOWN-trend"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
input int nPeriod=10;
///---- int Widners Oscilator
double SectionBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---- Output in Char
   SetIndexBuffer(0,SectionBuffer1, INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//---
   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 limit=prev_calculated-1;
   if(prev_calculated==0)
     {
      for(int i=0; i<limit; i++)
         SectionBuffer1[i]=0.0;
      limit=nPeriod;
     }
//---
   for(int i=limit; i<rates_total; i++)
     {
      double local_minimum_price=DBL_MAX;
      int local_minimum_index=-1;
      for(int j=limit-nPeriod; j<=i; j++)
        {
         if(low[j]<local_minimum_price)
           {
            local_minimum_price=low[j];
            local_minimum_index=j;
           }
         SectionBuffer1[j]=0.0;
        }
      SectionBuffer1[local_minimum_index]=local_minimum_price;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Файлы:
1.mq5  6 kb
 
Vladimir Karputov:

Вот вариант, который работает онлайн - на истории не работает. Пример:

Вы можете опять посчитать моё сообщение оскорблением, но....

Такими примерами вы только отпугиваете желающих изучить mql5. Отбиваете всяческую охоту вникать в возможности языка.

В любой момент можно найти бар с максимальным и\или минимальным значением перечисления ENUM_SERIESMODE

В примере: ищем бар с максимальным значением high обозначенного вертикальной линией.


//+------------------------------------------------------------------+
//|                                                           00.mq5 |
//|                                                  Alexey Viktorov |
//|                     https://www.mql5.com/ru/users/alexeyvik/news |
//+------------------------------------------------------------------+
#property copyright "Alexey Viktorov"
#property link      "https://www.mql5.com/ru/users/alexeyvik/news"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   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[])
  {
//--- return value of prev_calculated for next call
 int barNumber = iHighest(_Symbol, PERIOD_H1, MODE_HIGH, 13, 9);
 Print(time[rates_total-1-barNumber]);
 Print(high[rates_total-1-barNumber]);
   return(rates_total);
  }
//+------------------------------------------------------------------+

void OnDeinit(const int reason)
{
 Comment("");
}/********************************************************************/

В результате выполнения кода получаем

2020.03.28 20:36:25.480 00 (EURUSD,H1)  2020.03.27 05:00:00
2020.03.28 20:36:25.480 00 (EURUSD,H1)  1.10866
 
Alexey Viktorov:

Вы можете опять посчитать моё сообщение оскорблением, но....

Такими примерами вы только отпугиваете желающих изучить mql5. Отбиваете всяческую охоту вникать в возможности языка.

В любой момент можно найти бар с максимальным и\или минимальным значением перечисления ENUM_SERIESMODE

В примере: ищем бар с максимальным значением high обозначенного вертикальной линией.


В результате выполнения кода получаем

Забудьте свои четверочные способы работы. OnCalculate даёт все необходимые массивы. 

 
Vladimir Karputov:

Забудьте свои четверочные способы работы. OnCalculate даёт все необходимые массивы. 

О каких четвёрочных способах вы говорите??? Это было сделано в mql5.

Да и в mql4 все необходимые массивы точно так-же присутствуют во входящих OnCalculate. В этом отношении языки mql4 и mql5 ничем не отличаются.

Файлы:
00.mq5  4 kb
 
Alexey Viktorov:

О каких четвёрочных способах вы говорите??? Это было сделано в mql5.

Да и в mql4 все необходимые массивы точно так-же присутствуют во входящих OnCalculate. В этом отношении языки mql4 и mql5 ничем не отличаются.

Функции iXXXX были перенесены из четверки - это не есть чистый MQl5.

 
TraSer:

Версия 1.001 - исправил работу на истории (хотя, как по мне) на истории данный индикатор информации не несёт:

//+------------------------------------------------------------------+
//|                                                        lines.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.001"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_label1  "DOWN-trend"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
input int nPeriod=10;
///---- int Widners Oscilator
double SectionBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---- Output in Char
   SetIndexBuffer(0,SectionBuffer1, INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//---
   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 limit=prev_calculated-1;
   if(prev_calculated==0)
     {
      for(int i=0; i<nPeriod; i++)
         SectionBuffer1[i]=0.0;
      limit=nPeriod;
     }
//---
   for(int i=limit; i<rates_total; i++)
     {
      double local_minimum_price=DBL_MAX;
      int local_minimum_index=-1;
      for(int j=i-nPeriod; j<=i; j++)
        {
         if(low[j]<local_minimum_price)
           {
            local_minimum_price=low[j];
            local_minimum_index=j;
           }
         if(SectionBuffer1[j]!=0.0)
            int d=0;
         SectionBuffer1[j]=0.0;
        }
      SectionBuffer1[local_minimum_index]=local_minimum_price;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Файлы:
1.mq5  6 kb
 
Vladimir Karputov:

Функции iXXXX были перенесены из четверки - это не есть чистый MQl5.

Я искать не буду то сообщение и даже не помню кто из разработчиков писал, но смысл был такой: Замерили скорость выполнения функций iXXX и по результатам пришли к мнению, что эти функции тормозить МТ5 не будут. В следствии чего было принято решение внести их в mql5. И даже в этом вы не точны. Функции iLowest и iHighest были в языке и раньше, альтернативы им нет. А внесли только iOpen, iHigh, iLow и iClose

 
TraSer:

Проверьте пожалуйста версию 1.001.

Что замечу: индикатор при поиске каждый раз возвращается на 'nPeriod' баров и ищет новый минимум. В следствии этого некоторые значения затираются. 

Также я бы реализовал такой индикатор в виде стиля DRAW_ARROW.

 
Vladimir Karputov:

Проверьте пожалуйста версию 1.001.

Что замечу: индикатор при поиске каждый раз возвращается на 'nPeriod' баров и ищет новый минимум. В следствии этого некоторые значения затираются. 

Также я бы реализовал такой индикатор в виде стиля DRAW_ARROW.

Немного изменил Ваш индикатор, и теперь он работает так, как мне хотелось бы.

//+------------------------------------------------------------------+
//|                                                        lines.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.001"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_label1  "DOWN-trend"
#property indicator_type1   DRAW_SECTION
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
input int nPeriod=10;
///---- int Widners Oscilator
double SectionBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---- Output in Char
   SetIndexBuffer(0,SectionBuffer1, INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//---
   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 limit=prev_calculated-1;
   if(prev_calculated==0)
     {
      for(int i=0; i<nPeriod; i++)
         SectionBuffer1[i]=0.0;
      limit=nPeriod;
     }
//---
   for(int i=limit; i<rates_total; i++)
     {
      double local_minimum_price=DBL_MAX;
      int local_minimum_index=-1;
      for(int j=i-nPeriod; j<=i; j++)
        {
         if(low[j]<local_minimum_price)
           {
            local_minimum_price=low[j];
            local_minimum_index=j;
           }
         if(local_minimum_index==i-(nPeriod/2))
            SectionBuffer1[local_minimum_index]=local_minimum_price;
         else
            SectionBuffer1[i-(nPeriod/2)]=0.0;
        }
      
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Но, к сожалению, я так и не понял, в чём была проблема. Если не сложно, не могли бы Вы объяснить?