Double ranking

First of all, I would like to express my gratitude to @Peppe, @RocketPower, @Tomasz, and a few other Amibroker experts. I would like to repost the exercise I learned from you all for the purpose of studying, which involves ranking by total value and then further sorting by IBD. I kindly ask for your help in reviewing and correcting my exercise so that I can improve my learning.
I sincerely appreciate your support.
My code is below :

#pragma sequence(scan,explore)

InputWatchlistNum = GetOption( "FilterIncludeWatchlist" ); 
list = CategoryGetSymbols( categoryWatchlist, InputWatchlistNum ); 
ListQty = StrCount(list, ",") + 1; 

if (Status("action") == actionScan)
{
	
	if( Status( "stocknum" ) == 0 )
	{
		StaticVarRemove( "rank*" );
		StaticVarRemove( "value*" );
		StaticVarRemove( "r*" );

		for( n = 0; ( symbol = StrExtract( List, n ) ) != "";  n++ ) {
			SetForeign( symbol );
			value = C * MA(Ref(V,-1),20) ;
			RestorePriceArrays();
			StaticVarSet( "value" + symbol, value );    // write ranked values to a static variable
		}	
    
    StaticVarGenerateRanks( "rank", "value", 0, 1224 ); 
    }
	
	
	
	if( Status( "stocknum" ) == 0 )
	{
		StaticVarRemove( "RS_*" );
		StaticVarRemove("RSraw_*");
		StaticVarRemove("RankRSraw*_"); 
		for( n = 0; ( symbol = StrExtract( List, n ) ) != "";  n++ )
		{
			SetForeign (Symbol,0); 
			RSraw = 0;		
			// relative strength IBD style
			ThreeMthRS  = 0.4*(C/Ref(C,-5));
			SixMthRS    = 0.2*(C/Ref(C,-(2*5)));
			NineMthRS   = 0.2*(C/Ref(C,-(3*5)));
			TwelveMthRS = 0.2*(C/Ref(C,-(4*5)));
			RSraw = ThreeMthRS + SixMthRS + NineMthRS + TwelveMthRS; 
			RestorePriceArrays(); 
			StaticVarSet("RSraw_"  +  Symbol, RSraw,True); 
			RSraw  = StaticVarGet ("RSraw_" + Name()); 				
		}	
		StaticVarGenerateRanks("Rank", "RSraw_", 0, 1224); 
		
		if( Status( "stocknum" ) == 0 )
		for (n = 0; (Symbol = StrExtract(list, n))  != "";  n++) 
		{
			Rank  = StaticVarGet ("RankRSraw_" +  Symbol);
			rankvalue = StaticVarGet("rankvalue"+symbol); 
			RSpctile = IIf(rankvalue <=500, 100 - 100*Rank/ListQty,-10000);	
			StaticVarSet("RS_" + Symbol, RSpctile, True);
		}
	}			

_exit(); // Exit nothing to do
}

symbol = Name();
RankC  = StaticVarGet ("RS_" +  Name()); 


_SECTION_BEGIN( "VIX" );
Period = Param("Period (days)", 30, 10, 100, 1); 
AnnualFactor = sqrt(252); 

Price = Close; 
Returns = log(Price / Ref(Price, -1)); 
Volatility = StDev(Returns, Period) * AnnualFactor * 100; 

_SECTION_END();

Rank2 = StaticVarGet( "rank1" + "value" + symbol );
RankC  = StaticVarGet ("RS_" +  Name()); 
rankvalue = StaticVarGet("rankvalue" + symbol);
bars=5;

AddTextColumn(Name(),"Stocks");
AddTextColumn(FullName(),"Company");
for ( i = 0; i < bars; i++ )  	
{
newday=Ref(day(),-i);
newmonth=Ref(Month(),-i);
newyear=Ref(Year(),-i);	
rs=Rankvalue;
rs=Ref(RS,-i);
rs1 = rankC;
rs1 = Ref(rankc,-i);

Filter = V > 1000;
SetOption( "NoDefaultColumns", True );
AddColumn(RS,""+newday+"/"+newmonth+"/"+newyear,1.2,colorDefault);
AddColumn(rs1,"Profit",1.2);
AddColumn(Ref(C,-i),"Price",1.2);
AddColumn(Ref(V,-i),"Volume",1.0);
AddColumn(Ref(C,-i)*Ref(V,-i),"Total Value",1.0);
AddColumn(Ref(RSI(14),-i), "RSI",1.2);
AddColumn(Volatility,"VIX",1.2);
}
if( Status( "Action" ) == actionExplore ) SetSortColumns( 3,4 );

