Library for Matrices and vectors in MQL5

Library for Matrices and vectors in MQL5

19 August 2022, 21:54
Omega J Msigwa
0
565

Introduction

Matrix is the foundation of complex trading algorithms as it helps you perform complex calculations effortlessly and without the need for too much computation power, It's no doubt that matrix has made possible many of the calculations in modern computers as we all know that bits of information are stored in array forms in our computer memory RAM.

There are hundreds if not thousands of matrix operations but I collected some of the most important operations for data scientists and machine learning enthusiasts, I coded all of them in one MQL5 library.

A good thing about the matrix operations is that they appear simple on the outside while on the inside they perform many computations which have been important to the foundation of complex machine learning models such as neural networks

The following are the necessary function of the library and how they work.

matrix

The library for matrices and vectors in MQL5

This post assumes you have a basic understanding of Linear Algebra.

Reading a CSV File To Matrix

It's undeniable that before you can build any model or perform any data analysis, you have to import your dataset and the most common type of file that is used to store a dataset is a CSV file, to read a csv file in MQL5 and store it in a Matrix run this line of code

   double Matrix[]; int rows, cols;
   
   CSVToMatrix(Matrix,rows,cols,"Apple Dataset.csv");
   MatrixPrint(Matrix,cols);

 Output in the logs,

FI      0       18:24:45.319    TestLibraryEA (#NQ100,H1)       Matrix
NN      0       18:24:45.319    TestLibraryEA (#NQ100,H1)       [ 
EL      0       18:24:45.319    TestLibraryEA (#NQ100,H1)         1.00000   1.00000   0.05000   2.62111   1.51234   0.31000  20.80000 157.64999
FL      0       18:24:45.319    TestLibraryEA (#NQ100,H1)         2.00000   1.00000   0.14000   2.15134   1.34945   0.31000  20.80000 174.61000
RM      0       18:24:45.319    TestLibraryEA (#NQ100,H1)         3.00000   1.00000   0.14000   2.28617   1.15921   0.31000  20.80000 165.11999
MM      0       18:24:45.319    TestLibraryEA (#NQ100,H1)         4.00000   1.00000   0.17000   2.20677   0.96751   0.36000  19.76000 174.78000
LN      0       18:24:45.319    TestLibraryEA (#NQ100,H1)         5.00000   1.00000   0.20000   2.00355   0.94014   0.36000  19.76000 177.57001
KN      0       18:24:45.319    TestLibraryEA (#NQ100,H1)         6.00000   1.00000   0.20000   1.12156   0.95020   0.36000  19.76000 165.30000
IN      0       18:24:45.319    TestLibraryEA (#NQ100,H1)         7.00000   1.00000   0.17000   1.34078   0.95775   0.44000  17.44000 149.80000
RO      0       18:24:45.319    TestLibraryEA (#NQ100,H1)         8.00000   1.00000   0.18000   1.15018   0.91710   0.44000  17.44000 141.50000
GO      0       18:24:45.319    TestLibraryEA (#NQ100,H1)         9.00000   1.00000   0.19000   1.11831   0.81439   0.44000  17.44000 151.83000
NN      0       18:24:45.319    TestLibraryEA (#NQ100,H1)        10.00000   1.00000   0.20000   1.16670   0.60272   0.54000  16.01000 145.86000
NQ      0       18:24:45.319    TestLibraryEA (#NQ100,H1)        11.00000   1.00000   0.20000   1.08454   0.67206   0.54000  16.01000 136.96001

Here is the difference

Ensure there are no strings in the csv file or date formatted values as they could be misinterpreted 

Printing the Matrix

This is a very useful function in the library, It is for the sake of printing matrices, The above matrix that was obtained from a csv file has been printed using this funtion, plug in the matrix and put the number of colums available on the inside and you are good to go

   MatrixPrint(Matrix,cols);

Checking if the Matrix is a Square one 

This is another useful feature, it lets you know if the matrix plugged in is a square one or not. why is this important?

To find the inverse of a matrix it has to be a square one so this function will let you make sure about that, It returns true if the matrix is a square one otherwise returns false

bool   IsMatrixSquare(double &Matrix[]);

for-example: Let's see if the above matrix is square

Print("Is this matrix a square ",IsMatrixSquare(Matrix));

output

DS      0       21:38:34.070    TestLibraryEA (#NQ100,H1)       Is this matrix a square false

Matrix Multiplication

This function lets you find the outcome matrix when the two matrices are multiplied.

   double A[3] = {3,4,2}, B[12] = {13,9,7,15, 8,7,4,6 ,6,4,0,3};
   mat.MatrixMultiply(A,B,AxB,3,3,rows,cols);
   mat.MatrixPrint(AxB,cols);

Make sure the number of columns in the first matrix matches the number of rows in the second matrix, This is number one law of multiplication of matrices

On the above code A is 1x3 matrix while B is 3x4 matrix the resulting matrix will be 1x4

Here is the output;

IO      0       21:49:55.480    TestLibraryEA (#NQ100,H1)       Matrix
QD      0       21:49:55.480    TestLibraryEA (#NQ100,H1)       [ 
RS      0       21:49:55.482    TestLibraryEA (#NQ100,H1)       83.00000 63.00000 37.00000 75.00000
KD      0       21:49:55.482    TestLibraryEA (#NQ100,H1)       ] 
MS      0       21:49:55.482    TestLibraryEA (#NQ100,H1)       rows = 1 cols = 4

Matrix Transpose & Matrix Un-transpose

When building neural network, or other machine learning models you'll often be required to transpose and Un-transpose your matrices, Transposing the matrix is changing the rows into columns and vice verse when un-transposing let's use the above matrix B

JR      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       Before transpose
EG      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       Matrix
ML      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       [ 
LK      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       13.00000  9.00000  7.00000 15.00000
MQ      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       8.00000 7.00000 4.00000 6.00000
OF      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       6.00000 4.00000 0.00000 3.00000
IQ      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       ] 
IF      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       rows = 3 cols = 4
EM      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       After transpose
KG      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       Matrix
CM      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       [ 
LI      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       13.00000  8.00000  6.00000
RS      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       9.00000 7.00000 4.00000
OH      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       7.00000 4.00000 0.00000
CS      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       15.00000  6.00000  3.00000
ED      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       ] 
ES      0       22:03:24.115    TestLibraryEA (#NQ100,H1)       rows = 4 cols = 3

Here is how to run the Transpose function

   double B[12] = {13,9,7,15, 8,7,4,6 ,6,4,0,3};
   
   Print("Before transpose");
   int columns = 4;
   MatrixPrint(B,columns);
   MatrixTranspose(B,columns);
   Print("After transpose");
   MatrixPrint(B,columns);

Let's see the its opposite

   Print("Before Untranspose");
   int to_columns = 3;
   MatrixPrint(B,to_columns);
   MatrixTranspose(B,to_columns);
   Print("After Untranspose");
   MatrixPrint(B,to_columns);

outputs,

NI      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       Before Untranspose
DO      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       Matrix
LE      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       [ 
CQ      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       13.00000  8.00000  6.00000
IK      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       9.00000 7.00000 4.00000
HP      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       7.00000 4.00000 0.00000
DJ      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       15.00000  6.00000  3.00000
FS      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       ] 
FH      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       rows = 4 cols = 3
OS      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       After Untranspose
LJ      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       Matrix
DO      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       [ 
EL      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       13.00000  9.00000  7.00000 15.00000
HR      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       8.00000 7.00000 4.00000 6.00000
RH      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       6.00000 4.00000 0.00000 3.00000
LL      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       ] 
LK      0       22:06:36.385    TestLibraryEA (#NQ100,H1)       rows = 3 cols = 4

Things are back to where they were.

Matrix Inverse

Finding the Inverse of a square matrix is relatively simple, using the function

    void   MatrixInverse(double &Matrix[]);

To find the inverse of a 2x2 matrix only 

Gauss Jordan Inverse

This is a powerful method for finding the inverse of larger matrices than 2x2 can be 4x4,5x5 or even 10x10

  void   Gauss_JordanInverse(double &Matrix[],int mat_order);
double squarematrix[9] = {3,5,23, 21,7,9, 0,2,11};
      
MatrixPrint(squarematrix,3); // before      
      
Gauss_JordanInverse(squarematrix,3);
MatrixPrint(squarematrix,3); // after

output

MF      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       Matrix
ES      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       [ 
CK      0       22:41:34.628    TestLibraryEA (#NQ100,H1)        3.00000  5.00000 23.00000
MR      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       21.00000  7.00000  9.00000
HE      0       22:41:34.628    TestLibraryEA (#NQ100,H1)        0.00000  2.00000 11.00000
GR      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       ] 
FI      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       rows = 3 cols = 3
RN      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       Inverse
MJ      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       Matrix
EO      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       [ 
PN      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       -4.91667  0.75000  9.66667
FE      0       22:41:34.628    TestLibraryEA (#NQ100,H1)        19.25000  -2.75000 -38.00000
CH      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       -3.50000  0.50000  7.00000
MN      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       ] 
PM      0       22:41:34.628    TestLibraryEA (#NQ100,H1)       rows = 3 cols = 3

Removing A column in the Matrix

Sometimes there might be unwanted column in the matrix that you want to remove 

 void   MatrixRemoveColumn(double &dataArr[],int column,int rows);

Removing the Entire row in the matrix

This is the same as removing the column but different approach

void   MatrixRemoveColumn(double &dataArr[],int column,int rows);


There are many other functions to explore in the Library I have on sale on the market linked here https://www.mql5.com/en/market/product/81533

The source code will be provided after the purchase for development and production use of your own trading systems,

Thanks for reading

Share it with friends: