Новая версия платформы MetaTrader 4 build 1335: Улучшения для Wine/macOS

 

В пятницу 14 мая 2021 года будет выпущена обновленная версия платформы MetaTrader 4. Обновление содержит следующие изменения:

  1. Проведена большая оптимизация работы под Wine на компьютерах с macOS и Linux:

    • Исправлено отображение писем, новостей и чата, а также разделов "Сигналы" и "Маркет".
    • Исправлено обновление содержимого окна "Навигатор" в MetaEditor.
    • Улучшено отображение иконок на панели инструментов.
    • Исправлена работа команд печати графиков.
    • Исправлено отображение панели торговли одним кликом.

  2. Обновлен DMG-пакет для легкой установки MetaTrader 4 на компьютерах с macOS. При помощи него платформа устанавливается как обычное приложение — нужно перетащить иконку платформы в Applications и дождаться, пока закончится инсталляция.

    В пакет были включены дополнительные компоненты, необходимые для более стабильной и быстрой работы. Тем, кто его использует, настоятельно рекомендуется переустановить MetaTrader 4 по ссылке https://download.mql5.com/cdn/web/metaquotes.software.corp/mt4/MetaTrader4.dmg

  3. Снижено потребление ресурсов в десктопной версии MetaTrader 4.
  4. Внесены исправления по крешлогам.

Обновление будет доступно через систему Live Update.

 
MetaQuotes:
Снижено потребление ресурсов в десктопной версии MetaTrader 4.

В каких местах удалось что-то ускорить? Дайте немного деталей, пожалуйста.

 
Терминалы под Виндой будут самообновляться как при прочих апдейтах или это только для Wine/macOS?
 

Пока не обновилось до 1335. В версии 1330 от 19 марта 2021 года возникает ошибка. Будет ли эта ошибка в 1335 версии?

Ошибка следующая:

2021.05.14 23:54:23.949 ZUP GBPUSD,Weekly: array out of range in 'ZUP.mq4' (46673,35)

Возникает следующим образом. Вывожу индикатор на месячном тф. Работает без ошибок.

Переключаю на недельный тф. Возникает ошибка.

Проверяю размер индикаторного буфера. Размер остался такой же, как на месячном тф.

Сделал тестовый индикатор для иллюстрации ошибки:

//+------------------------------------------------------------------+
//|                                                    test_Bars.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2

