Новая версия платформы MetaTrader 5 build 3620: улучшения веб-терминала, поддержка ONNX и ускоренное умножение матриц в MQL5

MetaQuotes  

В пятницу 10 марта 2023 года будет выпущена обновленная версия платформы MetaTrader 5.

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

Новая версия платформы MetaTrader 5 build 3620: улучшения веб-терминала, поддержка ONNX и ускоренное умножение матриц в MQL5

Помимо этого, в MQL5 появилась поддержка нового алгоритма умножения матриц General Matrix Multiplication (GeMM). Он позволяет значительно ускорить вычисления на большинстве процессоров. На данный момент новый алгоритм поддерживается в методе matrix::GeMM.

Также в MQL5 появилась поддержка работы с моделями ONNX. Это позволит значительно облегчить использование нейронных сетей в торговых советниках.

Обновление содержит следующие изменения:


MetaTrader 5 Client Terminal build 3620

  1. Terminal: Исправлена ошибка при подсчете итоговой прибыли в торговом отчете.
  2. Terminal: Обновлены фундаментальные данные по торговым инструментам, доступные через Обзор рынка.
  3. Terminal: Исправлен запуск торговой платформы под Wine 7.0.1 при работе в Linux-системах.
  4. Terminal: Исправлено добавление символов в Обзор рынка через строку поиска. Символ, найденный по описанию, было невозможно добавить в список кликом мыши на его строке.
  5. MQL5: Добавлена поддержка работы с моделями ONNX (Open Neural Network Exchange).

    ONNX — открытая библиотека для построения нейронных сетей глубокого обучения. Этот формат поддерживается множеством платформ, включая Chainer, Caffee2 и PyTorch. Создав ONNX модель при помощи специализированных инструментов, вы можете интегрировать ее в свою MQL5-программу и использовать для принятия торговых решений.

    Описание всех поддерживаемых функций доступно в документации. Пример работы с тестовой моделью доступен в публичных проектах в MetaEditor. Найдите проект ONNX.Price.Prediction в разделе "Инструменты \ Публичные проекты", а затем нажмите "Присоединиться" в контекстном меню. Проект загрузится на компьютер и появится в Навигаторе:


    Пример работы с ONNX моделю в публичных проектах


    Скомпилируйте проект и запустите его на EURUSD H1, чтобы посмотреть результат.

    Помимо готовой модели и MQL5-кода для ее запуска, в проекте также доступен Python скрипт PricePredictionTraining.py. Он показывает, как самостоятельно создать модель ONNX. Для работы скрипта установите на свой компьютер Python, а также необходимые модули из командной строки:

    python.exe -m pip install --upgrade pip
    python -m pip install --upgrade tensorflow
    python -m pip install --upgrade pandas
    python -m pip install --upgrade scikit-learn
    python -m pip install --upgrade matplotlib
    python -m pip install --upgrade tqdm
    python -m pip install --upgrade metatrader5
    python -m pip install --upgrade onnx==1.12
    python -m pip install --upgrade tf2onnx
    Подробные инструкции по работе с ONNX доступны в документации.

  6. MQL5: Добавлена поддержка нового алгоритма умножения матриц General Matrix Multiplication (GeMM). Он позволяет значительно ускорить вычисления на большинстве процессоров за счет распараллеливания задач и более правильного использования кэшей L1/L2/L3. Скорость вычисления при этом сравнима с такими известными пакетами, как Math Kernel Library (MKL) и OpenBLAS. В ближайшее время мы опубликуем подробные сравнительные тесты.

    Новый алгоритм на данный момент поддерживается в методе matrix::GeMM. Если ваш процессор поддерживает инструкции AVX и FMA (большинство процессоров, выпущенных после 2013 года), алгоритм будет задействован автоматически.

  7. MQL5: Добавлена поддержка передачи матриц и векторов в DLL. Теперь вы можете импортировать функции, использующие этот тип данных, из внешних библиотек.

    Матрицы и векторы передаются в DLL в виде указателя на буфер. Например, для передачи матрицы типа float, соответствующий параметр экспортируемой из DLL-функции должен принимать указатель на буфер с типом float. Пример:

    MQL5
    #import "mmlib.dll"
    bool sgemm(uint flags,matrix<float> &C,const matrix<float> &A,const matrix<float> &B,ulong M,ulong N,ulong K,float alpha,float beta);
    #import
    C++
    extern "C" __declspec(dllexport) bool sgemm(UINT flags,float *C,const float *A,const float *B,UINT64 M,UINT64 N,UINT64 K,float alpha,float beta)
    Для правильной обработки матриц и векторов, кроме их буферов, следует передавать их размеры.

  8. MQL5: Добавлена новая функция CopySeries для копирования синхронизированных таймсерий из MqlRates в отдельные массивы.

    Функция CopySeries позволяет за один раз получать только нужные таймсерии в разные указанные массивы, при этом они все синхронизированы между собой. Это означает, что все значения в полученных массивах по конкретному индексу N будут принадлежать одному и тому же бару на указанной паре символ/таймфрейм. В этом случае не требуется заботиться о том, чтобы все полученные таймсерии были синхронизированы по времени открытия бара.

    В отличие от CopyRates, которая возвращает полный набор таймсерий в виде массива MQLRates, функция CopySeries позволяет программисту получать только нужные таймсерии на основе комбинации флагов, указывающих тип запрашиваемых таймсерий. При этом порядок массивов, передаваемых в функцию, должен соответствовать порядку полей в структуре MqlRates:

    struct MqlRates
      {
       datetime time;         // время начала периода
       double   open;         // цена открытия
       double   high;         // наивысшая цена за период
       double   low;          // наименьшая цена за период
       double   close;        // цена закрытия
       long     tick_volume;  // тиковый объем
       int      spread;       // спред
       long     real_volume;  // биржевой объем
      }

    Таким образом, если необходимо получить значения таймсерий time, close и real_volume для последних 100 баров текущего символа/таймфрейма, вызов должен быть следующим:

    datetime  time[];
    double    close[];
    long      volume[];
    CopySeries(NULL,0,0,100,COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_VOLUME_REAL,time,close,volume);
    

    При этом важен порядок массивов "time, close, volume" — он должен соответствовать порядку полей в структуре MqlRates. А вот порядок значений в маске rates_mask значения не имеет, маска могла быть такой :

    COPY_RATES_VOLUME_REAL|COPY_RATES_TIME|COPY_RATES_CLOSE

    Пример

    //--- input parameters
    input datetime InpDateFrom=D'2022.01.01 00:00:00';
    input datetime InpDateTo  =D'2023.01.01 00:00:00';
    input uint     InpCount   =20;
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart(void)
      {
    //--- массивы для получения таймсерий из ценовой структуры Rates
       double   open[];
       double   close[];
       float    closef[];
       datetime time1[], time2[];
    //---запросим цены закрытия в массив типа double
       ResetLastError();
       int res1=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount,
                           COPY_RATES_TIME|COPY_RATES_CLOSE, time1, close);
       PrintFormat("1. CopySeries  returns %d values. Error code=%d", res1, GetLastError());
       ArrayPrint(close);
       
    
    //--- теперь запросим еще цены открытия, а цены закрытия в массив типа float
       ResetLastError();
       int res2=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount,
                           COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_OPEN, time2, open, closef);
       PrintFormat("2. CopySeries  returns %d values. Error code=%d", res2, GetLastError());
       ArrayPrint(closef);
    //--- сравним полученные данные
       if((res1==res2) && (time1[0]==time2[0]))
         {
          Print("  | Time             |    Open      | Close double | Close float |");
          for(int i=0; i<10; i++)
            {
             PrintFormat("%d | %s |   %.5f    |   %.5f    |   %.5f   |",
                         i, TimeToString(time1[i]), open[i], close[i], closef[i]);
            }
         }
    /*  Результат
            1. CopySeries  returns 0 values. Error code=0
            [ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604
            [10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247
            2. CopySeries  returns 0 values. Error code=0
            [ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604
            [10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247
              | Time             |    Open      | Close double | Close float |
            0 | 2023.03.01 17:00 |   1.06660    |   1.06722    |   1.06722   |
            1 | 2023.03.01 18:00 |   1.06722    |   1.06733    |   1.06733   |
            2 | 2023.03.01 19:00 |   1.06734    |   1.06653    |   1.06653   |
            3 | 2023.03.01 20:00 |   1.06654    |   1.06520    |   1.06520   |
            4 | 2023.03.01 21:00 |   1.06520    |   1.06573    |   1.06573   |
            5 | 2023.03.01 22:00 |   1.06572    |   1.06649    |   1.06649   |
            6 | 2023.03.01 23:00 |   1.06649    |   1.06694    |   1.06694   |
            7 | 2023.03.02 00:00 |   1.06683    |   1.06675    |   1.06675   |
            8 | 2023.03.02 01:00 |   1.06675    |   1.06684    |   1.06684   |
            9 | 2023.03.02 02:00 |   1.06687    |   1.06604    |   1.06604   |
    */
      }
  9. MQL5: Исправлена ошибка, в редких случаях приводившая к получению некорректного тикета ордера после отправки запроса функцией OrderSend. Ошибка могла возникать при параллельной торговле на одном счете через разные платформы.
  10. MQL5: Исправлена ошибка импорта EX5-библиотек. Она возникала, если имя импортируемой библиотеки совпадало с именем файла, в который она импортируется.
  11. MetaEditor: Добавлена рассылка Push-уведомлений участникам групповых проектов. Теперь каждый участник всегда будет в курсе любых изменений в файлах или настройках проекта. Для получения уведомлений укажите свой MetaQuotes ID в разделе "Настройки \ Безопасность" вашего профиля MQL5.community.


    Push-уведомления об изменениях в проекте


  12. MetaEditor: Обновлены иконки файлов в Навигаторе. Новые более простые метафоры облегчат восприятие информации.
  13. Tester: Исправлена ошибка, приводившая к обрезанию входного строкового параметра, если в нем присутствовал символ "|".
  14. Исправления по крешлогам.

MetaTrader 5 Web Terminal build 3620

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


    Новые цветовые схемы для веб-терминала


  2. Переработано окно спецификации торгового инструмента. Все данные перекомпонованы в компактные логические блоки для более удобного просмотра.


    Обновленное окно спецификации торгового инструмента


  3. Исправлено открытие реальных счетов через веб-терминал. В некоторых случаях после заполнения регистрационной формы сервер мог возвращать ошибку.
  4. Исправлена ошибка в торговом диалоге. Если пользователь открывал диалог модификации позиции, а затем закрывал позицию кнопкой "X" в окне инструментов, содержимое диалога не сбрасывалось. Теперь в этом случае диалог будет автоматически возвращаться в режим выставления нового ордера.
  5. Исправлено отображение поля Server в диалоге управления счетами.
  6. Исправлено отображение текущего таймфрейма на панели инструментов.
  7. Исправлено отображение объема в количестве единиц базового актива в торговом диалоге.
  8. Исправлена модификация уровней "Стоп Лосс" и "Тейк Профит". В некоторых случаях модификация одного значения могла приводить к сбросу второго.
  9. Исправлено отображение предупреждения о рисках инвестора.

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

Vitaliy Kuznetsov  

1. Где в WEB терминале увидеть его билд?

2. Плюс думаю, что лот стоит синхронизировать со значением панели  быстрой торговли.

