Passing an Array to StaticVarGenerateRanks


#1

I am having a vexing problem in trying to utilize an array created outside of a for loop and using it to populate a static variable which will serve as the input to perform a ranking with the StaticVarGenerateRanks function. When using the code below, the Exploration ranking column doesn’t show the anticipated result.

//===== Detect Watchlist ==============
wlnumber=GetOption("FilterIncludeWatchlist");
watchlist=GetCategorySymbols(categoryWatchlist,wlnumber);
//============= Symbol Ranking Using Array ==============
ValueArray=ROC(C,89);
riA=StaticVarSet("riA",ValueArray);
StaticVarGenerateRanks("Rank","riA",0,1224);
//================ Get Static Variables =================
RankriA=StaticVarGet("RankriA");
//============ Specify Columns for Exploration ============
Filter = 1;
if ( Status( "actionex" ) == actionExplore ) 
{
SetOption("NoDefaultColumns",True);
SetSortColumns(-4);
AddTextColumn(Name(),"Symbol",1.0,colorDefault,colorDefault,55);
AddColumn(DateTime(),"Date ",formatDateTime,colorDefault,colorDefault,75);
AddTextColumn("","X",1.0,colorDefault,colorDefault,3);
AddColumn(riA,"(riA)  ",1.4,colorDefault,colorDefault,60);
AddColumn(RankRiA," ",1.0,colorDefault,colorDefault,25);
}

I have read the manual and am aware that if I put the ValueArray inside a loop and use a static variable as input for StaticVarGenerateRanks I can get a proper ranking in the Exploration column, but there is a reason why I want to achieve this in an alternative way directly from the ValueArray. I do not understand why StaticVarGenerateRanks is not receiving the necessary information to create a ranking.

Thanks to anyone who might have some suggestions as to what I am missing/doing wrong.

Russell


#2

I think you may be confused as to the purpose of StaticVarGenerateRanks, which is to generate ordinal rank numbers for a series of existing static variables (not just one). This often means static variables that share the same array calculation and that are calculated for different symbols. There’s nothing for it to do when used with a single static variable as an input.

It’s not super clear what you’re after instead, but if you’re just after an ordinal rank number for an array in an Explore, you can use AddRankColumn. Alternatively if you want to sort the values in the array, try Sort.


#3

Thanks Alan for your helpful reply. What I was looking for was to have the functionality of “AddRankColumm” along with the flexibility to customize the heading text and column width like what is available with just “AddColumn”. Your suggestion of using “Sort” seemed like a great option but after numerous trial and error attempts, I have been unable to achieve an ordinal ranking [1,2,3,4,5…] of another column using this function. It seems that what I want falls into the “no can do” category.


#4

Alan,
Am re-posting my response below as the original formatting was awful.

Thanks Alan for your helpful reply. What I was looking for was to have the functionality of AddRankColumm along with the flexibility to customize the heading text and column width like what is available with just AddColumn. Your suggestion of using Sort seemed like a great option but after numerous trial and error attempts, I have been unable to achieve an ordinal ranking [1,2,3,4,5…] of another column using this function. It seems that what I want falls into the “no can do” category.


#5

… highly unlikely :wink:


Have you tried multiple-column sort? A quote from:
http://amibroker.com/guide/afl/setsortcolumns.html

Upto 10 columns can be specified for multiple-column sort. Multiple SetSortColumns make sense if you want to add multiple rankings by different columns via AddRankColumn.

// sort by 1st column in ascending order AND then by Second column in descending order (multiple-column sort).
SetSortColumns( 1, -2 ); 

Besides, apart from SetSortColumns() and AddRankColumn() you can also make use of AddSummaryRows() : http://amibroker.com/guide/afl/addsummaryrows.html

You can even create additional column (it might be even invisible) just for sorting purposes.


#6

Milosz,

Thank you for your response, but I don’t think your suggestions enable me to set up a sort column in my preferred way like this:
2017-09-10_21-31-17
The code used to produce the information for the Rank column came straight from the StaticVarGenerateRanks reference in the manual and since AddColumn was used to display it, I could customize both the text for the heading and the column width. If the Score calculation is done strictly with arrays without using a loop then yes, AddRankColumn will show the identical ranking information but without any options available to tailor the output to suit my personal preference. As far as I can tell, AddSummaryRows doesn’t help in my quest either. :frowning:

Russell


#7

Russel, you should rather avoid using StaticVarGenerateRanks() in Exploration for a couple of reasons. In general it was not meant to be used that way. One of the reason is that it should be called only once (in case of exploration/scan - when the last symbol is being processed). Identyfing the last symbol is possible, but requires a not standard approach. This topic has already been discussed on this forum. There’s no straightforward way of identyfing it similar to the first symbol. If you really need to, you can find some solutions in this thread:

Your code:

… is wrong. Some main mistakes:

  1. You call StaticVarGenerateRanks() for each symbol and additionally it generates ranking from just one symbol - which makes no sense. If your watchlist contains 1000 symbols, you call it 999 times more than you should. As the exploration progresses, you should store all the necessary information in static variables and call StaticVarGenerateRanks() only once, to generate ranking from all those static variables.

  2. You overwrite your static variable with each processed symbol - as a result after processing all symbols, your static variable stores only the last symbol’s data.

  3. Instead of creating just one static variable (your case) you should create a set of static variables this way:

StaticVarSet( "ValuesToSort" + sym, Value );

… this way you will create as many static variables as there are in a selected watchlist(s)

Take a closer look at the examples in AB documentations:
https://www.amibroker.com/guide/afl/staticvargenerateranks.html

You can also take a look at my example of using StaticVarGenerateRanks() in Exploration, but as I said, genarally it should be rather avoided :

In case of exploration use SetSortColumns() , AddRankColumn() and AddSummaryRows() instead of StaticVarGenerateRanks() whenever possible.


#8

Milosz,

Thank you again for responding; your willingness to share is awesome. The references you pointed to are quite relevant and indicate to me that I have some homework to do. I must admit that with my lack of a programming background, I was not fully comprehending how static variables operate or the effect of calling functions like StaticVarGenerateRanks has on the internal workings of AFL. Your help is much appreciated and with a little more thought should allow me to overcome some of the roadblocks to writing better and more efficient code.

Russell