Generate ranks on Daily data but evaluate strategy on Hourly

I am trying to generate ranks on daily data, but evaluate a strategy on hourly data (which is its native periodicity)

I am grabbing the symbols from a watchlist.

When I switch the chart back and forth from daily to hourly the ranking should be the same for that particular day, but it is not. The rank should switch only once a day, so when on an hourly chart, the plot line should "stair-step" from one day to the next.

Here is my attempt. Can someone see why it is not working properly?

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
_SECTION_END();

/////////////////////   First Rank on Daily bars  //////////////////////////////////////////////////////////////////////////////////////////

TimeFrameSet( inDaily ); // switch to daily time frame 

SymbolCount = 0;
mySymList = "";

EnableTextOutput(0);
mySymList = CategoryGetSymbols( categoryWatchlist, 64, 0 ); 
EnableTextOutput(1);

for( i = 0; ( sym = StrExtract( mySymList, i ) ) != ""; i++ )
{
	SymbolCount ++;
  //printf( "Symbol is " + sym + " " );   
}
printf("Symbol SymbolCount: " + NumToStr(SymbolCount,0)  + "\n" ); 

FirstSymbol = IIf( Status("stocknum") == 0 , FirstSymbol = 1, FirstSymbol = 0);

if( FirstSymbol )
{
	PPOShort = Param( "PPO Short Period", 12, 1, 150, 1 );
	PPOLong = Param( "PPO Long Period", 26, 1, 150, 1 );
	PPOsignal = Param( "PPOsignal", 9, 1, 150, 1 );

	// delete static variables 
	StaticVarRemove( "ItemScore*" ); 

	// fill input static arrays 
	for ( i = 0; ( sym = StrExtract( mySymList, i ) ) != ""; i++ ) 
	{ 
		SetForeign( sym );
		
		myROC = ROC(Close, 14);
		
		RestorePriceArrays();
		
		// write ranked values to a static variable
		StaticVarSet( "ItemScore" + sym, myROC );
	} 
	
	// perform ranking 
	StaticVarGenerateRanks( "Rank", "ItemScore", 0, 1224 ); // normal rank mode 
}
else
{
  // Not first symbol
}

myScoreSymbol = "AAPL";	
ThisScore = StaticVarGet("ItemScore" + myScoreSymbol ); 
//Plot( ThisScore, myScoreSymbol + "_score", colorYellow ); 
printf( "ThisScore: " + NumToStr( ThisScore ) + "\n" ); 
	
// read ranking
ThisRank = StaticVarGet("RankItemScore" + myScoreSymbol ); 
DailyRankPct = ((SymbolCount-ThisRank)/SymbolCount)*100;
//Plot( DailyRank , myScoreSymbol + "_rank", colorAqua ); 
printf( "RankItemScore: " + NumToStr( StaticVarGet( "RankItemScore" + "AAPL" ), 0 ) + "\n" ); 

for ( i = 0; ( sym = StrExtract( mySymList, i ) ) != ""; i++ ) 
{ 
  //Plot( StaticVarGet( "RankItemScore" + sym ), sym, colorCustom10 + i ); 
} 


/////////////////////   STRATEGY on 60min  //////////////////////////////////////////////////////////////////////////////////////////

TimeFrameRestore();

ExpandedRankPct = TimeFrameExpand( DailyRankPct, inDaily);
Plot( ExpandedRankPct , myScoreSymbol + "_rank", colorAqua );

TimeFrameRestore and RestorePriceArray do the same thing.

Also you should apply Timeframeset where it belongs to (-> where there are arrays to be compressed). In addition Param functions should not be set within if statements but outside of it.

SymbolCount is one line.

This is too much code too and not required.

FirstSymbol = IIf( Status("stocknum") == 0 , FirstSymbol = 1, FirstSymbol = 0);

Below is modified code. Not tested for (other hidden) mistakes as I have fixed it in this forum editor only!

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
_SECTION_END();

