Скачать MetaTrader 5

Как получить номер бара по времени входа в позицию?

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

Приветствую!

Пишу трейлинг, который проходится по барам начиная от времени входа в позицию. Никак не могу найти функцию, которая бы определял номер бара текущего символа и периода по времени.

В MQL4 такая функция был (iBarShift), а в 5-й версии её, судя по всему, нет.

Подскажите, пожалуйста, её просто переименовали или совсем убрали?  Может быть есть альтернативные функции, которые делают то, что мне нужно?

Artyom Trishkin
Модератор
81501
Artyom Trishkin  
varenich:

Приветствую!

Пишу трейлинг, который проходится по барам начиная от времени входа в позицию. Никак не могу найти функцию, которая бы определял номер бара текущего символа и периода по времени.

В MQL4 такая функция был (iBarShift), а в 5-й версии её, судя по всему, нет.

Подскажите, пожалуйста, её просто переименовали или совсем убрали?  Может быть есть альтернативные функции, которые делают то, что мне нужно?

//+------------------------------------------------------------------+
int GetBarShift(string symbol_name,ENUM_TIMEFRAMES timeframe,datetime time) {
   if(time<0) return(-1);
   //---
   datetime array[], time0;
   if(CopyTime(symbol_name,timeframe,0,1,array)<0) return(-1);
   time0=array[0];
   if(CopyTime(symbol_name,timeframe,time0,time,array)<0) return(-1);
   datetime temptime=GetTime(symbol_name,timeframe,ArraySize(array)-1);
   if(array[0]==temptime && temptime<=time) return(ArraySize(array)-1);
   else return(ArraySize(array));
}
//+------------------------------------------------------------------+
fxsaber
6720
fxsaber  
Artyom Trishkin:
//+------------------------------------------------------------------+
int GetBarShift(string symbol_name,ENUM_TIMEFRAMES timeframe,datetime time) {
   if(time<0) return(-1);
   //---
   datetime array[], time0;
   if(CopyTime(symbol_name,timeframe,0,1,array)<0) return(-1);
   time0=array[0];
   if(CopyTime(symbol_name,timeframe,time0,time,array)<0) return(-1);
   datetime temptime=GetTime(symbol_name,timeframe,ArraySize(array)-1);
   if(array[0]==temptime && temptime<=time) return(ArraySize(array)-1);
   else return(ArraySize(array));
}
//+------------------------------------------------------------------+
Это очень дорого и не полностью. Оптимально
int iBarShift( const string Symb, const ENUM_TIMEFRAMES TimeFrame, const datetime time )
{
  int Res = -1;
  datetime LastBar;

   if (::SeriesInfoInteger(Symb, TimeFrame, ::SERIES_LASTBAR_DATE, LastBar))
   {
      if (time > LastBar)  
        Res = 0;
      else
      {
        const int Shift = ::Bars(Symb, TimeFrame, time, LastBar);
        
        if (Shift > 0)
          Res = Shift - 1;
      }
    }
  
  return(Res);
}
Artyom Trishkin
Модератор
81501
Artyom Trishkin  
fxsaber:
Это очень дорого и не полностью. Оптимально
Чудесно. Благодарю, возьмём на вооружение.
Евгений Панин
243
Евгений Панин  

Привет!

Спасибо всем за помощь!

Я тоже вышел из ситуации с помощью функции Bars, которой на вход можно передать нужное время и точку отсчета (текущее время). На выход она выдаёт количество баров от точки отсчета до нужного времени.

Всё сработало.

Еще раз спасибо тем, кто откликнулся. 

Artyom Trishkin
Модератор
81501
Artyom Trishkin  
varenich:

Привет!

Спасибо всем за помощь!

Я тоже вышел из ситуации с помощью функции Bars, которой на вход можно передать нужное время и точку отсчета (текущее время). На выход она выдаёт количество баров от точки отсчета до нужного времени.

Всё сработало.

Еще раз спасибо тем, кто откликнулся. 

Bars() возвращает количество баров, но вот смещение не всегда показывает верно. Проверьте.
George Merts
4097
George Merts  
Хм... Век живи - век учись... Я использовал бинарный поиск... А оказывается, его можно заменить такой хорошей функцией (если ИНОГДА возникает ошибка в смещении - это просто надо иметь ввиду, и корректировать возвращаемое значение путем полного перебора в этом случае)
Евгений Панин
243
Евгений Панин  
Нашел еще один способ - через стандартный класс CiTime: https://www.mql5.com/ru/docs/standardlibrary/technicalindicators/timeseries/citime/citimegetdata
Документация по MQL5: Стандартная библиотека / Классы для работы с индикаторами / Таймсерии / CiTime / GetData
Документация по MQL5: Стандартная библиотека / Классы для работы с индикаторами / Таймсерии / CiTime / GetData
  • www.mql5.com
