MetaTrader 5 build 3620: Web Terminal improvements, ONNX support and fast matrix multiplications in MQL5

Added support for operations with ONNX models (Open Neural Network Exchange). ONNX is an open-source format for machine learning models

10 March 2023

Terminal

  1. Fixed total profit calculations in trading reports.
  2. Updated fundamental data for trading instruments available through the Market Watch window.
  3. Fixed trading platform launch under Wine 7.0.1 in Linux-systems.
  4. Fixed adding of symbols to the Market Depth via the search bar. A symbol found by description could not be added to the list by clicking on its line.

MQL5

  1.  Added support for operations with ONNX models (Open Neural Network Exchange).

    ONNX is an open-source format for machine learning models. This format is supported by many platforms, including Chainer, Caffee2 and PyTorch. Create an ONNX model using specialized tools, integrate it into your MQL5 application and use it to make trading decisions.

    Descriptions of all supported functions are available in the documentation. An example of a test ONNX model is available in public projects in MetaEditor. Find the ONNX.Price.Prediction project in "Toolbox \ Public projects" and select Join in the context menu. The project will download to your computer and will appear in the Navigator:


    An example of working with an ONNX model in public projects


    Compile the project and run it on EURUSD H1 to see the result.

    In addition to the model and the MQL5 code which runs it, the project also includes the PricePredictionTraining.py Python script. It shows how you can create an ONNX model yourself. To run the script, install Python on your computer and the required modules from the prompt line:

    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
    Instructions on how to use ONNX are available in the documentation.

  2. Added support for General Matrix Multiplication (GeMM). This algorithm speeds up calculations on some processor types through parallelized tasks and optimized utilization of L1/L2/L3 caches. The calculation speed is comparable with popular packages such as Math Kernel Library (MKL) and OpenBLAS. Detailed comparative tests will be published soon.

    The new algorithm is currently supported in the matrix::GeMM method. If your processor supports AVX and FMA instructions (most processors released after 2013 support these instructions), the algorithm will be enabled automatically.

  3.  Added ability to transfer matrices and vectors to DLL. This enables the import of functions which utilize the relevant types, from external variables.

    Matrices and vectors are passed to a DLL as a pointer to a buffer. For example, to pass a matrix of type float, the corresponding parameter of the function exported from the DLL must take a float-type buffer pointer. For example:

    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)
    In addition to buffers, you should pass matrix and vector sizes for correct processing.

  4. Added new CopySeries function for copying synchronized timeseries from MqlRates into separate arrays.

    The CopySeries function allows obtaining only the necessary timeseries into different specified arrays during one call, while all of timeseries data will be synchronized. This means that all values in the resulting arrays at a certain index N will belong to the same bar on the specified Symbol/Timeframe pair. Therefore, there is no need for the programmer to additionally synchronize the received timeseries by the bar opening time.

    Unlike CopyRates, which returns the full set of timeseries as an MqlRates array, the CopySeries function allows obtaining specific required timeseries into separate arrays. This can be done by specifying a combination of flags to select the type of timeseries. The order of the arrays passed to the function must match the order of the fields in the MqlRates structure:

    struct MqlRates
      {
       datetime time;         // period beginning time
       double   open;         // open price
       double   high;         // high price for the period
       double   low;          // low price for the period
       double   close;        // close price
       long     tick_volume;  // tick volume
       int      spread;       // spread
       long     real_volume;  // exchange volume
      }

    Thus, if you need to get the values of the 'time', 'close' and 'real_volume' timeseries for the last 100 bars of the current Symbol/Timeframe, you should use the following call:

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

    The order of the arrays "time, close, volume" must match the order of the fields in the MqlRates structure. The order of values in the rates_mask is ignored. The mask could be as follows:

    COPY_RATES_VOLUME_REAL|COPY_RATES_TIME|COPY_RATES_CLOSE

    Example

    //--- 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)
      {
    //--- arrays to get timeseries from the Rates structure
       double   open[];
       double   close[];
       float    closef[];
       datetime time1[], time2[];
    //---request close prices to a double array
       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);
       
    
    //--- now also request open prices; use float array for close prices
       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);
    //--- compare the received data
       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]);
            }
         }
    /*  Result
            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   |
    */
      }
  5. Fixed OrderSend function operation. The function request could return an incorrect order ticket if the same account was used simultaneously on several platforms.
  6. Fixed import of EX5 libraries. An error occurred if the name of the imported library matched the name of the file into which it was imported.

MetaEditor

  1.  Added sending of push notifications to shared project members. The new option can notifies users of changes in project settings and files. To enable notifications, enter your MetaQuotes ID under the "Settings \ Security" section of your MQL5.community profile.


    Push notifications about project updates


  2. Updated file icons in the Navigator. New, simpler metaphors will make them easier to understand.

Tester

  1. Fixed an error which caused the input string parameter to be truncated if it contained the "|" character.

MetaTrader 5 Web Terminal build 3620

  1. Added ready-made color templates for the web terminal interface. The templates affect the display of chart bars and lines, and the prices in the Market Watch and account financial statements. Our design team has prepared color template presets, based on your suggestions and on traditional color combinations.


    New web terminal color templates


  2. Redesigned symbol specification window. Trading instrument data has been rearranged into logical blocks for ease of viewing.


    Updated trading instrument specification window


  3. Fixed opening of real accounts via the web terminal. The server could return an error after filling out a registration form.
  4. Fixed an error in the trading dialog. If the user closed a position by pressing the X button in the Toolbox window while the position modification dialog was open, the dialog contents were not reset. After the update, the dialog will automatically reset to a new order placing mode in this case.
  5. Fixed display of the Server field in the account management dialog.
  6. Fixed display of the current timeframe on the toolbar.
  7. Fixed display of volumes in terms of underlying asset units, in the trading dialog.
  8. Fixed modification of Stop Loss and Take Profit levels. Modifying one of the values could reset the second one under certain conditions.
  9. Fixed display of investment risk warnings.