Обсуждение статьи "Рецепты MQL5 - Изучение свойств позиции в тестере MetaTrader 5"

 

Опубликована статья Рецепты MQL5 - Изучение свойств позиции в тестере MetaTrader 5:

Модифицированная версия эксперта из предыдущей статьи "Рецепты MQL5 - Свойства позиции на пользовательской информационной панели". Рассмотрим ряд вопросов: получение данных баров, отслеживание события "новый бар" на текущем символе, подключение торгового класса стандартной библиотеки, создание функции поиска торговых сигналов, создание функции для выполнения торговых операций, а также определение торгового события в функции OnTrade().

Рецепты MQL5 - Изучение свойств позиции в тестере MetaTrader 5

Автор: Anatoli Kazharski

 

Добрый вечер, подскажите плиз, в функции CheckNewBar статическая переменная new_bar обнуляется в первой же строчке, а потом логика фукции строится на том, равна она нулю или нет. Подскажите плиз - где я не понимаю ?!?!

bool CheckNewBar()
  {
//--- Переменная для времени открытия текущего бара
   static datetime new_bar=NULL;
//--- Массив для получения времени открытия текущего бара
   static datetime time_last_bar[1]={0};
//--- Получим время открытия текущего бара
//    Если возникла ошибка при получении, сообщим об этом
   if(CopyTime(_Symbol,Period(),0,1,time_last_bar)==-1)
     { Print(__FUNCTION__,": Ошибка копирования времени открытия бара: "+IntegerToString(GetLastError())+""); }
//--- Если это первый вызов функции
   if(new_bar==NULL)
     {
      // Установим время
      new_bar=time_last_bar[0];
      Print(__FUNCTION__,": Инициализация ["+_Symbol+"][TF: "+TimeframeToString(Period())+"]["
            +TimeToString(time_last_bar[0],TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"]");
      return(false); // Вернём false и выйдем 
     }
//--- Если время отличается
   if(new_bar!=time_last_bar[0])
     {
      new_bar=time_last_bar[0]; // Установим время и выйдем 
      return(true); // Запомним время и вернем true
     }
//--- Дошли до этого места - значит бар не новый, вернем false
   return(false);
  }
 
Sergey Voytsekhovsky:

Добрый вечер, подскажите плиз, в функции CheckNewBar статическая переменная new_bar обнуляется в первой же строчке, а потом логика фукции строится на том, равна она нулю или нет. Подскажите плиз - где я не понимаю ?!?!

В справке сказано:

Локальные переменные, объявленные с ключевым словом static сохраняют свои значения в течение всего времени существования  функции. При каждом следующем вызове функции такие локальные переменные содержат те значения, которые они имели при предыдущем вызове.

То есть при новом вызове функции CheckNewBar()  переменная new_bar будет сохранять значение полученное при предыдущем вызове функции, но в первой же строке ей будет присвоено новое значение NULL...... и тогда совсем мне не понятно зачем все это и как оно работает. Плиз развейте мои непонятки, скорее всего я где-то туплю, вот только ГДЕ ???

 
Sergey Voytsekhovsky:

Добрый вечер, подскажите плиз, в функции CheckNewBar статическая переменная new_bar обнуляется в первой же строчке, а потом логика фукции строится на том, равна она нулю или нет. Подскажите плиз - где я не понимаю ?!?!

Если я правильно понял Справку, в строчке    static datetime new_bar=NULL;  "Если начальные значения не указаны, то переменные статического класса памяти принимают нулевые начальные значения." Значит ее вообще не нужно было инициализировать нулем и тогда логика была бы безупречна. Или нет ???

 
Sergey Voytsekhovsky:

Если я правильно понял Справку, в строчке    static datetime new_bar=NULL;  "Если начальные значения не указаны, то переменные статического класса памяти принимают нулевые начальные значения." Значит ее вообще не нужно было инициализировать нулем и тогда логика была бы безупречна. Или нет ???

Инициализировать переменные НУЖНО всегда. Это неписанный закон. Тот кто его не выполняет - рано или поздно вылавливает очень трудновылавливаемые ошибки :)


Как работает статическая переменная:

//+------------------------------------------------------------------+
//|                                                      Test EA.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- we work only at the time of the birth of new bar
   static datetime PrevBars=0;
   Print("PrevBars ",PrevBars);
   datetime time_0=iTime(Symbol(),Period(),0);
   if(time_0==PrevBars)
      return;
   PrevBars=time_0;
   Print("New bar. PrevBars ",PrevBars);
  }
//+------------------------------------------------------------------+


Распечатка во вкладку "Эксперты". Самый первый вход в OnTick() - инициализация статической переменной, новый бар.

2018.01.08 00:00:00   PrevBars 1970.01.01 00:00:00
2018.01.08 00:00:00   New bar. PrevBars 2018.01.08 00:00:00
2018.01.08 00:00:30   PrevBars 2018.01.08 00:00:00
2018.01.08 00:00:59   PrevBars 2018.01.08 00:00:00
2018.01.08 00:01:00   PrevBars 2018.01.08 00:00:00
2018.01.08 00:01:00   New bar. PrevBars 2018.01.08 00:01:00
2018.01.08 00:01:30   PrevBars 2018.01.08 00:01:00
2018.01.08 00:02:00   PrevBars 2018.01.08 00:01:00
Файлы:
Test_EA.mq5  4 kb
 
Vladimir Karputov:

Инициализировать переменные НУЖНО всегда. Это неписанный закон. Тот кто его не выполняет - рано или поздно вылавливает очень трудновылавливаемые ошибки :)


Как работает статическая переменная:


Распечатка во вкладку "Эксперты". Самый первый вход в OnTick() - инициализация статической переменной, новый бар.

ОК, понял, спасибо за лаконичный и очень доходчивый ответ.

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