Working with matrix MTXsetblock

Hi everybody,
I want to do the following:

  1. For each bar create Matrix A (3rows X 1 Column) and fill that matrix with the close of the current bar and the close of the two previous bars.
    This way the bar of today (bar count N) will have a matrix with the close of bar n and the close of n-1 and the Close of n-2.
    Bar of yesterday (Barcount n-1) has the close Barcount n-1, n-2 y n-3.

  2. Multiply each element of Matrix A by the current value of the RSI(5).
    In order to do so
    Step 2a) I create Matrix C (1 row1colum) where I store the Value of RSI(5) of the current bar
    Stept 2b) I multiply MATRIX A @ MATRIX B
    This way I will get a Matrix C which will have also 3 rows and 1 column and each element of the matrix C will be:
    First element in row1= Close today
    RSI(5) today
    Second element (Row2): Close yesterdayRSI(5)today
    Third element (row 3); close two days ago
    RSI(5)today .

  3. Now I want to calculate the result of MATRIX C minus REF(MATRIX C,-1).

  4. Convert the MatrixA to a String and then from string to Number with the idea of applying AFL formulas to such list of number.
    For instance if the list of number is List= (25,17,32,47,55)
    To use the following formula diff=c-Ref(c,-1); where c is the values within the list.

Below is the Code I Wrote.

//STEP 1

MATRIXA = Matrix( 3, 1, 0 );// Create a Matrix of 10 rows and 1 Column

MATRIXA = MxSetBlock( MATRIXA, 0, 2, 0, 0, Close );// I fill the matrix with the close array

MatrixAString=MxToString(MATRIXA);// I will display this variable in the exploration to see it it does what I want.


//STEP 2
MATRIXB = Matrix( 1, 1, 0 );// Create a Matrix of 1 rows and 1 Column

MATRIXB = MxSetBlock( MATRIXA, 0, 0, 0, 0, RSI(5));// I fill the matrix with the RSI(5) array. Also Tried with  LastValue(RSI(5)

MatrixBString=MxToString(MATRIXB);// I will display this variable in the exploration to see it it does what I want.

// step 2b 
MATRIXC=MATRIXA * LastValue(RSI(5) );// Should not be the same that  line 24 below?? 
MatrixCString=MxToString(MATRIXC);// I will display this variable in the exploration to see it it does what I want.

//Or I understand that should be able to be done this way too
//MATRIXC=MATRIXA @ MAtrixB;//  Amibroker does not let me because It says that the number of columns in matrixA should be equal to number of rows Matrix B
// wich I do not understand because MAtrix B is a MAtrix of 1*1.



//Step 3
//I want to Calculate the result of Matrix C Minus Ref (MAtrixC,-1);

// Step 4 Convert MatrixA to list of number with the intend to apply AFL formulas over that list of numbers. 

STringlistaA=StrToNum(MatrixAString);// I will dispay in the exploration to see how it works.




Filter=1;
AddColumn( C, "    c   ", 1.2); 
AddColumn(RSI(5),"rsi5",1.2);



AddTextColumn(MatrixAString,"MatrixAString",1.2);
AddTextColumn(MatrixbString,"MatrixBString",1.2);
AddTextColumn(MatrixCString,"MatrixcString",1.2);
AddColumn(STringlistaA,"STringlistaA",1.2);

And Also a picture of the Exploration Output

Image of Exploration

Now let’s review step by step comparing what I get vs what I expected

Step1)

Stetp1 REsultado

I see that the elements of the matrix are the first 3 values of the Array Close and are kept the same in the matrix of every bar.

Step 1 Expected

Step2a)

2a resultado

I do not understand why shows a Matrix of three rows when I actually define the matrix B as 1X1. I do not understand either why it does not include the RSI Value of the bar.
I also tried with last Value ( RSI(5); but it did not work either. Next What I expected to get.

2a expected

Step2b)
2b Resultado

I do not know what is calculating. Anyway, the elements of the matrix do not change as I expected.

Below what I expected to get:
2b expected

Step 3) No idea how to do it. I do not know if I can use Ref to substract on matrix from the other.

Step4)

I do not know why the formula StrToNum does not work, it could be because the string that comes out from the matrix is a wolfram type. But then, how I convert it to a list of numbers and being able to apply formulas over such list of numbers.

I know that you can access the elements of the array one by one the following way:

To access matrix elements, use:

my_var_name[ row ][ col ];

where

row is a row index (0... number of rows-1)

and

col is a column index (0... number of columns-1)

The issue is that if the Matrix have a few elements like in my example it is easy but If I have 90 elements seems very cumbersome.

I read the manual for matrix and performed searches but I do not see how to implement it.

I would appreciate any help. Thanks a lot in advance.

@Eddie, there is a wrong assignment in the line:

MATRIXB = MxSetBlock( MATRIXA, 0, 0, 0, 0, RSI(5));

Should be:

MATRIXB = MxSetBlock( MATRIXB, 0, 0, 0, 0, RSI(5));

I truly do not understand the purpose of the calculations and why you are setting the matrices dimensions in such a way to hold only few values.

Looking at what you want to achieve, I think that the matrices columns (or rows) should be eventually dimensioned as per the Barcount.