Если же выставлять лот в панели слева, то после закрытия и открытия данного меню лот становится на 0.01 меньше

3. Когда делаешь масштаб графика фиксированным (уменьшив по вертикали) и начинаешь график таскать по кругу, иногда видно как масштаб прыгает 

4. Когда переключаешь пары. График улетает значительно левее, бывает что вообще за экран.

Возможно нужна отсечка, которая запоминается, если график утягиваем влево, но не должна меняться при смене пары или тф

5. Хотелось бы видеть выпадающий список выбора тф, как сами знаете где, плюс в десктоп версии

Неделю и месяц можно унести туда в выпадающий список. Функционала больше, места экономнее

Alexey Viktorov  
MetaQuotes:

В пятницу 3 марта 2023 года будет выпущена обновленная версия платформы MetaTrader 5 в бета-режиме.

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

6. MQL5: Добавлена новая функция CopySeries для копирования синхронизированных таймсерий из MqlRates в отдельные массивы.

Будут-ли добавлены варианты функции CopySeries аналогично функции CopyRates 

int  CopyRates(
   string           symbol_name,       // имя символа
   ENUM_TIMEFRAMES  timeframe,         // период
   datetime         start_time,        // с какой даты
   int              count,             // сколько копируем
   MqlRates         rates_array[]      // массив, куда будут скопированы данные
   );
int  CopyRates(
   string           symbol_name,       // имя символа
   ENUM_TIMEFRAMES  timeframe,         // период
   datetime         start_time,        // с какой даты
   datetime         stop_time,         // по какую дату
   MqlRates         rates_array[]      // массив, куда будут скопированы данные
   );
Stanislav Korotky  
Более актуально было бы появление Copy-функций с синхронизацией сразу по нескольким инструментам.
Roman  
Stanislav Korotky #:
Более актуально было бы появление Copy-функций с синхронизацией сразу по нескольким инструментам.

Полностью согласен. Причём с синхронизацией не по OHLC а по тикам.

MetaQuotes:

2. MQL5: Добавлена новая функция CopySeries для копирования синхронизированных таймсерий из MqlRates в отдельные массивы.

То есть CopyRates может возвращать несинхронизированные таймсерии MqlRates одного инструмента ?
Где об этом сказано в документации???
Я вообще в шоке от таких новостей.
И давно возмущён, почему вы позволяете терминалу возвращать не подготовленные данные.
Любой Си программист, знает жёсткое правило, запрещено возвращать область памяти, если в ней ещё содержаться некорректные данные, по сути мусор.
У вас почему-то это правило игнорируется совсем, и не дожидаясь корректных данных, возращаете то что есть.


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

Файлы:
0jjpg.zip  364 kb
Nikolai Semko  

MetaQuotes:

MQL5: Добавлена новая функция CopySeries для копирования синхронизированных таймсерий из MqlRates в отдельные массивы.

Все также нельзя копировать более TERMINAL_MAXBARS баров?

Dmi3  

Сделайте, пожалуйста, заявки с признаком только пассивные.

Это именно то, что от вас ждут ВСЕ, торгующие через МТ5 на Мосбирже. 

https://www.mql5.com/ru/forum/435703

Заявки с признаком только пассивные (BoC - Book-or-Cancel)
Заявки с признаком только пассивные (BoC - Book-or-Cancel)
  • 2022.11.03
  • www.mql5.com
В декабре 2022 года на Срочном рынке будет добавлен новый признак заявки только пассивная. https://www.moex...
Renat Fatkhullin  
Roman #:

Полностью согласен. Причём с синхронизацией не по OHLC а по тикам.

То есть CopyRates может возвращать несинхронизированные таймсерии MqlRates одного инструмента ?
Где об этом сказано в документации???
Я вообще в шоке от таких новостей.
И давно возмущён, почему вы позволяете терминалу возвращать не подготовленные данные.
Любой Си программист, знает жёсткое правило, запрещено возвращать область памяти, если в ней ещё содержаться некорректные данные, по сути мусор.
У вас почему-то это правило игнорируется совсем, и не дожидаясь корректных данных, возращаете то что есть.


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

Из документации: https://www.mql5.com/ru/docs/series/copyseries

Примечание

Если интервал запрашиваемых таймсерий полностью находится вне доступных данных на сервере, то функция возвращает -1. В случае если запрашиваются данные находятся за пределами TERMINAL_MAXBARS (максимальное количество баров на графике), функция также вернет -1.

При запросе данных из индикатора, если запрашиваемые таймсерии еще не построены или их необходимо загрузить с сервера, то функция сразу же вернет -1, но при этом сам процесс загрузки/построения будет инициирован.

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

Не наводите панику. Никаких "областей памяти с некорректными данными" нет.

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

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