/////////////////////   First Rank on Daily bars  //////////////////////////////////////////////////////////////////////////////////////////

EnableTextOutput(0);
mySymList = CategoryGetSymbols( categoryWatchlist, 64, 0 ); 
EnableTextOutput(1);

SymbolCount = StrCount(mySymList, ",") + 1;
printf("Symbol SymbolCount: %g\n",  SymbolCount ); 

PPOShort = Param( "PPO Short Period", 12, 1, 150, 1 );
PPOLong = Param( "PPO Long Period", 26, 1, 150, 1 );
PPOsignal = Param( "PPOsignal", 9, 1, 150, 1 );

FirstSymbol = Status("stocknum") == 0;

if( FirstSymbol )
{
	// delete static variables 
	StaticVarRemove( "ItemScore*" ); 

	// fill input static arrays 
	for ( i = 0; ( sym = StrExtract( mySymList, i ) ) != ""; i++ ) 
	{ 
		SetForeign( sym );
		
		TimeFrameSet( inDaily ); // switch to daily time frame 			
			myROC = ROC(Close, 14);			
		TimeFrameRestore();	
		
		score = TimeFrameExpand( myROC, inDaily);
		
		// write ranked values to a static variable
		StaticVarSet( "ItemScore" + sym, score );
	} 
	
	// perform ranking 
	StaticVarGenerateRanks( "Rank", "ItemScore", 0, 1224 ); // normal rank mode 
}

myScoreSymbol = "AAPL";	
ThisScore = StaticVarGet("ItemScore" + myScoreSymbol ); 
//Plot( ThisScore, myScoreSymbol + "_score", colorYellow ); 
printf( "ThisScore: " + NumToStr( ThisScore ) + "\n" ); 
	
// read ranking
ThisRank = StaticVarGet("RankItemScore" + myScoreSymbol ); 
DailyRankPct = ((SymbolCount-ThisRank)/SymbolCount)*100;
//Plot( DailyRank , myScoreSymbol + "_rank", colorAqua ); 
printf( "RankItemScore: " + NumToStr( StaticVarGet( "RankItemScore" + "AAPL" ), 0 ) + "\n" ); 

for ( i = 0; ( sym = StrExtract( mySymList, i ) ) != ""; i++ ) 
{ 
  //Plot( StaticVarGet( "RankItemScore" + sym ), sym, colorCustom10 + i ); 
} 


/////////////////////   STRATEGY on 60min  //////////////////////////////////////////////////////////////////////////////////////////


Plot( DailyRankPct, myScoreSymbol + "_rank", colorAqua );
2 Likes

@fxshrat,

Thank you very much for the above code. I, too, am trying to build a ranking method, almost on the same method. But what i observed was, i get different results when i use timeframeset function in ranking criteria.

For example, when i use below code, i get the correct result.

for( n = 0; ( Symbol = StrExtract( List, n ) )  != "";  n++ )
    {
        SetForeign( symbol );
       
        // write our ranking criteria to a variable
        // in this example we will use 10-bar rate-of-change
                
       values=  ROC( Close, 10 );

       RestorePriceArrays();

        // write ranked values to a static variable
        StaticVarSet( "values"  + symbol, values );

    }

	StaticVarGenerateRanks( "rank", "values" , 0, 1224 );

but, when i use above code with timeframe functions, i get entrely different values.

for( n = 0; ( Symbol = StrExtract( List, n ) )  != "";  n++ )
    {
        SetForeign( symbol );

        // write our ranking criteria to a variable
        // in this example we will use 10-bar rate-of-change
      
          TimeFrameSet(inDaily);
        
       myROC=  ROC( Close, 10 );
       TimeFrameRestore();
       values= TimeFrameExpand(myROC, inDaily);
        		
       
        // write ranked values to a static variable
        StaticVarSet( "values"  + symbol, values );

    }

	StaticVarGenerateRanks( "rank", "values" , 0, 1224 );

