Question regarding sorting arrays

Hi,

Kind of looking for direction, please point to some article or ideas..

I am currently working on a dashboard. I have several arrays coded like PIVOTS, GANN values and FIBOS, All these values I am displaying in a Grid, all fine till now.. These are all price values basically. I want to sort these values in a descending order and display in a table accordingly. So which ever value is the highest will be rendered in a table. First of all will this be possible ? Is this the use case for using matrix ? Can you point to some resource or article ?

Any help would be greatly appreciated. I am stuck.

forum%20screenshot

Thanks,
Vinay

First, you have to sort before displaying.
You can't draw and than expect it to be sorted.

https://www.amibroker.com/guide/afl/sort.html

If you already have an Array, directly use the built-in Sort Function.

If values are not in one Array, copy all the values required to a new Array, then sort it and use it for display purposes.

I didn't quite understand what you want to sort, can you elaborate it with a real example from your pic.
Mark the groups if you want to sort multiple arrays.

I still don't see where the Matrix comes into the picture.

1 Like

@vinaykumar it is likely that you can use a combination of a matrix and a list of strings (used to sort captions) as in the example posted here:


Working with matrices - Ranking

4 Likes

Hi travick, thanks for your reply. Yes I know that we have to first sort and then draw.

From the above screenshot for example consider first 5 values (BUY ABOVE, WATCH UP 1, WATCH UP 2, T1 UP, T2 UP). The values of those columns should be sorted in descending order which means first T2 UP then T1 UP should be rendered and so on... Yes all these are in different arrays.

That will depend on how your code is, so you'll have to post it here.

I can see its already showing in ascending order from whatever arrays you are reading, can't you plot the arrays in reverse order ?
Anyway, post the code else its just guess work.

1 Like

Hi,

Firstly I would like to thank @beppe and @travick for your valuable inputs, It all helped.
Finally I was able to crack sorting using matrix. Below is the code for doing so, this is how I implemented.

	//********************************** SORTING **************************8
	 // I can add any number of arrays comma separated here
	columnnames = "Open,Close";
	MatrixRows = 1 + StrCount(columnnames, ",");
	MatrixColumns = BarCount + 1;
	bi = BarIndex();
	selectedColIndex = SelectedValue( bi ) - bi[ 0 ]; 

	z = Matrix( MatrixRows, MatrixColumns, 0 ); 
	for(row=0;row < MatrixRows; row++) {
		//Assign the arrays to each row..
		z = MxSetBlock( z, row, row, 0, MatrixColumns - 2, VarGet(StrExtract(columnnames, row)) );
		// this last column is used to store counter like a unique row Id, 
		//so if sorted i can reach out to correct column when displaying
		z[row][MatrixColumns - 1] = row;
	}
	//finally do a descending order sort
	z = mxSortRows( z, False, selectedColIndex );
	//************************************** END SORTING ****************************88
	for(row = 0; row < MatrixRows; row++) {
		printf(StrExtract(columnnames, z[row][MatrixColumns - 1]) + ":" + z[row][selectedColIndex]);
		printf("\n");
	}

Thanks again,
Vinay

2 Likes

Hi

Just a glance at the code, will test it later but this line in all contexts will overflow.
It is bound to throw exceptions.

You may subtract 2 in other parts of the code but its still not a good practice

No, it won't throw exception. It is matrix but not 1-dim (symbol) array. Please get your facts straight before writing. 2-dim AB arrays can exceed BarCount!

He stores Open, Close arrays from 1st to second to last index of column vector(s) and stores row index to last column. That's why he set size of columns to BarCount+1.

One thing he should do is this though (in case MatrixColumns becomes lower than 2)

z = MxSetBlock( z, row, row, 0, Max(0, MatrixColumns-2), VarGet(StrExtract(columnnames, row)) );
//********************************** SORTING ***************************
 // I can add any number of array comma separated here
columnnames = "Open,Close";
MatrixRows = StrCount(columnnames, ",")+1;
MatrixColumns = BarCount + 1;
bi = BarIndex();
selectedColIndex = SelectedValue( bi ) /*- bi[ 0 ]*/; 

z = Matrix( MatrixRows, MatrixColumns, 0 ); 
rownum = MxGetSize(z, 0);
colnum = MxGetSize(z, 1);
last_element = Max(0, colnum-2);// last idx of 1-dim array
last_column = colnum-1;
for (row=0;row < rownum; row++) {
	//Assign the arrays to each row..
	z = MxSetBlock( z, row, row, 0, last_element, VarGet(StrExtract(columnnames, row)) );
	// this last column is used to store counter like a unique row Id, 
	//so if sorted i can reach out to correct column when displaying
	z[row][last_column] = row;
}