Достаточно одного раза, чтобы вы словили "вечное синхронное ожидание данных", чтобы навсегда забыть о таком желании. Фактически это бы убивало всех роботов у всех трейдеров.

Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Состояние клиентского терминала
Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Состояние клиентского терминала
  • www.mql5.com
Состояние клиентского терминала - Состояние окружения - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
Roman  
Renat Fatkhullin #:

Из документации: https://www.mql5.com/ru/docs/series/copyseries

Примечание

Если интервал запрашиваемых таймсерий полностью находится вне доступных данных на сервере, то функция возвращает -1. В случае если запрашиваются данные находятся за пределами TERMINAL_MAXBARS (максимальное количество баров на графике), функция также вернет -1.

При запросе данных из индикатора, если запрашиваемые таймсерии еще не построены или их необходимо загрузить с сервера, то функция сразу же вернет -1, но при этом сам процесс загрузки/построения будет инициирован.

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

Не наводите панику. Никаких "областей памяти с некорректными данными" нет.

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

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

Достаточно одного раза, чтобы вы словили "вечное синхронное ожидание данных", чтобы навсегда забыть о таком желании. Фактически это бы убивало всех роботов у всех трейдеров.

Да, с сетевым взаимодействием соглашусь.
Но фактически закачка данных происходит на момент старта программы, или открытие нового графика, или реконнекта и т.д.
То есть в момент когда никаких решений ещё не принимается, а ожидается получение этих данных чтоб принять потом решение ))
Какой смысл отдавать неполные данные в терминал после таймаута! Если для принятия решения их ещё недостаточно, так как данные не полные и не конечные.
Вот в чём вопрос был. Их же можно накапливать, причём не обязательно в память если вопрос упирается в ограниченные ресурсы пользователя.
И дождавшись полной загрузки с теми же сетевыми таймаутами, затем полностью отдать готовые данные в окружение терминала.
Таким образом исключается получение пользователем, не тех данных которые он ожидал, при обращении к функции.
"Функция вернет то количество данных, которые будут готовы к моменту истечения таймаута"

Но по большому счёту удивление было в другом, то что ввели CopySeries для копирования синхронизированных таймсерий из MqlRates
Несложно сделать вывод, что CopyRates как я понял может возвращать таймсерии, со сдвигом между массивами структуры MqlRates.
Вот по этому поводу и было негодование. Или я не так понял? И не к тому отношу слово синхронизация?
А введённая CopySeries как раз решает проблему отдачи данных между таймаутами?
И данные всегда будут те которые ожидал, на момент обращения функцией?



А по кастомному символу на видео, какая-то фигня происходит.
Или реал тайм данные не корректно считаются в формуле, или ещё что-то...
Формула самая простая 

-1*EURUSD + GBPUSD + EURGBP


История строит одно, а реал тайм строит другое.
И после нажатия обновить, происходит перестроение. 

И ещё. Было бы не плохо в настройках кастомного символа, увидеть параметр задающий частоту обновления.
Так как согласно документации, кастомный символ построенный через формулу, обновляется десять раз в секунду.
т.е. 100 ms, что достаточно многовато, и хотелось бы самому задавать частоту обновления.

fxsaber  

По Тестеру в списке изменений ничего нет, поэтому пишу о проблеме в b3580, с которой за сутки столкнулся второй раз.


В Тестере нажатие на кнопку Старт ничего не вызывает. Все Агенты ready, в логах пусто, даже кратковременного переключения Старт->Стоп не происходит.

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


В обоих случаях помогала перезагрузка Терминала.

Vitaliy Kuznetsov  
fxsaber #:

По Тестеру в списке изменений ничего нет, поэтому пишу о проблеме в b3580, с которой за сутки столкнулся второй раз.


В Тестере нажатие на кнопку Старт ничего не вызывает. Все Агенты ready, в логах пусто, даже кратковременного переключения Старт->Стоп не происходит.

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


В обоих случаях помогала перезагрузка Терминала.

Возможно, если была визуализация, сначала надо закрыть то окно.

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