If I no need to call SetForeign() who can help me recode my code?

Proper code was presented long time ago:

1 Like

Thank you very much, @Tomazs.
I also tried to follow the instructions, but I got stuck with the second loop (I’ve been trying hard to learn, but my results are still limited).
At first, I sorted the list based on total trading volume. Then, I tried to sort based on profit for the top 500 most traded stocks (using @Roketpower’s formula).
I’ve rewritten it several times, but still haven’t gotten the desired result.
I would really appreciate it if someone could help correct it and help me understand where I went wrong.
Below is my code.

#pragma sequence(scan,explore)
Version( 6.40 ); 

InputWatchlistNum = GetOption( "FilterIncludeWatchlist" ); 
list = CategoryGetSymbols( categoryWatchlist, InputWatchlistNum );
ListQty = StrCount( list, "," ) + 1;

if( Status( "action" ) == actionScan )
{

    if( Status( "stocknum" ) == 0 )
    {
        StaticVarRemove( "rank*" );
        StaticVarRemove( "value*" );
        //StaticVarRemove( "r*" );
    }
        value = C * MA( Ref( V, -1 ), 20 ) ;
        StaticVarSet( "value" + symbol, value );        // write ranked values to a static variable
        StaticVarGenerateRanks( "rank", "value", 0, 1234 );


    //value = StaticVarGet("Value" + symbol);
    rankvalue = StaticVarGet("rankvalue"+symbol);

    if( Status( "stocknum" ) == 0 )
    {
        StaticVarRemove( "RS_*" );
        StaticVarRemove( "RSraw_*" );
        StaticVarRemove( "RankRSraw*_" );
        
            RSraw = 0;
       
            ThreeMthRS  = 0.4 * ( C / Ref( C, -63 ) );
            SixMthRS    = 0.2 * ( C / Ref( C, -2 * 63 ) );
            NineMthRS   = 0.2 * ( C / Ref( C, -3 * 63 ) );
            TwelveMthRS = 0.2 * ( C / Ref( C, -4 * 63 ) );
            RSraw = ThreeMthRS + SixMthRS + NineMthRS + TwelveMthRS;
        
            StaticVarSet( "RSraw_"  +  Symbol, RSraw );
            RSraw  = StaticVarGet( "RSraw_" + Name() );
        

        StaticVarGenerateRanks( "Rank", "RSraw_", 0, 1224 );

        if( Status( "stocknum" ) == 0 )
        {
            for( n = 0; ( Symbol = StrExtract( list, n ) )  != "";  n++ )
            {
				SetForeign(Symbol);
                Rank  = StaticVarGet( "RankRSraw_" +  Symbol );
                rankvalue = StaticVarGet( "rankvalue" + symbol );
                RSpctile = IIf( rankvalue <= 600, 100 - 100 * Rank / ListQty, -10000 );
                StaticVarSet( "RS_" + Symbol, RSpctile, True );
                RestorePriceArrays();
            }
        }
    }
	RestorePriceArrays();
    _exit(); //Thoat ra va khong lam gi trong mode SCAN
}

symbol = Name();
RankC  = StaticVarGet( "RS_" +  symbol );

//Rank2 = StaticVarGet( "rank1" + "value" + symbol );

RankC  = StaticVarGet( "RS_" +  Name() );
rankvalue = StaticVarGet( "rankvalue" + symbol );


bars = 5;
AddTextColumn( Name(), "Stocks" );
AddTextColumn( FullName(), "Cty" );