Please give your insight.
Thanks .

First of all if ranking then you should check pad&align setting of analysis settings!
BTW, AmiBroker 6.28+ will inform you if pad and align is turned OFF while doing ranking.
181959

Secondly longer interval has to be integer multiple of (selected) shorter interval if working with timeframe functions. What do I mean? For example I have already posted similar responses in regards to timeframe functions (+ ranking) here


and here (second paragraph).

So if I use this "fixed" code which is edited from post 1 then as seen below in explorer I am getting matching results in both intraday and in daily TF.

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
_SECTION_END();

/////////////////////   First Rank on Daily bars  //////////////////////////////////////////////////////////////////////////////////////////

wlnum = GetOption("FilterIncludeWatchlist");

EnableTextOutput(0);
mySymList = CategoryGetSymbols( categoryWatchlist, wlnum, 0 ); 
EnableTextOutput(1);

SymbolCount = StrCount(mySymList, ",") + 1;
printf("Symbol SymbolCount: %g\n",  SymbolCount ); 

//PPOShort = Param( "PPO Short Period", 12, 1, 150, 1 );
//PPOLong = Param( "PPO Long Period", 26, 1, 150, 1 );
//PPOsignal = Param( "PPOsignal", 9, 1, 150, 1 );

FirstSymbol = Status("stocknum") == 0;

tmfrm = inDaily;

if( FirstSymbol )
{
	// delete static variables 
	StaticVarRemove( "ItemScore*" ); 

	// fill input static arrays 
	for ( i = 0; ( sym = StrExtract( mySymList, i ) ) != ""; i++ ) 
	{ 
		SetForeign( sym );
		
		TimeFrameSet( tmfrm ); // switch to daily time frame 			
			myROC = ROC(Close, 10);			
		TimeFrameRestore();	
		
		score = TimeFrameExpand( myROC, tmfrm, expandLast);
		
		// write ranked values to a static variable
		StaticVarSet( "ItemScore" + sym, score );
	} 
	
	// perform ranking 
	StaticVarGenerateRanks( "Rank", "ItemScore", 0, 1224 ); // normal rank mode 
}

myScoreSymbol = Name();	
ThisScore = StaticVarGet("ItemScore" + myScoreSymbol ); 
//Plot( ThisScore, myScoreSymbol + "_score", colorYellow ); 
printf( "ThisScore: " + NumToStr( ThisScore ) + "\n" ); 
	
// read ranking
ThisRank = StaticVarGet("RankItemScore" + myScoreSymbol ); 
DailyRankPct = ((SymbolCount-ThisRank)/SymbolCount)*100;
//Plot( DailyRank , myScoreSymbol + "_rank", colorAqua ); 
printf( "RankItemScore: " + NumToStr( StaticVarGet( "RankItemScore" + myScoreSymbol ), 0 ) + "\n" ); 

//for ( i = 0; ( sym = StrExtract( mySymList, i ) ) != ""; i++ ) 
//{ 
  //Plot( StaticVarGet( "RankItemScore" + sym ), sym, colorCustom10 + i ); 
//} 


/////////////////////   STRATEGY on 60min  //////////////////////////////////////////////////////////////////////////////////////////


Plot( DailyRankPct, myScoreSymbol + "_rank", colorAqua );


// -- Exploration --
AddSummaryRows( 62, 1.2);
SetSortColumns( 1, 2);

Filter = (DateNum() != Ref(DateNum(),1) OR Status("lastbarinrange")) AND ! IsNull(ThisScore);
AddTextColumn( Interval(2), "Selected Interval", 1);
AddColumn(ThisRank, "Daily Ranking", 1.0);
AddColumn(ThisScore, "Daily Score", 1.2);

181026

180959

10 Likes

@fxshrat ,

Thank you very much for the efforts you take to educate people like me.

Thanks once again

@fxshrat

Can I use your solution using a End-of-Day data?

Thanks!