Number of symbols above MAs, was: Watchlist Inconsistency

Hi All,

I am trying to adapt some code that I found on these boards that @portfoliobuilder had suggested back in 2019.

I am simply trying to total the number of stocks in a given watchlist tradiing above their 20 and 50day MAs.

Code seems to work fine on some watchlists but not others. Screenshots at bottom. You can see that it is picking up the correct number of symbols in the list but not providing the totals in all instances.

Wondering if someone is able to spot what is going wrong.

Thanks to @portfoliobuilder for the original code and to all who spend the time to read my query.

Thanks Dejaco

// select your WL in the Analysis window

wlnumber  = GetOption( "FilterIncludeWatchlist" );
watchlist = CategoryGetSymbols( categoryWatchlist, wlnumber );
SymbolCount = StrCount(watchlist, ",") + 1;

AboveTwentyTotal = 0;
AboveFiftyTotal = 0;
TwentyEMA = EMA(Close,20);
FiftyMA = MA(Close,50);

for( num = 0; ( symbol = StrExtract( watchlist, num ) ) != ""; num++ )
{

    SetForeign( symbol );

    AboveTwenty = Close > TwentyEMA;
    AboveTwentyTotal += AboveTwenty;
    
    AboveFifty = Close > FiftyMA;
    AboveFiftyTotal += AboveFifty;

    RestorePriceArrays();

}

///  Exploration  ///
Filter = Status("LastBarInRange") AND Status( "stocknum" ) == 0;
SetOption("NoDefaultColumns",True);
AddColumn(DateTime(), "Date", formatDateTime);
AddColumn( AboveTwentyTotal, "Trading above 20EMA" , 1.0 );
AddColumn( AboveFiftyTotal, "Trading above 50MA" , 1.0 );
AddColumn( SymbolCount, "Total # of Symbols in WL", 1.0);

image
image
image

I can see that totals in all 3 cases (Total # of symbols in WL) are correct, i.e. exactly the same as shown in Filter window.

As for averages - the results you are getting are incorrect because
as it was brought up before several times that the code from @portfoliobuilder (or your adaptation) is INCORRECT.

PLEASE PROVIDE the original link from where code was taken so we could correct original.

First and foremost, inside the loop the code does not calculate Close > TwentyEMA for symbols in the watch lists because those moving averages are outside the loop, so the code merely adds up data for very first symbol in the watchlist over and over again.

Secondly, presented method (loop with Foreign calls) is not recommended.

Recommended is loopless - to use AddSummaryRows as instructed in the Users' Guide
http://www.amibroker.com/f?addsummaryrows

Filter=1; 
TwentyEMA = EMA(Close,20);
FiftyMA = MA(Close,50);
AddColumn( C > TwentyEMA, "AboveTwenty" ); 
AddColumn( C > FiftyMA, "AboveFifty" ); 
AddSummaryRows( 1, 1.0 ); 
1 Like

@dejaco Above @Tomasz has shown you one method of solving your problem. If you are looking for a method to create variables that you can use in a strategy then perhaps this code can get you started.

// First run a SCAN on the Watch List of interest
// then run the Explore or Plot or begin using calcs in a backtest

if( Status( "actionEx" ) == actionScan )
{
    if( Status( "stocknum" ) == 0 )
    {
        StaticVarRemove( "~Above*" );
    }

    StaticVarAdd( "~Above20", Close > EMA( Close, 20 ) );
    StaticVarAdd( "~Above50", Close > EMA( Close, 50 ) );
    Buy = 0; 

}
svAbove20 = StaticVarGet( "~Above20" );
svAbove50 = StaticVarGet( "~Above50" );

////////////////////////
// Exploration
////////////////////////
if( Status( "action" ) == actionExplore )
{
    //Filter = 1;
	Filter = Status("LastBarInRange") AND Status( "stocknum" ) == 0;
    SetOption( "NoDefaultColumns", True );
    AddColumn( DateTime(), "Date", formatDateTime );
    //AddColumn( C, "Close" );
    //AddColumn( EMA( Close, 20 ), "ema20", 1.2, colorDefault, IIf( Close > EMA( Close, 20 ), colorLime, colorDefault ) );
    //AddColumn( EMA( Close, 50 ), "ema50", 1.2, colorDefault, IIf( Close > EMA( Close, 50 ), colorYellow, colorDefault ) );
    AddColumn( svAbove20, "# Above EMA(20)", 1.0 );
    AddColumn( svAbove50, "# Above EMA(50)", 1.0 );
}

////////////////////////
// Charting
////////////////////////
if( Status( "action" ) == actionIndicator )
{
    Plot( svAbove20, "# Above MA(20)", colorGreen, styleThick );
    Plot( svAbove50, "# Above MA(50)", colorLightYellow, styleDashed );
}

That will produce this type of output,

image

If you comment out the top few lines in the Exploration and uncomment the others, you can use the Exploration to debug the code an manually confirm that it is producing the expected result. For example,
image

And for comparison if you use the code provided by @Tomasz on the same WL and the same day you can produce this output for comparison.
image

Please DO NOT use

 SetOption( "NoDefaultColumns", True ); // DO NOT USE THIS !

People copy-paste blindly codes like this in all the places and do more harm than good. Without default columns, show arrows functionality does not work. Show arrows REQUIRES default columns.

Hi Tomasz

Thanks very much for your answer and your time.

The link for the code that I copied is below.

How to count the number of tickers in a watchlist with condition? - AFL Programming - AmiBroker Community Forum

Hi @portfoliobuilder, thanks very much for your answer. Really appreciate the time people like you take to answer these queries.

1 Like

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.