---
title: "MetaTrader 5 build 3620: Web Terminal improvements, ONNX support and fast matrix multiplications in MQL5 - Release Notes"
description: "Added support for operations with ONNX models (Open Neural Network Exchange). ONNX is an open-source format for machine learning models. - Release Notes"
image: "https://www.metatrader5.com/c/17/1/public-project.png"
---

# 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](https://www.metatrader5.com/en/releasenotes/terminal/2251).
2. Updated [fundamental data](https://www.metatrader5.com/en/terminal/help/trading/market_watch#fundamental) for trading instruments available through the Market Watch window.
3. Fixed trading platform launch under Wine 7.0.1 in [Linux-systems](https://www.metatrader5.com/en/terminal/help/start_advanced/install_linux).
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](https://en.wikipedia.org/wiki/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](https://www.mql5.com/go?link=https://chainer.org/), [Caffee2](https://www.mql5.com/go?link=https://caffe2.ai/) and [PyTorch](https://www.mql5.com/go?link=https://pytorch.org/). 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](https://www.mql5.com/en/docs/onnx). An example of a test ONNX model is available in [public projects](https://www.metatrader5.com/en/metaeditor/help/mql5storage/projects#public) 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](https://www.metatrader5.com/c/17/1/public-project.png)

   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](https://www.mql5.com/en/docs/onnx).
2. Added support for [General Matrix Multiplication](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms#Level_3) (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](https://en.wikipedia.org/wiki/Math_Kernel_Library) (MKL) and [OpenBLAS](https://en.wikipedia.org/wiki/OpenBLAS). Detailed comparative tests will be published soon. The new algorithm is currently supported in the [matrix::GeMM](https://www.mql5.com/en/docs/matrix/matrix_products/matrix_gemm) method. If your processor supports [AVX](https://en.wikipedia.org/wiki/Advanced_Vector_Extensions) and [FMA](https://en.wikipedia.org/wiki/FMA_instruction_set) 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](https://www.mql5.com/en/docs/basis/preprosessor/import) 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](https://www.mql5.com/en/docs/series/copyseries) function for copying synchronized timeseries from [MqlRates](https://www.mql5.com/en/docs/constants/structures/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](https://www.mql5.com/en/docs/constants/structures/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](https://www.mql5.com/en/docs/constants/structures/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](https://www.mql5.com/en/docs/trading/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](https://www.metatrader5.com/en/metaeditor/help/mql5storage/projects#shared) members. The new option can notifies users of changes in project settings and files. To enable notifications, enter your [MetaQuotes ID](https://www.mql5.com/en/articles/476) under the "Settings \ Security" section of your [MQL5.community](https://www.mql5.com/) profile.

   ![Push notifications about project updates](https://www.metatrader5.com/c/17/1/notification__iphone.jpg)
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](https://www.metatrader5.com/c/17/1/web-color-scheme.jpg)
2.  Redesigned symbol specification window. Trading instrument data has been rearranged into logical blocks for ease of viewing.

   ![Updated trading instrument specification window](https://www.metatrader5.com/c/17/1/web-specification.jpg)
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.

**Earlier publications:**

- [MetaTrader 5 for iPhone/iPad: Improved on-chart trading and analytical functions](https://www.metatrader5.com/en/releasenotes/terminal/2277)
- [MetaTrader 5 build 3550: Improvements and fixes](https://www.metatrader5.com/en/releasenotes/terminal/2265)
- [MetaTrader 5 platform build 3540: 2FA/TOTP authentication and improved Market Watch in Web Terminal](https://www.metatrader5.com/en/releasenotes/terminal/2264)
- [MetaTrader 5 build 3520: 2FA/TOTP authentication using Google Authenticator](https://www.metatrader5.com/en/releasenotes/terminal/2262)
- [MetaTrader 5 build 3510: Web Terminal improvements](https://www.metatrader5.com/en/releasenotes/terminal/2261)
