Discussion of article "Matrix and Vector operations in MQL5"

 

New article Matrix and Vector operations in MQL5 has been published:

Matrices and vectors have been introduced in MQL5 for efficient operations with mathematical solutions. The new types offer built-in methods for creating concise and understandable code that is close to mathematical notation. Arrays provide extensive capabilities, but there are many cases in which matrices are much more efficient.

Over the past years, we have done a lot to introduce advanced technologies into the MQL5 language:


      The MQL5 language will continue to develop, while one of the top priority direction is machine learning. We have big plans for further development. So, stay with us, support us, and keep learning with us.

      Author: MetaQuotes

       
      matrix corr_from_matrix=rates.CorrCoef(false);   // false means that vectors are in strings матрицы

      Sure it's not in the columns?

       
          //--- get Close prices into vector
          if(close.CopyRates(symbols[i], InTF, COPY_RATES_CLOSE, 1, InBars))
           {
            //--- insert the vector into the timeseries matrix
            rates.Col(close, i);

      Unfortunately, this simple way of filling the matrix has a serious flaw: multicurrency bars are not synchronised.

      Perhaps it makes sense to make the standard CopyRates method for matrices as well, in order to get correct data as easily.

       
      We paid attention to the simple filling of vectors with price data. However, there are also trades.
      vector::Deals( void* Filter );

      Accordingly, it is necessary to fill the Statistics section not only with mathematical methods, but also with financial ones: Gain, MaxDD, PF, etc.

       
      fxsaber #:

      Sure it's not in the columns?

      Yeah, it's a typo.

      Thank you, it's fixed.

       
      fxsaber CopyRates method for matrices as well, in order to get correct data as easily.

      Here is the CopyRates method and an example in it

      //+------------------------------------------------------------------+
      //| Script programme start function|
      //+------------------------------------------------------------------+
      void OnStart()
       {
      //--- get quotes into the matrix
        matrix matrix_rates;
        if(matrix_rates.CopyRates(Symbol(), PERIOD_CURRENT, COPY_RATES_OHLCT, 1, 10))
          Print("matrix rates: \n", matrix_rates);
        else
          Print("matrix_rates.CopyRates failed. Error ", GetLastError());
      //--- check
        MqlRates mql_rates[];
        if(CopyRates(Symbol(), PERIOD_CURRENT, 1, 10, mql_rates)>0)
         {
          Print("mql_rates array:");
          ArrayPrint(mql_rates);
         }
        else
          Print("CopyRates(Symbol(), PERIOD_CURRENT,1, 10, mql_rates). Error ", GetLastError());
      //--- get quotes to vector = invalid call
        vector vector_rates;
        if(vector_rates.CopyRates(Symbol(), PERIOD_CURRENT, COPY_RATES_OHLC, 1, 15))
          Print("vector_rates COPY_RATES_OHLC: \n", vector_rates);
        else
          Print("vector_rates.CopyRates COPY_RATES_OHLC failed. Error ", GetLastError());
      //--- get the closing prices into a vector
        if(vector_rates.CopyRates(Symbol(), PERIOD_CURRENT, COPY_RATES_CLOSE, 1, 15))
          Print("vector_rates COPY_RATES_CLOSE: \n", vector_rates);
        else
          Print("vector_rates.CopyRates failed. Error ", GetLastError());
       };
      /*
       matrix rates:
       [[0.99686,0.99638,0.99588,0.99441,0.99464,0.99594,0.99698,0.99758,0.99581,0.9952800000000001]
       [0.99708,0.99643,0.99591,0.9955000000000001,0.99652,0.99795,0.99865,0.99764,0.99604,0.9957]
       [0.9961100000000001,0.99491,0.99426,0.99441,0.99448,0.99494,0.9964499999999999,0.99472,0.9936,0.9922]
       [0.99641,0.99588,0.99441,0.99464,0.99594,0.99697,0.99758,0.99581,0.9952800000000001,0.99259]
       [1662436800,1662440400,1662444000,1662447600,1662451200,1662454800,1662458400,1662462000,1662465600,1662469200]]
       mql_rates array:
       [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume]
       [0] 2022.09.06 04:00:00 0.99686 0.99708 0.99611 0.99641 44630 0
       [1] 2022.09.06 05:00:00 0.99638 0.99643 0.99491 0.99588 45190 0
       [2] 2022.09.06 06:00:00 0.99588 0.99591 0.99426 0.99441 30600 0
       [3] 2022.09.06 07:00:00 0.99441 0.99550 0.99441 0.99464 38670 0
       [4] 2022.09.06 08:00:00 0.99464 0.99652 0.99448 0.99594 52800 0
       [5] 2022.09.06 09:00:00 0.99594 0.99795 0.99494 0.99697 72270 0
       [6] 2022.09.06 10:00:00 0.99698 0.99865 0.99645 0.99758 101300 0
       [7] 2022.09.06 11:00:00 0.99758 0.99764 0.99472 0.99581 70120 0
       [8] 2022.09.06 12:00:00 0.99581 0.99604 0.99360 0.99528 61660 0
       [9] 2022.09.06 13:00:00 0.99528 0.99570 0.99220 0.99259 69500 0
       vector_rates.CopyRates COPY_RATES_OHLC failed. Error 4003
       vector_rates COPY_RATES_CLOSE:
       [0.9931,0.99293,0.99417,0.99504,0.9968399999999999,0.99641,0.99588,0.99441,0.99464,0.99594,0.99697,0.99758,0.99581,0.9952800000000001,0.99259]
      */
      Документация по MQL5: Методы матриц и векторов / Инициализация / CopyRates
      Документация по MQL5: Методы матриц и векторов / Инициализация / CopyRates
      • www.mql5.com
      CopyRates - Инициализация - Методы матриц и векторов - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
       
      Rashid Umarov #:

      Here's the nails the CopyRates method and the example in it

      Apparently I didn't formulate the problem well. When filling the matrix to calculate symbol correlation, it can happen that EURUSD[5].BarTime does not match GBPUSD[5].BarTime. This is called multi-bar non-synchronisation. You have to devote quite a lot of time/effort to such data preparation before calculations. If it could be solved with one line, it would be great.

       

      The article states:

      Над матрицами и векторами можно поэлементно производить математические операции — сложение, вычитание, умножение и деление. Для этого оба объекта должны быть одного и того же типа и должны иметь одинаковые размеры. Каждый член матрицы/вектора оперирует с соответствующим элементом второй матрицы/вектора.

      I would like to clarify how this calculation is done, i.e. are the numbers brought to double and then the calculation and back conversion to the initial data type takes place, which would reduce the loss of precision (or am I wrong and there is no difference?), or immediately in the data type that is there? Obviously, different types save RAM, but if I calculate data in arrays, I bring the numbers to double for calculations, and then again, let's say, to float to preserve the accuracy of calculations. Should I make it optional how to perform operations on numbers?
       
      Fantastic explanation. Very helpful.
       

      The instruction contains the following

      void matrix.FromBuffer(const int rows, const int cols, const scalar array[], const int count=-1, const int offset=0)

      frombuffer

      Creates a matrix from a one-dimensional array


      but in fact it doesn't work. Is there another way to copy a one-dimensional array into a matrix?

       
      There is, read the article .