Стандартная библиотека / Классы для работы с индикаторами / Таймсерии / CiTime / GetData - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
Alexey Kozitsyn
7297
Alexey Kozitsyn  
fxsaber:
Это очень дорого и не полностью. Оптимально
int iBarShift( const string Symb, const ENUM_TIMEFRAMES TimeFrame, const datetime time )
{
  int Res = -1;
  datetime LastBar;

   if (::SeriesInfoInteger(Symb, TimeFrame, ::SERIES_LASTBAR_DATE, LastBar))
   {
      if (time > LastBar)  
        Res = 0;
      else
      {
        const int Shift = ::Bars(Symb, TimeFrame, time, LastBar);
        
        if (Shift > 0)
          Res = Shift - 1;
      }
    }
  
  return(Res);
}
Не совсем корректно. В условии time > LastBar должно быть >= . А вообще, спасибо.
Alexey Kozitsyn
7297
Alexey Kozitsyn  

Модифицировал функцию. Убрал ошибку для случая, когда time = времени открытия бара. Добавил возможность указать порядок нумерации. Добавил возврат времени открытия свечи:

Если есть вариант проще или есть ошибки - напишите, пожалуйста.
 

Alexey Kozitsyn
7297
Alexey Kozitsyn  
Alexey Kozitsyn:
Если есть вариант проще или есть ошибки - напишите, пожалуйста.

Исправлена ошибка при старте терминала:

//+------------------------------------------------------------------+
//| Номер бара по времени                                            |
//+------------------------------------------------------------------+
int iBarShift( const string symbol,               // Символ
              const ENUM_TIMEFRAMES timeframe,    // Период
              const datetime time,                // Время для нахождения номера бара
              const bool asSeries,                // Флаг порядка нумерации
              datetime &barOpenTime               // Время открытия бара (out)
             )
  {
//--- Искомый номер
   int res=WRONG_VALUE;
//--- Время открытия последнего бара
   datetime lastBar;
//--- Получаем время открытия последнего бара по символу/периоду
   if(SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE,lastBar))
     {
      //--- Количество баров в истории
      const int bars=Bars(symbol,timeframe);
      const bool sync = (bool)SeriesInfoInteger( symbol, timeframe, SERIES_SYNCHRONIZED );
      if( bars <= 0 || !sync )                    // Если функция не сработала|история не синхронизирована
         return( res );                           // Возвращаем ложное значение
      //--- Проверка на нулевой бар
      if( time >= lastBar )                       // Если время не больше времени открытия последней свечи
         res =( asSeries ) ? 0 : bars-1;          // Номер последнего бара
      else                                        // Если время меньше времени открытия последней свечи
        {
         //--- Получаем количество баров в истории до времени открытия свечи time
         int shift=Bars(symbol,timeframe,time,lastBar);
         //--- Определяем время открытия бара для времени time
         barOpenTime=GetBarOpenTime(symbol,timeframe,time);
         //--- Проверяем корректность данных
         if(barOpenTime>0 && shift>0) // Если время корректно и количество баров найдено
           {
            //--- Проверяем, совпадает ли время открытия бара с временем time
            shift=(barOpenTime==time) ? shift-1 : shift;   // Изменяем сдвиг при необходимости
            //--- Определяем номер бара в зависимости от индексации баров
            res=(asSeries) ? shift : bars-shift-1;
           }
        }
     }
   else                         // Если значение не получено - ошибка
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": Время открытия последнего бара по "+symbol+
            " "+EnumToString(timeframe)+" не получено!");
//--- Возвращаем номер бара
   return( res );
  }
//+------------------------------------------------------------------+
//| Получаем время открытия свечи по времени time                    |
//+------------------------------------------------------------------+
datetime GetBarOpenTime( const string symbol,              // Символ
                        const ENUM_TIMEFRAMES timeframe,   // Период
                        const datetime time                // Момент времени
                        )
  {
//--- Массив - приемник
   datetime t[1];
//--- Получаем время открытия бара
   if( CopyTime( symbol,timeframe, time, 1, t ) == 1 )     // Если время получено
      return( t[ 0 ] );                                    // Возвращаем время открытия бара
   else                                                    // Если время не получено
     {
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": время открытия свечи для момента "+TimeToString(time,TIME_DATE|TIME_SECONDS)+
            " не получено!");                              // Ошибка
      return(0);                                           // Возвращаем ошибочное значение
     }
  }


 

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