AddToComposite results

I am trying to develop an indicator (refer below) showing the number of stocks above 20 week moving average on a specific watchlist of 90 stocks. It works fine except for the fact that when I manually count the stocks above 20 week moving average, it shows some discrepancy. I have been trying to figure this out for a number of days and would appreciate if someone can help. Thanks.

MA20 = MA(C,20);
Above20 = Close > MA20;

Buy = 0; 
Filter = 0;

AddToComposite( Above20 , "~Above20", "X", 7);
 
Above20ma = Foreign ("~Above20", "C", True);
Plot(Above20ma,"Above 20",colorBrightGreen,styleLine,0,0,0,0,2);

@applet There are several very informative threads here on the forum about building composite indicators. You should read through some like this one,

If you want a good review of the AddToComposite function you will find this classic document,

If you want to try the StaticVarAdd method here is a start (have not really tested it so go over it carefully),

// pick watchlist in AA window
wlnum = GetOption( "FilterIncludeWatchlist" );
List = CategoryGetSymbols( categoryWatchlist, wlnum );

maPeriods = Param( "maPeriods", 20, 5, 35, 1 );


if( Status( "stocknum" ) == 0 )
{
    StaticVarRemove( "~AboveAverage*" );
    StaticVarRemove( "~SymbolCount*" );

    for( n = 0; ( Symbol = StrExtract( List, n ) )  != "";  n++ )
    {
        SetForeign( Symbol );
        
        AboveAverage = Close > MA( C, maPeriods );
        StaticVarAdd( "~AboveAverage", AboveAverage );
        StaticVarAdd( "~SymbolCount", 1 );

        RestorePriceArrays();
    }
}

svAboveAverage = StaticVarGet( "~AboveAverage" );
svSymbolCount = StaticVarGet( "~SymbolCount" );
PercentAbove = ( svAboveAverage / svSymbolCount ) * 100;

///////////////
// Explore
///////////////
Filter = Status( "stocknum" ) == 0;
SetOption("NoDefaultColumns",True);
AddColumn(DateTime(), "Date", formatDateTime);
AddColumn( svAboveAverage , "Stocks with C > MA(" + maPeriods + ") ", 1.0 );
AddColumn( svSymbolCount, "Total Number of Stocks", 1.0 );
AddColumn( PercentAbove, "PercentAbove", 1.1, colorWhite, colorDarkGreen );

///////////////
// Chart
///////////////
Plot( PercentAbove, "PercentAbove", colorRed, styleThick );

4 Likes

@portfoliobuilder Thanks a mill for this. I spent a good time with the code understanding it and reading about StaticVarAdd functions. This works perfectly fine and far exceeds my initial requirements. Much appreciated.

@portfoliobuilder can you please help me understand as to how this function knows to count the symbols in a particular watchlist. I know it works but trying to understand as to how? There is no reference in this function to count symbols in the watchlist. I am sure missing something and would appreciate the guidance. Lastly, how can I only count the symbols which are active i.e. have a price at a particular point of time? I am using Norgate and running this on a watchlist of S&P 500 current and past.

@applet,

StaticVarAdd is placed within looping code. That looping code iterates a comma separated list of symbols. So all StaticVarAdd does is simply adding 1 to each iteration step (-> each step -> new symbol of list).

But counting like that is a waste of code lines because it is not operating on any array. It just counts number, nothing more and nothing less.

So instead of three lines the same result can be achieved with just a single line of code outside of loop:

svSymbolCount = StrCount(list, ",")+1;

So e.g.

// pick watchlist in AA window
wlnum = GetOption( "FilterIncludeWatchlist" );
List = CategoryGetSymbols( categoryWatchlist, wlnum );

maPeriods = Param( "maPeriods", 20, 5, 35, 1 );

trigger = Status("action") == actionExplore OR ParamTrigger("Create Average", "CLICK HERE");

if ( trigger ) {
	if( Status( "stocknum" ) == 0 )
	{
		AboveAverage = 0;
		for( n = 0; ( Symbol = StrExtract( List, n ) )  != "";  n++ )
		{
			SetForeign( Symbol );        
				AboveAverage += Nz(Close > MA( C, maPeriods ));			
			RestorePriceArrays();
		}
		StaticVarSet( "~AboveAverage", AboveAverage );// being set one time
	}
}

svAboveAverage = StaticVarGet( "~AboveAverage" );
svSymbolCount = StrCount(List, ",")+1;
PercentAbove = ( svAboveAverage / svSymbolCount ) * 100;

// further code for output, etc. below:
// ....

Note: there is not any static vars within loop required at all.


If you want to exclude symbols not having data at a bar then both upper ones can not be used because again they do not operate on array data but just return numbers.
In order to operate on array data you may use NOT IsNull(C) check within loop.

Take a look at example here:

4 Likes