Ordering Variables By Quantity?

 
I've got 64 total variables that I would like to order from highest to lowest by their numeric value. Is there a way to accomplish this?
 
Calpurnia:
I've got 64 total variables that I would like to order from highest to lowest by their numeric value. Is there a way to accomplish this?

Depends whether you just need the values in order, or whether you also need to know that the largest item is e.g. #33 of 64. If the former, you can probably just put them in an array and use ArraySort(). If the latter, then you're probably going to have to use a bespoke sort function which sorts both the values and a list of indices.

 

If you need index correlation you can still use the ArraySort() operator by creating an array with two columns and 64 rows. Put the index ID number in the second column. When the array is sorted it (it sorts the first column by default) will move the ID number with the sorted value in the first column.


The documentation associated with ArraySort() says that it sorts by the "first" dimension, but I have found that in a two dimensional array, it does not sort by the first row (which if I understand their definition of "first dimension"); instead, it sorts by the first "element" in each row, or stated differently and as I stated in the first paragraph, it sorts by the first column.

 
FXtrader2008:

If you need index correlation you can still use the ArraySort() operator by [...]

Good point. It never occurred to me that this might work - I can't immediately think of another language which has multidimensional arrays and allows simple numeric sorting of them. You learn something new every day...

 

I understand the array sort feature...I'm just not sure how to get the values into the array since they are pulled from global variables?

Here's abit of my code:

double JPYUSDr = ((JPYs-USDs)/60);
double JPYEURr = ((JPYs-EURs)/60);
double JPYGBPr = ((JPYs-GBPs)/60);
double JPYCHFr = ((JPYs-CHFs)/60);
double JPYCADr = ((JPYs-CADs)/60);
double JPYAUDr = ((JPYs-AUDs)/60);
double JPYNZDr = ((JPYs-NZDs)/60);

How would I assign the values of JPYUSDr through JPYNZDr into an array? Once I get the values into an array, I think I can handle it from there. Thanks for all the help so far!

 
Calpurnia:

I understand the array sort feature...I'm just not sure how to get the values into the array since they are pulled from global variables?

Here's abit of my code:

double JPYUSDr = ((JPYs-USDs)/60);
double JPYEURr = ((JPYs-EURs)/60);
double JPYGBPr = ((JPYs-GBPs)/60);
double JPYCHFr = ((JPYs-CHFs)/60);
double JPYCADr = ((JPYs-CADs)/60);
double JPYAUDr = ((JPYs-AUDs)/60);
double JPYNZDr = ((JPYs-NZDs)/60);

How would I assign the values of JPYUSDr through JPYNZDr into an array? Once I get the values into an array, I think I can handle it from there. Thanks for all the help so far!

If you declare a single dimension array with 62 elements, the code would look like this:


YourArray[0]=((JPYs-USDs)/60);
YourArray[1]=((JPYs-EURs)/60);

YourArray[2]= etc

.

.

.

YourArray[61]=etc


ArraySort(YourArray, WHOLE_ARRAY, 0, MODE_DESCEND );

or

ArraySort(YourArray, WHOLE_ARRAY, 0, MODE_ASCEND );


If you declare a two dimensional array containing 62 rows with two elements in each row (ie the value you want to sort placed in the first element of the row, and index value in the second element of the row.


YourArray[0,0]=((JPYs-USDs)/60);

YourArray[1,0]=((JPYs-EURs)/60);

etc

etc

then place the index numbers in the following array elements


YourArray[0,1]=1

YourArray[1,1]=2

YourArray[2,1]=3

etc

etc


 
FXtrader2008:

If you declare a single dimension array with 62 elements, the code would look like this:

YourArray[0]=((JPYs-USDs)/60);
YourArray[1]=((JPYs-EURs)/60);

YourArray[2]= etc

My turn to propose a minor amendment. It looks like there are eight underlying values, and what's being analysed is the 64 combinations of them (albeit 8 of the 64 comparisons will be zero because JPYs - JPYs = 0 etc). This leads to two things. Firstly, if you only need to know the single biggest difference-value, then you only need to sort the 8 values, not all 64. The biggest difference is then obviously the largest of the eight values minus the smallest of the eight.


Secondly, if you do want the full list then there's a more elegant way of populating the array to be sorted, without using 64 separate lines of code. This kind of route also caters pretty easily for the addition of further currencies (or removal of them), or even a change to the formula so that the values for a pair of currencies ares multiplied rather than subtracted etc:


// List of "index" values for each currency. Add an index for a new currency at

// the bottom of this block, and increase IDX_COUNT

#define IDX_JPY   0

#define IDX_USD   1

#define IDX_EUR   2

#define IDX_GBP   3

#define IDX_CHF   4

#define IDX_CAD   5

#define IDX_AUD   6

#define IDX_NZD   7

#define IDX_COUNT 8



int start()

{

   // Define an array to hold each individual currency value such as JPYs

   double Vals[];

   ArrayResize(Vals, IDX_COUNT);


   // Store whatever the values are here. New currencies need to be added

   // at the bottom of this block

   Vals[IDX_JPY] = JPYs;   

   Vals[IDX_USD] = USDs;   

   Vals[IDX_EUR] = EURs;   

   Vals[IDX_GBP] = GBPs;   

   Vals[IDX_CHF] = CHFs;   

   Vals[IDX_CAD] = CADs;   

   Vals[IDX_AUD] = AUDs;   

   Vals[IDX_NZD] = NZDs;   

   

   // Create an array of differences between each currency value

   // Note that this array will contain IDX_COUNT meaningless values

   // such as JPYs - JPYs and EURs - EURs. You may need to bear this

   // in mind depending on how the array is later used.

   double Diffs[][2];

   ArrayResize(Diffs, IDX_COUNT * IDX_COUNT);

   

   // Populate the array of differences between each currency

   for (int i = 0; i < IDX_COUNT; i++) {

      for (int j = 0; j < IDX_COUNT; j++) {

         int idx = (i * IDX_COUNT) + j;

         Diffs[idx][0] = (Vals[i] - Vals[j]) / 60;

         Diffs[idx][1] = idx;

      }

   }


   // Sort the array in descending order 

   ArraySort(Diffs, WHOLE_ARRAY, 0, MODE_DESCEND);


   // Largest item such as JPYs - USDs is in Diffs[0][0].

   // The index of any item, in Diffs[n][1], can be converted to

   // a pair of currencies as follows.

   int iPair1 = MathFloor(Diffs[0][1] / IDX_COUNT);   

   int iPair2 = MathMod(Diffs[0][1],  IDX_COUNT);   

}


For example, with the following random data...


double JPYs = 23;

double USDs = 42;

double EURs = 1;

double GBPs = 18;

double CHFs = 102;

double CADs = 60;

double AUDs = 95;

double NZDs = 88;


...then the iPair1 and iPair2 calculated by the above code will be 4 and 2 respectively: i.e. IDX_CHF minus IDX_EUR. The iPair1 and iPair2 values from Diffs[63][1] will be the other way round: IDX_EUR and IDX_CHF.


Depending on how you use the array of differences, you may need to bear in mind and watch out for the 8 "dummy" values such as USDs - USDs.


 
Excellent advice all round. Thanks for the help chaps! I appreciate it!
Reason: