Скачать MetaTrader 5

Как оптимально задать условие поиска увеличения размера некоего значения?

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Хочешь написать торгового робота? Загляни в Справочник MQL5!
Victor Demihov
618
Victor Demihov 2015.09.23 15:44 

 Появлиась задача определить наличие постоянно увеличивающегося значения возвращаемого некоторым расчётом. Я для простоты решил эткатать алгоритм на индюке. В общем вышла такая логика:

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                             Custom indicator initialization function                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------+
int OnInit()
{
   IndicatorBuffers(1);
   
   string name = WindowExpertName();
   
   // Связывание буфферов с индексами и определение стилей
   SetIndexBuffer (0, MaxSize);
   SetIndexStyle (0,  DRAW_NONE);
   SetIndexDrawBegin (0, 100);
   
   sequenceCount = 0;
//---
   return (INIT_SUCCEEDED);
}
//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                          Определение наличия увеличивающегося размера бара                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------+
bool ExistencePositiveSequence (int fi_Index)
{
   if (High [fi_Index] > High [fi_Index + 1])
   {
      sequenceCount++;
      
      return (true);
   }
   sequenceCount = 0;
   
   return (false);
}
//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                               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 = rates_total - prev_calculated;
   
   if (prev_calculated == 0) limit--;
   else limit++;
   
   for (int i = 0; i < limit; i++)
   {
      if ( (ExistencePositiveSequence (i) == true) && (sequenceCount == 3))
        CDraw.DrawObject (_Symbol, _Period,  OBJ_ARROW_UP, i, Time[i], Open[i]);
   }
   
//--- return value of prev_calculated for next call
   return (rates_total);
}

 Т.е. по сути у меня происходит возврат наличия на данном баре самой высокой точки чем на предыдущем, и инкрементируется счётчик sequenceCount с каждый выполнкннымусловием. Если условие выполняется заданное количесто раз ( на данный момент я вбил 3), то рисуется срелка.

 В общем, стрелкирисуются там где нужно, и видимо алгоритм верный, но есть какой то косяк. Вот скрин работы индюка:

 

Надеюсь задача понятна. Нужно найти места, где имеется 3 последовательно увеличивающихся бара.. И на3-ем баре нарисовать стрелку. Может алгоритм не корректный особо? Может можно иначе реализовать? Но тут просто всё, и вроде как нет резона что-то менять.

Victor Demihov
618
Victor Demihov 2015.09.24 17:22  
Неужели этот так сложно найти является ли текущий бар больше по размеру N-предыдущих ? Такое молчание, как-будто никто не понял, что я имел ввиду.
Рустам
3597
Рустам 2015.09.24 18:14  
но это же азы алгоритмизации, вы вон классы пишете...
Victor Demihov
618
Victor Demihov 2015.09.24 20:17  
FAQ:
но это же азы алгоритмизации, вы вон классы пишете...

Ну я что-то заклинил на этом. Нужно всего навсего определить является ли хай текущего бара самым высоким за N-баров. Почему у меня не верно определяется данный бар?

Код  я выше привёл. Что не так? 

Рустам
3597
Рустам 2015.09.24 20:21  
а вы попробуйте считать в обратную сторону
Victor Demihov
618
Victor Demihov 2015.09.25 07:13  
FAQ:
а вы попробуйте считать в обратную сторону
А разница какая? Ведь если с одной стороны идти то нужно сравнивать на > предыдущих, а с другой на .. > следующих. Но суть то не меняется. Причина то в чём? У меня ошибка логическая что-ли?
Рустам
3597
Рустам 2015.09.25 09:18  
shanty:
А разница какая? Ведь если с одной стороны идти то нужно сравнивать на > предыдущих, а с другой на .. > следующих. Но суть то не меняется. Причина то в чём? У меня ошибка логическая что-ли?
  хорошо, а скажите мне что будет с переменной sequenceCount когда она перевалит за "3" ? 
Victor Demihov
618
Victor Demihov 2015.09.25 11:08  
FAQ:
  хорошо, а скажите мне что будет с переменной sequenceCount когда она перевалит за "3" ? 
Тогда всё-равно вернуться должно значение sequenceCount больше 3 и выходи из функции ExistencePositiveSequence в true. Соответственно, объект, в данном случает стрелка, нарисуется на текущем баре. Самое главное, что в любом случае должно рисоваться на баре, у которого хай выше чем N-предыдущих. Но никак не иначе. А у меня стрелки рисуются даже когда текущий бар выше предыдущего, а предыдущий ниже пред предыдущего. Это почему?
Aleksey
248
Aleksey 2015.09.25 11:32  
Индексация элементов таймсерий производится задом наперед, от последнего к первому. Текущий бар, самый последний в массиве, имеет индекс 0. Самый старый бар, первый на графике, имеет индекс Bars-1.
Aleksey
248
Aleksey 2015.09.25 11:36  
Бары 6543210  у вас идёт сравнение 1 бар > 2, 2>3, 3>4  и на третьем рисуется стрелочка, всё правильно по коду, рисуется. Двигаетесь справа налево. В итоге находится нечто подобное где точка бар на котором рисуется стрелка ./
Victor Demihov
618
Victor Demihov 2015.09.26 07:52  
PozitiF:
Индексация элементов таймсерий производитсязадом наперед, от последнего к первому. Текущий бар, самый последний вмассиве, имеет индекс 0. Самый старый бар, первый на графике, имеетиндекс Bars-1.

Ну так это понятно. Это я знаю.

PozitiF:
Бары 6543210  у вас идёт сравнение 1 бар > 2, 2>3, 3>4  и на третьем рисуется стрелочка, всё правильно по коду, рисуется. Двигаетесь справа налево. В итоге находится нечто подобное где точка бар на котором рисуется стрелка ./

Теперь я понял, что нестыковка была в том, что я создавал объект не на баре, который в начале цикла, т.е. последний, а на последнем в цикле т.е. ближайшем в историю. Потому было смещение. 

 Поправил. Теперь вот так:

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                             Custom indicator initialization function                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------+
int OnInit()
{
   IndicatorBuffers(1);
   
   // Связывание буфферов с индексами и определение стилей
   SetIndexBuffer (0, MaxSize);
   SetIndexStyle (0,  DRAW_NONE);
   
   sequenceCount = 0;
   
   return (INIT_SUCCEEDED);
}
//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                          Определение наличия увеличивающегося размера бара                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------+
bool ExistencePositiveSequence (int fi_Index)
{
   if (High[fi_Index] > High[fi_Index + 1])
   {
      sequenceCount++;
      
      return (true);
   }
      sequenceCount = 0;
      
   return (false);
}
//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                               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 = rates_total - prev_calculated;
   
   if (prev_calculated == 0) limit--;
   
   else limit++;
   
   for (int i = 0; i < limit; i++)
   {
      if (ExistencePositiveSequence (i) == true)
      {  
         if (sequenceCount == 3)
           CDraw.DrawObject (_Symbol, _Period,  OBJ_ARROW_UP, 0, Time[0], Open[0]);
      }
   }
   
   return (rates_total);
}

  Как и задумано, сравниваются последние 3 бара. Если хай текущего бара больше предыдущих 3, то на текущем баре т.к. индекс у функции рисования 0, рисуется стрелка. Вижу, что не всё так как хотелось бы:

 вывы

Сейчас то что не так? 

123
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий