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

 

Сделайте примерно вот так, пусть у вас функция поиска вершинки сама ищет является ли переданный бар вершинкой, чтобы в основном теле программы было минимум ненужных действий. Вот примерно так, функция принимает номер бара и смотрит выше ли он левостоящих bars баров.

bool ExistencePositiveSequence (int fi_Index, int bars)
{
//---
   int cx=0;
//---
   if (High[fi_Index] > High[fi_Index + 1])
   {
      cx++;
      
      while(High[fi_Index+cx] > High[fi_Index+cx+1]){
         cx++;
         if(cx>=bars)return true;
      }
   }
   return (false);
}
 
CDraw.DrawObject (_Symbol, _Period,  OBJ_ARROW_UP, 0, Time[0], Open[0]);
Зачем поставили нули Time[0] Open[0] как метод рисования у вас узнает на каком именно баре рисовать стрелки ? Ещё одно, не знаю как у вас устроен данный метод но id объектов должны быть разными, хотя видимо это у вас учитывается раз несколько стрелок рисуется.
 

Согласен. С точки зрения ООП, это грамотнее реализовано. Но я лишь проверял свою мысль и не заморачивался над компановкой кода. Почему тогда у меня не верно? Ведь логически то написано всё нормально. Вы видите у меня не корректность вообще?

Переписал вот так:

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                          Определение наличия увеличивающегося размера бара                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------+
bool ExistencePositiveSequence (int fi_Index, int bars)
{
//---
   int cx = 0;
//---
   if (High[fi_Index] > High[fi_Index + 1])
   {
      cx++;
      
      while (High[fi_Index + cx] > High[fi_Index + cx + 1]){
         cx++;
         if (cx >= bars) return true;
      }
   }
   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, 3) == true)
      {  
         CDraw.DrawObject (_Symbol, _Period,  OBJ_ARROW_UP, 0, Time[0], Open[0]);
      }
   }
   return (rates_total);

 Теперь пропускает некоторые места на графике:

 ц

    Так что и этот вариант не работает как нужно.

 
CDraw.DrawObject (_Symbol, _Period,  OBJ_ARROW_UP, 0, Time[0], Open[0]);


вот тут почему поставили 0, выше об этом писал уже, у вас метод рисования не знает на каком именно баре стрелки рисовать, рисует только на 0 баре.

Time[i], Open[i]);
 
shanty:

Вы видите у меня не корректность вообще?

Вижу, некорректность именно в рисовании, с алгоритмом поиска всё отлично.
 
PozitiF:


вот тут почему поставили 0, выше об этом писал уже, у вас метод рисования не знает на каком именно баре стрелки рисовать, рисует только на 0 баре.

Если будет не 0, а i, то рисоваться будет объект на на последнем баре, т.е. на момент расчёта последнем, а на 3 в цикле, а это смещение на 3, как я понимаю. Я сделал, как Вы написали:

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                          Определение наличия увеличивающегося размера бара                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------+
bool ExistencePositiveSequence (int fi_Index, int bars)
{
//---
   int cx = 0;
//---
   if (High[fi_Index] > High[fi_Index + 1])
   {
      cx++;
      
      while (High[fi_Index + cx] > High[fi_Index + cx + 1]){
         cx++;
         if (cx >= bars) return true;
      }
   }
   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, 3) == true)
      {  
         CDraw.DrawObject (_Symbol, _Period,  OBJ_ARROW_UP, i, Time[i], Open[i]);
      }
   }
   return (rates_total);
}

 Всё-равно не корректно отрисовываются объекты. Вот на скрине можно увидеть сколько пропусков имеется:

 в

 Код из класса рисующий объект вот:

//=========================================================================================================================================
// Поиск объекта по имени. ================================================================================================================
bool DrawGrafics::FindObject (string fs_ObjName)
{
   if (ObjectFind (fs_ObjName) == -1)
      return (false);
   
   return (true);
}
//=========================================================================================================================================
// Удаление одного объекта по имени. ======================================================================================================
void DrawGrafics::DeleteOneObject (string       fs_ObjName,       // Имя объекта
                                   ENUM_OBJECT  fe_ObjType)       // Тип объекта
{
   string name = StringSubstr (fs_ObjName, 11, GetObjectLength (fe_ObjType));       // Извлекаем имя объекта
   
   ResetLastError();
   
   if (!StringCompare (name, GetObjName (fe_ObjType)))   return;         // Если выбран искомый объект..

   if (ObjectDelete (fs_ObjName))                               //.. Удалим его
   {
      // Перерисуем объект
      WindowRedraw();
   }
   else
   {
      Logging::WriteLog (StringConcatenate (__FUNCTION__, " => Не удалось стереть объект с именем: ", fs_ObjName, ". Ошибка № ", _LastError),
                         Logging::NeedLogs, Logging::PrintUP, Logging::CommentUP);
   }
}
//=========================================================================================================================================
// Удаление всех объектов по имени. =======================================================================================================
void DrawGrafics::DeleteAllObjects (void)
{
   string objName = NULL;
   
   for (int obj = ObjectsTotal(); obj >= 0; obj--)
   {
      objName = ObjectName (obj);
      
      if (StringSubstr (objName, 11, 10) != "OBJ_BUTTON")
      {
          ResetLastError();
          
          if (!ObjectDelete (objName))
          {
             Logging::WriteLog (StringConcatenate (__FUNCTION__, " => Не удалось стереть объект с именем: ", objName, ". Ошибка № ", _LastError),
                               Logging::NeedLogs, Logging::PrintUP, Logging::CommentUP);
          }
          
          // Перерисуем объект
          WindowRedraw();
      }
   }
}
//=========================================================================================================================================
// Отрисовка объета. ======================================================================================================================
void DrawGrafics::DrawObject (string       fs_Symbol,           // Символ инструмента, на графике которого рисуется стрелка
                              int          fi_TF,               // ТФ инструмента, на котором рисуется стрелочка
                              ENUM_OBJECT  fe_ObjType,          // Тип рисуемого объекта
                              int          fi_Number,           // Порядковый номер бара, с которого берутся данные ( Время и Цена )
                              datetime     fdt_Time1,           // Время открытия бара на заданном индексе
                              double       fd_Price1,           // Цена открытия бара на заданном индексе
                              datetime     fdt_Time2 = 0,       // Время открытия бара на заданном индексе
                              double       fd_Price2 = 0.0)     // Цена открытия бара на заданном индексе
{
   string objName = "";
   
   objName = StringConcatenate (_Symbol, "_", GetTFName (fi_TF), "_", GetObjName (fe_ObjType), "_",  fdt_Time1);
   
   if (!FindObject (objName))
   {
      ObjectCreate (objName, fe_ObjType, 0, fdt_Time1, fd_Price1);
   }
   else
   {
      DeleteOneObject (objName, fe_ObjType);
      
      ObjectCreate (objName, fe_ObjType, 0, fdt_Time1, fd_Price1);
      
      // Перерисуем объект
      WindowRedraw();
   }
}

 Уже не понятно в какую сторону и смотреть...

 
shanty:

Если будет не 0, а i, то рисоваться будет объект на на последнем баре, т.е. на момент расчёта последнем, а на 3 в цикле, а это смещение на 3, как я понимаю. Я сделал, как Вы написали:

Нет будет рисоваться именно на текущем баре если он выше 3 левостоящих. По скрину пропусков вроде не вижу. Нарисуйте на скрине где вы видите пропуск ?
 
PozitiF:
Нет будет рисоваться именно на текущем баре если он выше 3 левостоящих. По скрину пропусков вроде не вижу. Нарисуйте на скрине где вы видите пропуск ?

Вот на вскиду:

 

Терминал не может не корректно отображать данные? 

 


Ну так разве там должна быть стрелка ? Хай бара указаного стрелкой возьмём за 0 он выше 1 (левостоящего) далее сравнивается 1 бар со 2, а вот второй уже не выше 3 потому нет стрелки. Знак не в ту сторону, но думаю понятно.

 

Хотя всё верно. Мне нужно было 2 повышающихся вершины, а это значит что счётчик будет не 3, а 2. Такой вариант работает. Тока если я уберу строку:

if (prev_calculated == 0) limit--;

Из функции OnCalculate(), то индикатор сообщает ошибку времени выполнения:

2015.09.26 17:38:43.858 2014.08.26 07:00  MaxSizeOfSequenceBars_PositiF.ex4 EURUSD,M15: array out of range in 'MaxSizeOfSequenceBars_PositiF.mq4' (48,29)

 Это ещё почему?

Я понимаю, что происходит выход за пределы массива. Но где, не понятно. 

Причина обращения: