Ошибка 4058 в build 210

 

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

20:00:02 Serfing GBPUSD,H4: TradeIsBusy() - GlobalVariableSetOnCondition ( "TradeIsBusy", 1.0, 0.0 ) - Error #4058

Причём, аналогичных строк там такое количество, что суточный лог стал весить 100-150 МВ!

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

 
Это ошибка ERR_GLOBAL_VARIABLE_NOT_FOUND, посмотрите в список ошибок:
https://docs.mql4.com/ru/runtime/errors
 
Renat:
Это ошибка ERR_GLOBAL_VARIABLE_NOT_FOUND, посмотрите в список ошибок:
https://docs.mql4.com/ru/runtime/errors


Я прекрасно знаю, что это за ошибка! И задал я свой вопрос потому, что раньше эта ошибка не возникала, а стала появляться в билде 210. И если Вы посмотрели процедуру TradeIsBusy(), то должны были понять, что в билде 210 существующая глобальная переменная периодически куда-то исчезает (о чём я абсолютно конкретно написал в своём посте). А это явный баг!

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

 
А Вы предварительно проверяете наличие такой глобальной переменной?

Новая версия клиентского терминала MetaTrader 4 build 209

Выпущен новый клиентский терминал MetaTrader 4 build 209:

1. Исправлена ошибка зависания терминала при отрисовке огромного количества вертикальных линий.

2. MQL4: исправлена ошибка формирования переменной last_error при обращении к несуществующей глобальной переменной.

3. MQL4: исправлена ошибка функции MessageBox, приводящая к крешу в 64-битных операционных системах.

4. Tester: исправлена генерация недельных и месячных данных при тестировании на других таймфреймах этого же инструмента.

5. Tester: убран режим моделирования контрольных точек.

6. Tester: исправлена ошибка неправильного появления экранных подсказок (тултипов) на графике оптимизации.

7. Tester: исправлена ошибка масштабирования окна графика оптимизации при использвании оптимизирующего параметра "математическое ожидание прибыли".

8. Tester: исправлена ошибка расчёта equity при срабатывании стопов.

9. Tester: исправлена ошибка генерации последнего тика при задании ограничивающих дат.

10. Tester: функция MarketInfo() отдаёт ненулевые значения размеров пункта и спреда для инструментов, присутствующих в окне котировок.
 

Естественно проверяю:

//+------------------------------------------------------------------+
// int TradeIsBusy( int MaxWaiting_sec = 30 )                        |
// Функция меняет значение глобальной переменной TradeIsBusy с 0     |
// на 1.                                                             |
// Если в момент запуска TradeIsBusy = 1, функция ждёт, пока         |
// TradeIsBusy станет = 0, и только потом меняет.                    |
// Если глобальной переменной TradeIsBusy не существует, функция     |
// создаёт её.                                                       |
// Коды возвратов:                                                   |
//  1 - успешное завершение. Глобальной переменной TradeIsBusy       |
// присвоено значение 1                                              |
// -1 - в момент запуска функции TradeIsBusy = 1, ожидание было      |
// прервано пользователем (эксперт удалён с графика, закрыт          |
// терминал, изменился период и/или символ графика, ... )            |
// -2 - в момент запуска функции TradeIsBusy = 1, истекло            |
// максимальное время ожидания (MaxWaiting_sec)                      |
//+------------------------------------------------------------------+
int TradeIsBusy(int MaxWaiting_sec = 30)
  {
// при тестировании нет смысла в разделении торгового потока - просто
// завершаем работу функции
      if(IsTesting()) 
          return(1);
      int _GetLastError = 0, StartWaitingTime = GetTickCount();
//+------------------------------------------------------------------+
//| Проверяем, существует ли гл. переменная и, если нет, создаём её  |
//+------------------------------------------------------------------+
      while(true)
        {
             // если эксперт был остановлен пользователем, прекращаем работу
             if(IsStopped()) 
               { 
                 Print("Эксперт был остановлен пользователем!"); 
                 return(-1); 
               }
             // если ожидание длится дольше времени, указанного в 
             // переменной MaxWaiting_sec, тоже прекращаем работу
             if(GetTickCount() - StartWaitingTime > MaxWaiting_sec * 1000)
               {
                    Print("Превышен лимит ожидания (" + MaxWaiting_sec + " сек.)!");
                    return(-2);
               }
             // проверяем, существует ли гл. переменная
             // если она есть, выходим из этого цикла и переходим к блоку изменения
             // значения TradeIsBusy
             if(GlobalVariableCheck("TradeIsBusy")) 
                 break;
             else
               // если GlobalVariableCheck вернула FALSE, значит либо переменной нет, 
               //либо при проверке возникла ошибка
               {
                    _GetLastError = GetLastError();
                    // если это всё таки ошибка, выводим информацию, ждём 0,1 секунды 
                    // и начинаем проверку сначала
                    if(_GetLastError != 0)
                      {
                           Print("TradeIsBusy() - GlobalVariableCheck( \"TradeIsBusy\" ) - Error #", 
                                 _GetLastError);
                           Sleep(100);
                           continue;
                      }
               }
             // если ошибки нет, значит глобальной переменной просто нет, пытаемся создать её
             // если GlobalVariableSet > 0, значит глобальная переменная успешно создана. 
             // Выходим из ф-ции
             if(GlobalVariableSet("TradeIsBusy", 1.0) > 0) 
                 return(1);
             else
               // если GlobalVariableSet вернула значение <= 0, значит при создании 
               // переменной возникла ошибка
               {
                    _GetLastError = GetLastError();
                    // выводим информацию, ждём 0,1 секунды и начинаем попытку сначала
                    if(_GetLastError != 0)
                      {
                           Print("TradeIsBusy() - GlobalVariableSet( \"TradeIsBusy\", 0.0 ) - Error #", 
                                 _GetLastError);
                           Sleep(100);
                           continue;
                      }
               }
       }
//+------------------------------------------------------------------+
//| Если выполнение функции дошло до этого места, значит глобальная  |
//| переменная существует.                                           |
//| Ждём, пока TradeIsBusy станет = 0 и меняем значение TradeIsBusy  |
//| с 0 на 1                                                         |
//+------------------------------------------------------------------+
      while(true)
        {
             // если эксперт был остановлен пользователем, прекращаем работу
             if(IsStopped()) 
               { 
                 Print("Эксперт был остановлен пользователем!"); 
                 return(-1); 
               }
             // если ожидание длится дольше времени, указанного в переменной 
             // MaxWaiting_sec, тоже прекращаем работу
             if(GetTickCount() - StartWaitingTime > MaxWaiting_sec * 1000)
               {
                    Print("Превышен лимит ожидания (" + MaxWaiting_sec + " сек.)!");
                    return(-2);
               }
             // пытаемся менять значение TradeIsBusy с 0 на 1
             // если нам это удаётся, выходим из ф-ции, возвращая 1 - 
             // "успешное завершение"
             if(GlobalVariableSetOnCondition("TradeIsBusy", 1.0, 0.0)) 
                 return(1);
             else
               // если нет, возможны 2 причины: TradeIsBusy = 1 (тогда надо ждать), 
               // либо возникла ошибка (это мы и проверим)
               {
                    _GetLastError = GetLastError();
                    // если это всё таки ошибка, выводим информацию и пробуем ещё раз
                    if(_GetLastError != 0)
                      {
                           Print("TradeIsBusy() - GlobalVariableSetOnCondition " + 
                                 "( \"TradeIsBusy\", 1.0, 0.0 ) - Error #", _GetLastError );
                           continue;
                      }
               }
             // если ошибки нет, значит TradeIsBusy = 1 (другой эксперт торгует) - 
             // выводим информацию и ждём...
             Comment("Ждём, пока другой эксперт закончит торговать...");
             Sleep(1000);
             Comment("");
        }
  }

Ошибка выдаётся самым последним: Print("TradeIsBusy() - GlobalVariableSetOnCondition " + "( \"TradeIsBusy\", 1.0, 0.0 ) - Error #", _GetLastError );

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

 
Уважаемые разработчики, хотелось бы всё-таки услышать Ваши пояснения.
 
Это ошибочное сообщение об ошибке. То есть, сама глобальная переменная существует, но поступает ложное сообщение об ошибке. Спасибо за сообщение, баг пофиксен и исправленный билд будет скоро доступен для скачивания.