For this reason, I think you can get rid of all the matrices and directly use the arrays to perform your steps (and optionally use the result of the last math operation for fill a new matrix and do something else with it).

// Step 1
A0 = Close;
A1 = Ref(Close, -1);
A2 = Ref(Close, -2);

// Step 2
RS = RSI(5);

// Step 3
A0_RS = A0 * RS;
A1_RS = A1 * RS;
A2_RS = A2 * RS;

// Step 4 (??)
A0_RS_1 = A0_RS - Ref(A0_RS, -1);
A1_RS_1 = A1_RS - Ref(A1_RS, -1);
A2_RS_1 = A2_RS - Ref(A2_RS, -1);

// Optionally, if needed fill a Matrix, etc.
m = Matrix(3, BarCount, 0);
m = MxSetBlock(m, 0, 0, 0, BarCount-1, A0_RS_1);
m = MxSetBlock(m, 1, 1, 0, BarCount-1, A1_RS_1);
m = MxSetBlock(m, 2, 2, 0, BarCount-1, A2_RS_1);

// Apply exploration to all bars
Filter = 1;
AddColumn(A0, "Close");
AddColumn(A1, "Ref(Close, -1)");
AddColumn(A2, "Ref(Close, -2)");
AddColumn(RS, "RSI(5)", 1.4);
AddColumn(A0_RS, "Close * RSI ");
AddColumn(A1_RS, "Ref(Close, -1) * RSI");
AddColumn(A2_RS, "Ref(Close, -2) * RSI");
AddColumn(A0_RS_1, "A0_RS - Ref(A0_RS, -1)");
AddColumn(A1_RS_1, "A1_RS - Ref(A1_RS, -1)");
AddColumn(A2_RS_1, "A2_RS - Ref(A2_RS, -1)");
SetSortColumns(-2); 

I'm not sure if the above steps are exactly what you wanted, but I hope you can grasp the concept.

1 Like

Thanks a lot for your answer Beppe.

In my example I used a Matrix holding few values because the purpose is to learn:

  1. How to fill the matrix
  2. To operate with them.
  3. To convert the matrix to string and from wolfram string to number.
    In the example I tried to perform the operations I will need to perform in other systems.
    It is easy to learn to do it with few values (3 rows) instead of using large Matrix, but in my systems I will have matrix with 60, 90 columns and/or rows.

As a matter of fact, the number of rows or column will be also a variable to optimize.
Because the matrix I will use in backtest will have many columns and rows, it is very cumbersome to have to define each one of the element of the matrix one by one. In addition, as the number of columns and rows will be optimized, I do not know beforehand how many elements I will have to define.
Going to you answer, when you say that the matrices columns (or rows) should be eventually dimensioned as per the Barcount. How do you do that?
In order to understand what your code is doing filling the matrix I simplified the code and I used it like this:
Image Code
I made the matrix 1row dimension and I added the line of code to convert the Matrix to a string in order to see with the explorer what was being placed within the matrix.
As you can see in the image, the for each day you have exactly the same matrix and It seems that for each date the matrix has the exact same number of elements and I do not know why that number of elements. I was expecting, maybe erroneously, that the day 02/01/2019 will have one element more than the matrix of the 01/01/2019 which is not the case. Probably it is that I do not understand well.
Image of Exploration2
I tried to define Barcount= number of columns and does not let me and give me this message.
“Error 55. Invalid assignment. The identifier is read-only (constant) and cannot be written to.”
What am I doing wrong???
After devoting a lot of time thinking about all this, I believe it is best If I go back to basic.
This is what I need to do.
This is what I need

Can you please help me . I do not know how to get there. Maybe it just cannot be done.

Thanks a lot beppe.

You can not assign value to predefined read only variables.
Barcount is one of them. It can be used right of assignment operator.


/// https://forum.amibroker.com/t/working-with-matrix-mtxsetblock/32575/4
array = DateTime();
period = 10;

m = Matrix( BarCount, period ); 
rownum = MxGetSize( m, 0 );
colnum = MxGetSize( m, 1 );

for( i = period; i < rownum; i++ ) {	
	for( j = 0; j < colnum; j++ ) {
		m[i][j] = array[i-j];
	}	
}

Filter = BarIndex() > colnum-1;

for( j = 0; j < colnum; j++ ) {
	m_array = MxGetBlock(m, 0, BarCount-1, j, j, True);
	AddColumn(m_array, "array -"+j, formatDateTime, -1,-1, 100);
}

34

1 Like

Or just using

/// https://forum.amibroker.com/t/working-with-matrix-mtxsetblock/32575/4
array = DateTime();
period = 10;

m = Matrix( BarCount, period ); 
rownum = MxGetSize( m, 0 );
colnum = MxGetSize( m, 1 );

for( j = 0; j < colnum; j++ ) {
	m = MxSetBlock(m, 0, BarCount-1, j, j, Ref(array, -j));
}	

Filter = BarIndex() > colnum-1;

for( j = 0; j < colnum; j++ ) {
	m_array = MxGetBlock(m, 0, BarCount-1, j, j, True);
	AddColumn(m_array, "array -"+j, formatDateTime, -1,-1, 100);
}
1 Like

Thanks a lot Fxshrat. It is really helpfull.

Best

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.