double zzL[];
double zzH[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   
//--- indicator buffers mapping
bool yyy=   SetIndexBuffer(0,zzL);
   SetIndexBuffer(1,zzH);
   Print(__LINE__,"  ArraySize(zzL) = ",ArraySize(zzL),"  Bars = ",iBars(_Symbol,Period()),"   Period() = ",Period(),   "   yyy = ",yyy);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
  
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//--------------------------------------------------------
void OnChartEvent(const int id, 
                  const long &lparam, 
                  const double &dparam, 
                  const string &sparam) 
  { 
  if (id==CHARTEVENT_CHART_CHANGE)
    {
    Print(__LINE__,"  ArraySize(zzL) = ",ArraySize(zzL),"  Bars = ",iBars(_Symbol,Period()),"   Period() = ",Period());
    }
  } 

Во вкладке Эксперты на Месячном тф:

2021.05.15 00:17:33.046 test_Bars GBPUSD,Monthly: 58  ArraySize(zzL) = 293  Bars = 293   Period() = 43200   yyy = true

Переключаем на недельный тф:

2021.05.15 00:36:53.634 test_Bars GBPUSD,Weekly: 25  ArraySize(zzL) = 293  Bars = 1185   Period() = 10080   yyy = true

2021.05.15 00:36:53.634   test_Bars GBPUSD,Weekly: 58  ArraySize(zzL) = 293  Bars = 1185   Period() = 10080

То есть при переключении на недельный тф размер буферного массива остался таким, как он был на месячном тф.

И далее вычисления индикатора происходят с ошибками. 

============

Ошибка возникает в блоке if (id==CHARTEVENT_CHART_CHANGE)

Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
  • www.mql5.com
MQL5: язык торговых стратегий для MetaTrader 5, позволяет писать собственные торговые роботы, технические индикаторы, скрипты и библиотеки функций
 
Andrey Khatimlianskii:

В каких местах удалось что-то ускорить? Дайте немного деталей, пожалуйста.

Больше ленивой загрузки ресурсов и инициализации по требованию.

 
Yurij Kozhevnikov:
Терминалы под Виндой будут самообновляться как при прочих апдейтах или это только для Wine/macOS?

Обновляются все

 
Eugeni Neumoin:

Пока не обновилось до 1335. В версии 1330 от 19 марта 2021 года возникает ошибка. Будет ли эта ошибка в 1335 версии?

На вашем примере у меня нормально перевыделяется рабочий буфер при переключениях таймфреймов:

2021.05.15 02:24:42.452 Test EURUSD,M5: 57  ArraySize(zzL) = 2048  Bars = 2048   Period() = 5
2021.05.15 02:24:16.243 Test EURUSD,M1: 57  ArraySize(zzL) = 2887  Bars = 2887   Period() = 1
2021.05.15 02:24:05.080 Test EURUSD,H4: 57  ArraySize(zzL) = 12114  Bars = 12114   Period() = 240

Обратите внимание, что система автоматически будет перестраивать буфер только для пересчета данных (первый раз и при приходе новых данных в OnCalculate).

Судя по всему, у вас множество сторонних OnChartEvent обработчиков, которые почему то думают, что под этот обработчик происходит обязательное и гарантированное перераспределение и перевычисление индикаторного буфера.

Думая так, вы берете совершенно другое значение количество баров из iBars и почему-то(!!!) считаете, что индикаторный буфер уже под него перевыделен и пересчитан. Это заблуждение.


Если вы работаете с индикаторным буфером вне OnCalculate, вы обязаны работать исключительно с фактическими размерностями этого буфера и не использовать никакие другие индексы/счетчики/размерности. Для гарантии в OnCalculate ведите вместе с буфером переменную с точным размером посчитанных данных.


То есть, в вашем коде ошибка с индексами из-за неправильного понимания размерностей рабочего буфера.
 
Renat Fatkhullin:

На вашем примере у меня нормально перевыделяется рабочий буфер при переключениях таймфреймов:

Обратите внимание, что система автоматически будет перестраивать буфер только для пересчета данных (первый раз и при приходе новых данных в OnCalculate).

Судя по всему, у вас множество сторонних OnChartEvent обработчиков, которые почему то думают, что под этот обработчик происходит обязательное и гарантированное перераспределение и перевычисление индикаторного буфера.

Думая так, вы берете совершенно другое значение количество баров из iBars и почему-то(!!!) считаете, что индикаторный буфер уже под него перевыделен и пересчитан. Это заблуждение.


Если вы работаете с индикаторным буфером вне OnCalculate, вы обязаны работать исключительно с фактическими размерностями этого буфера и не использовать никакие другие индексы/счетчики/размерности. Для гарантии в OnCalculate ведите вместе с буфером переменную с точным размером посчитанных данных.


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

Хорошо. Я упросил тестовую программу.

Удалил  OnChartEvent. Проверил все окна с графиками. Ни на одном графике нет установленных программ.

И проверяю только в блоке OnInit:

//+------------------------------------------------------------------+
//|                                                    test_Bars.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2

double zzL[];
double zzH[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   
//--- indicator buffers mapping
bool yyy=   SetIndexBuffer(0,zzL);
   SetIndexBuffer(1,zzH);
   Print(__LINE__,"  ArraySize(zzL) = ",ArraySize(zzL),"  Bars = ",iBars(_Symbol,Period()),"   Period() = ",Period(),   "   yyy = ",yyy);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
  
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//--------------------------------------------------------
/*void OnChartEvent(const int id, 
                  const long &lparam, 
                  const double &dparam, 
                  const string &sparam) 
  { 
  if (id==CHARTEVENT_CHART_CHANGE)
    {
    Print(__LINE__,"  ArraySize(zzL) = ",ArraySize(zzL),"  Bars = ",iBars(_Symbol,Period()),"   Period() = ",Period());
    }
  }*/

Переключаю тф с максимального - месячного вниз.

Результаты:

2021.05.15 08:45:51.947 test_Bars GBPUSD,Monthly: 25  ArraySize(zzL) = 2305  Bars = 293   Period() = 43200   yyy = true

2021.05.15 08:50:51.086 test_Bars GBPUSD,Weekly: 25  ArraySize(zzL) = 293  Bars = 1185   Period() = 10080   yyy = true
2021.05.15 08:51:04.380 test_Bars GBPUSD,Daily: 25  ArraySize(zzL) = 1185  Bars = 2305   Period() = 1440   yyy = true
2021.05.15 08:51:16.453 test_Bars GBPUSD,H4: 25  ArraySize(zzL) = 2305  Bars = 16847   Period() = 240   yyy = true
2021.05.15 08:51:34.993 test_Bars GBPUSD,H1: 25  ArraySize(zzL) = 16847  Bars = 19139   Period() = 60   yyy = true

=====================


Похоже, что обработчик  OnChartEvent, когда включен только даже он один, работает с этими данными из  OnInit.

Ошибки возникают в функциях доступа к данным буфера: Time, Low и так далее. В программе стоит проверка с размером iBars. Значение этого размера правильное.

А вот  ArraySize(zzL) показывает другое значение. И именно это значение является фактическим для функций доступа к данным буфера. То есть массив с буфером имеет размер старого значения.

В примере выше вообще нет никаких сторонних обработчиков.

Цитата: " Обратите внимание, что система автоматически будет перестраивать буфер только для пересчета данных (первый раз..."

- Это в OnInit?

 
Eugeni Neumoin:

И проверяю только в блоке OnInit:

onint - это инициализация, то есть все перераспределяется заново.
По вашим результатам очевидно что буфер имеет предыдущий размер и еще не увеличен под будущий ТФ.
Перенесите принт в OnCalculate и будут одинаковые значения. (если все данные загружены)

Очевидно жеж что в ините подгружаются данные, и всё может еще измениться.
У вас в коде нет подгрузки истории, нет проверки на подгрузку истории. В такие моменты нужно делать полный перерасчет всего.

if (rates_total-prev_calculated>1) 
   {
   //загрузились новые бары, делаем перерасчет всех данных и перерисовываем всё
   }
 
Eugeni Neumoin:

Хорошо. Я упросил тестовую программу.

Удалил  OnChartEvent. Проверил все окна с графиками. Ни на одном графике нет установленных программ.

И проверяю только в блоке OnInit:

Переключаю тф с максимального - месячного вниз.

Результаты:

2021.05.15 08:45:51.947 test_Bars GBPUSD,Monthly: 25  ArraySize(zzL) = 2305  Bars = 293   Period() = 43200   yyy = true

2021.05.15 08:50:51.086 test_Bars GBPUSD,Weekly: 25  ArraySize(zzL) = 293  Bars = 1185   Period() = 10080   yyy = true
2021.05.15 08:51:04.380 test_Bars GBPUSD,Daily: 25  ArraySize(zzL) = 1185  Bars = 2305   Period() = 1440   yyy = true
2021.05.15 08:51:16.453 test_Bars GBPUSD,H4: 25  ArraySize(zzL) = 2305  Bars = 16847   Period() = 240   yyy = true
2021.05.15 08:51:34.993 test_Bars GBPUSD,H1: 25  ArraySize(zzL) = 16847  Bars = 19139   Period() = 60   yyy = true

=====================


Похоже, что обработчик  OnChartEvent, когда включен только даже он один, работает с этими данными из  OnInit.

Ошибки возникают в функциях доступа к данным буфера: Time, Low и так далее. В программе стоит проверка с размером iBars. Значение этого размера правильное.

А вот  ArraySize(zzL) показывает другое значение. И именно это значение является фактическим для функций доступа к данным буфера. То есть массив с буфером имеет размер старого значения.

В примере выше вообще нет никаких сторонних обработчиков.

Цитата: " Обратите внимание, что система автоматически будет перестраивать буфер только для пересчета данных (первый раз..."

- Это в OnInit?

Вы категорически не понимаете принципа работы индикаторов. И не умеете полностью читать точные обьяснения.

А именно, что размеры расчетных буферов гарантируются только в OnCalculate. Мало того, ArraySize расчетного буфера может быть больше реально доступного количества баров - догадайтесь сами, почему. Поэтому, если хотите работать с буфером вне OnCalculate, запоминайте количество реально просчитанных в OnCalculate данных в отдельной переменной.

 
Renat Fatkhullin:

Обновляются все

Здравствуйте Ренат! Убидительная к Вам просьба, выложить таки, пусть на стороннем ресурсе гугл/яндекс диске крайний дистрибутив МТ4 под windows/wine от/под MetaQuotes, очень иногда нужен и актуален, пожалуйста.

С уважением, Михаил.