for( i = 0; i < bars; i++ )
{
    newday = Ref( day(), -i );
    newmonth = Ref( Month(), -i );
    newyear = Ref( Year(), -i );
    rs = Rankvalue;
    rs = Ref( RS, -i );
    rs1 = rankC;
    rs1 = Ref( rankc, -i );
    obv1 = Ref( OBV(), -i );
    Filter = 1 ;
    SetOption( "NoDefaultColumns", True );
    AddColumn( rs1, "Profit", 1.2 );
    AddColumn( Ref( ROC( C, 20 ), -1 ), "ROC 20", 1.2 );
    AddColumn( Ref( C, -i ), "Gia", 1.2 );
    AddColumn( Ref( V, -i ), "KL", 1.0 );
    AddColumn( Ref( MA(V,20), -i ), "MA20_KL", 1.0 );
    AddColumn( Ref( C, -i )*MA( Ref( V, -1 ), 20 ), "GTGD", 1.0 );
    AddColumn( Ref( RSI( 14 ), -i ), "RSI", 1.2 );

}

if( Status( "Action" ) == actionExplore ) SetSortColumns( 3, 4 );

@Huynq99 , given that I probably don't understand the purpose of your formula, here's a simplified version. The exploration part is limited to displaying the calculated values.

#pragma sequence(scan,explore)
Version( 6.40 );

InputWatchlistNum = GetOption( "FilterIncludeWatchlist" );
list = CategoryGetSymbols( categoryWatchlist, InputWatchlistNum );
ListQty = StrCount( list, "," ) + 1;

if( Status( "action" ) == actionScan )
{

    if( Status( "stocknum" ) == 0 )
    {
        StaticVarRemove( "value*" );
        StaticVarRemove( "rank*" );
        StaticVarRemove( "rsraw*" );
    }

    symbol = Name();
    value = C * MA( Ref( V, -1 ), 20 ) ;
    StaticVarSet( "value" + symbol, value );        // write ranked values to a static variable
    StaticVarGenerateRanks( "rank", "value", 0, 1234 );

    ThreeMthRS  = 0.4 * ( C / Ref( C, -63 ) );
    SixMthRS    = 0.2 * ( C / Ref( C, -2 * 63 ) );
    NineMthRS   = 0.2 * ( C / Ref( C, -3 * 63 ) );
    TwelveMthRS = 0.2 * ( C / Ref( C, -4 * 63 ) );
    RSraw = ThreeMthRS + SixMthRS + NineMthRS + TwelveMthRS;
    _TRACEF( "%s - RS Raw: %g", symbol, RSraw );

    StaticVarSet( "rsraw"  + symbol, RSraw );
    StaticVarGenerateRanks( "rank", "rsraw", 0, 1224 );
    _exit();
}

symbol = Name();
rank1 = StaticVarGet( "rankvalue" + symbol );
rank2 = StaticVarGet( "rankrsraw" + symbol );
RSpctile = IIf( rank1 <= 600, 100 - 100 * rank2 / ListQty, -10000 ); // ? not clear what are you doing here...

Filter = 1 ;
AddTextColumn( Name(), "Ticker" );
AddColumn( rank1, "Rank 1", 1 );
AddColumn( rank2, "Rank 2", 1 );
AddColumn( RSpctile, "RS pctle", 1.2 );

if( Status( "action" ) == actionExplore )
    SetSortColumns( 2, -6 );
2 Likes

@Huynq99, an important correction: remove the two StaticGenerateRanks lines from the Scan block and put them in a new block when status("stocknum") == 0.

   // previous code edited...
}

if( Status( "stocknum" ) == 0 )
{
    StaticVarGenerateRanks( "rank", "value", 0, 1234 );
    StaticVarGenerateRanks( "rank", "rsraw", 0, 1224 );
}

symbol = Name();
rank1 = StaticVarGet( "rankvalue" + symbol );
rank2 = StaticVarGet( "rankrsraw" + symbol );
RSpctile = IIf( rank1 <= 600, 100 - 100 * rank2 / ListQty, -10000 ); // ? not clear what are you doing here...
// rest of code...

There is no point in executing them multiple times... sorry (today I'm rather distracted by the news from the Vatican).

3 Likes