Hi all,
I thought I'd share some of my code for anyone that wants to use it. I used to be a big IBD fan, but have tried to automate most of my approach over time using MATLAB and then later Amibroker.
One ranking I really find useful is IBD's Relative Strength. It ranks all stocks against each other using a score that is based on their short, medium and long term returns. After some forum research on the net, it seems like the score formula that best imitates this the sum of returns over 1qtr, 2 qtr, 3qtr and a full trading year. The 1qtr return has double the weight of the others. Then a percentile ranking using static vars is created from this giving the IBD-style 0-100 score you see in their stock checkups and charts.
I then store the percentile rankings for each stock in their own static variable for easy retrieval when running my screens.
This runs every night as it can take some time depending how far back you want to calculate the history for each stock.
Comments, criticism and improvements are more than welcome!
Code is below.
// Relative Strength ranking of stocks
// Choose markets to include in the universe (I only use NYSE Market and delisted databases for backtesting hence why they are commented out)
listNYSE = CategoryGetSymbols(categoryMarket, 1);
listNSDQ = CategoryGetSymbols(categoryMarket, 2);
listARCA = CategoryGetSymbols(categoryMarket, 3);
//listNMKT = CategoryGetSymbols(categoryMarket, 4);
//listDLST = CategoryGetSymbols(categoryMarket, 14);
// Create the full list of stocks to be ranked
List = listNYSE + "," + listNSDQ + "," + listARCA;// "," + listNMKT + "," + listDLST;
ListQty = StrCount(List, ",") + 1;
// Determine the quantity of stocks to rank
StaticVarSet("UniListTotal", ListQty, True);
// Clear the static vars from last run
StaticVarRemove( "RS_*" );
// Generate the raw RS score for every stock and store in a static var
for (n = 0; (Symbol = StrExtract(List, n)) != ""; n++)
{
SetForeign (Symbol);
// relative strength IBD style
ThreeMthRS = 0.4*(C/Ref(C,-63));
SixMthRS = 0.2*(C/Ref(C,-63*2));
NineMthRS = 0.2*(C/Ref(C,-63*3));
TwelveMthRS = 0.2*(C/Ref(C,-63*4));
RSraw = ThreeMthRS + SixMthRS + NineMthRS + TwelveMthRS;
RestorePriceArrays();
StaticVarSet("RSraw_" + Symbol, RSraw);
}
// rank the stocks using this extremely useful function!
StaticVarGenerateRanks("Rank", "RSraw_", 0, 1224);
// Convert the static var ranks generated into a percentile score.
for (n = 0; (Symbol = StrExtract(List, n)) != ""; n++)
{
Rank = StaticVarGet ("RankRSraw_" + Symbol);
RSpctile = 100 - 100*Rank/ListQty;
StaticVarSet("RS_" + Symbol, RSpctile, True);
// use this opportunity to store the highest ranking stocks in a watchlist.
if (LastValue(RSpctile) >= 95)
CategoryAddSymbol( Symbol, categoryWatchlist, 1132);
else
CategoryRemoveSymbol(Symbol, categoryWatchlist, 1132);
}
// remove unnecessary static data
// free up old stuff
StaticVarRemove("RSraw_*");
StaticVarRemove("RankRSraw*_");