"\nBefore sorting";
MxToString(z);

//finally do a descending order sort
z = mxSortRows( z, False, selectedColIndex );

"After sorting";
MxToString(z);

//************************************** END SORTING ****************************
for (row = 0; row < rownum; row++) {
	printf( "%s:%g\n", StrExtract(columnnames, z[row][last_column]), z[row][selectedColIndex]);
}

The following may be alternative... defining minimum matrix size of min. one row and min. two columns:

z = Matrix(Max(1, MatrixRows), Max(min_col_size=2, MatrixColumns), 0); 
rownum = MxGetSize(z, 0);
colnum = MxGetSize(z, 1);
last_column = colnum-1;
last_bi = colnum-min_col_size;// last idx of 1-dim array

And if you want to store the actual visible chart then you may do like so (instead of using BarCount -> See QuickAFL -> Extra safety bars added -> initial BackwardRef set to 30).

bi = BarIndex();
fvb = FirstVisibleValue(bi);
lvb = LastVisibleValue(bi);
barnum = lvb-fvb+1;
selectedColIndex = SelectedValue(bi) - fvb;

So,

/// @link https://forum.amibroker.com/t/question-regarding-sorting-arrays/10235/6
/// @link https://forum.amibroker.com/t/question-regarding-sorting-arrays/10235/9
//********************************** SORTING ***************************
 // I can add any number of array comma separated here
columnnames = "Open,Close";

bi = BarIndex();
fvb = FirstVisibleValue(bi);
lvb = LastVisibleValue(bi);
barnum = lvb-fvb+1;
selectedColIndex = SelectedValue(bi) - fvb;

printf("visible barnum: %g, BarCount: %g\n", barnum, BarCount);

MatrixRows = StrCount(columnnames, ",")+1;
MatrixColumns = barnum + 1;// 1 extra column for storing row idx

z = Matrix(Max(1, MatrixRows), Max(2, MatrixColumns), 0);
 
rownum = MxGetSize(z, 0);
colnum = MxGetSize(z, 1);

last_column = colnum-1;
last_bi = last_column-1;// last idx of 1-dim array

for (row=0;row < rownum; row++) {
	//Assign the arrays to each row..
	arr = VarGet(StrExtract(columnnames, row));
	z = MxSetBlock(z, row, row, 0, last_bi, arr);
	// this last column is used to store counter like a unique row Id, 
	//so if sorted i can reach out to correct column when displaying
	z[row][last_column] = row;
}

"\nBefore sorting";
MxToString(z);

//finally do a descending order sort
z = mxSortRows( z, False, selectedColIndex );

"After sorting";
MxToString(z);

//************************************** END SORTING ****************************
for (row = 0; row < rownum; row++) {
	printf( "%s:%g (column:%g)\n", StrExtract(columnnames, z[row][last_column]), z[row][selectedColIndex], selectedColIndex+1);
}

600

1 Like

Hi @fxshrat, thanks for your valuable input, I will incorporate your ideas.

Problem I am facing now is Amibroker 6.0 won't support MXSETBLOCK and MXSORTROWS functions, its giving undefined error. How to overcome this issue ? Upgrading amibroker to Higher version is the only solution to this problem ? I can recreate MXSETBLOCK and creating MXSORTROWS is bit complicated and may not be efficient.

In the documentation it says that this function is supported from AFL 4.10. I was confused that AFL 4.10 is the amibroker version. It seems like its AFL version. How to see version of AFL is supported by particular amibroker installation ?

MxSetBlock - sets values in the rectangular block of matrix cells (AFL 4.10)

Thanks,
Vinay

You have used MxSetBlock and MxSortRows yourself above. So I am surprised that you are surprised now.

Yes, you would have to upgrade AmiBroker to make the code to work since those functions have been implemented after AB 6.0. They have been implemented during development cycle of AB 6.01 to 6.10.

AFL version always is AB final release version minus two. So AB 6.10 minus two is AFL 4.10.

2 Likes

Guessed it. thanks for the confirmation related to AFL versioning.

In a hindsight I can tell that numbering AFL that way was a mistake. I will probably remove separate AFL versioning.

3 Likes