Библиотеки: IsNewBar

 

IsNewBar:

Класс СIsNewBar для определения момента времени, когда происходит смена бара. Обычно для таких вещей используется не класс, а просто функция IsNewBar(). Но такая функция содержит статическую переменную, и по этой причине нельзя использовать несколько вызовов этой функции. Для многократного использования такой функции в коде эксперта гораздо удобнее будет сделать ее членом класса, что и было выполнено в данном случае с помощью библиотеки IsNewBar.mqh.

Автор: Nikolay Kositsin

 
Я не профи, но по моему этот код ошибочен. Переменная Recount всегда true. И следовательно каждый тик будет воспринят как новый бар. Зачем там вообще эта переменная? Зачем там вообще вызывать CopyClose? Выкладываемые коды вообще проверяются на правильную работу? Если я ошибаюсь. то прошу поправить и объяснить.
 
lordlev:
Я не профи, но по моему этот код ошибочен. Переменная Recount всегда true. И следовательно каждый тик будет воспринят как новый бар. Зачем там вообще эта переменная? Зачем там вообще вызывать CopyClose? Выкладываемые коды вообще проверяются на правильную работу? Если я ошибаюсь. то прошу поправить и объяснить.
Ещё раз всё перепроверил и нашёл ошибку. В самом прикреплённом файле отсутствует присвоение Recount значения false, а в коде примера всё верно.
 
lordlev:
Ещё раз всё перепроверил и нашёл ошибку. В самом прикреплённом файле отсутствует присвоение Recount значения false, а в коде примера всё верно.
Ну это поправимо!
 

возможно я и ошибаюсь. но помойму вот так будет правильнее

if(TNew>m_TOld)

 иначе во время подкачки (правки истории) будет неточность работы

Не моглибы Вы пояснить что это и для чего вставлена такая проверка

if(...  && TNew)

 я её не понимаю. Когда это условии истинно, когда ложно? Спасибо 

 
Prival:

Не моглибы Вы пояснить что это и для чего вставлена такая проверка

 я её не понимаю. Когда это условии истинно, когда ложно? Спасибо 

Имхо, это проверка того, что TNew не равно m_TOld и одновременно не равно нулю ( т.е. D'1970.01.01 00:00:00')...

Второе условие, также имхо, проверяет, что функция

datetime TNew=datetime(SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE));

вернула что-то отличное от нуля... 

Сейчас запустил скрипт с этой функцией - вернула мне как раз 0. Может из-за выходных.

 
Prival:

Не моглибы Вы пояснить что это и для чего вставлена такая проверка

 я её не понимаю. Когда это условии истинно, когда ложно? Спасибо 

Проверка на ноль нужна, чтобы сразу при старте и первой проверке условия не получить начало нового бара (не зависимо от того, сколько прошло времени с его открытия).
 
Prival:

возможно я и ошибаюсь. но помойму вот так будет правильнее

 иначе во время подкачки (правки истории) будет неточность работы

Не моглибы Вы пояснить что это и для чего вставлена такая проверка

 я её не понимаю. Когда это условии истинно, когда ложно? Спасибо 

Пожалуй, для перестраховки будет более логичным сделать

if(TNew>m_TOld && TNew)

хотя при подкачке истории всё-равно TNew будет равно нулю. Ноль в переменную TNew может попасть в любой момент времени, так что делать проверку на отсутствие нуля следует всё время.

 
Automated-Trading:

IsNewBar:

Автор: Николай Косицин

В вашем классе(как и в большинстве функций, код которых я видел ) есть небольшая ошибка . При первом вызове метода IsNewBar он всегда возвращает true, независимо от наличия реального нового бара.

Но такая функция содержит статическую переменную, и поэтому мы не можем использовать несколько вызовов этой функции.

Для хранения времени открытия последнего бара можно также использовать двумерный массив.

 
Я сделал альтернативную версию CIsNewBar, без статической переменной. Я просто использовал Tick.time_msc, чтобы сделать идемпотентную функцию:


class CIsNewBar{
private:
   long checkedMs;
   datetime lastBarOpenedAt;
   bool lastValue;
   CTickUtils tickUtils;
public:
   CIsNewBar(){}
   ~CIsNewBar(){}

   bool isNewBar(){
      MqlTick tick;
      SymbolInfoTick(_Symbol, tick);
      long tickMs = tick.time_msc;

      
      if(checkedMs >= tickMs){ //уже обрабатывали эту функцию на этом тике?
         return lastValue;     //так, верните буферизованное значение
      }

      datetime time[1];
      CopyTime(_Symbol, _Period, 0, 1, time);


      if(lastBarOpenedAt != time[0]){
         lastBarOpenedAt = time[0];
         lastValue = true;
      } else {
         lastValue = false;
      }

      checkedMs = tickMs;
      return lastValue;
   }
 

Я думаю, что это быстрый легкий класс, который устраняет вышеупомянутые проблемы.

Эта версия:

  • не будет выдавать ложное предупреждение при первом вызове функции.isNewBar().
  • устраняет постоянное повторное создание новых переменных при каждом вызове функции, не используя статические переменные, что ускоряет выполнение.
  • возвращает значение true только один раз для каждого бара.
  • занимает мало места в памяти.
class CIsNewBar{
        private:
                datetime lastBarOpenedAt;
                datetime time[1];
        public:
                CIsNewBar(){CopyTime(_Symbol, _Period, 0, 1, time);lastBarOpenedAt = time[0];}
                ~CIsNewBar(){}
                bool isNewBar(){
                        CopyTime(_Symbol, _Period, 0, 1, time);
                        if(lastBarOpenedAt < time[0]){
                                lastBarOpenedAt = time[0];
                                return(true);
                                }
                        else { return(false);}
                        }
        };

Чтобы реализовать класс:

CIsNewBar someName;

void OnTick(){
        if(someName.isNewBar()){
                /// Вызовите новый обработчик события bar или
                /// Выполните работу для нового бара. 
                }
        }
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
  • www.mql5.com
Predefined Macro Substitutions - Named Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5