How to calculate the exact number of stocks above & below a MA

Dear Group,

I am crating a composite to check number of stocks in a watchlist "NIFTY 500" which are above and below their 50 DMA. Possibility of C=MA50 is pretty remote. The afl is as follows:

_SECTION_BEGIN("Advance Decline Line 500");

MA20 = EMA(C,20);
MA50 = EMA(C,50);
MA100 = EMA(C,100);
MA200 = EMA(C,200);

if( InWatchListName("NSE - NIFTY 500") AND Name()!="NIFTY 500" ) AddToComposite(C>MA50,"~NSE - NIFTY 500 Above MA50","X",flags = atcFlagDefaults); 
if( InWatchListName("NSE - NIFTY 500") AND Name()!="NIFTY 500" ) AddToComposite(C<MA50,"~NSE - NIFTY 500 Below MA50","X",flags = atcFlagDefaults);
//if( InWatchListName("NSE - NIFTY 500") AND Name()!="NIFTY 500" ) AddToComposite(C=MA50,"~NSE - NIFTY 500 At MA50","X",flags = atcFlagDefaults);

ScripF1="~NSE - NIFTY 500 Above MA50";
ScripF2="~NSE - NIFTY 500 Below MA50";
//ScripF3="~NSE - NIFTY 500 At MA50";

 
CloseF1=Foreign(ScripF1,"Close");
CloseF2=Foreign(ScripF2,"Close");
//CloseF3=Foreign(ScripF3,"Close");
CloseTotal = CloseF1 + CloseF2;
//CloseTotal = CloseF1 + CloseF2 +CloseF3;

_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));


Graph0=Plot(CloseF1, "Adv Line", colorGreen, styleThick);

Graph1=Plot(CloseF2, "Dec Line", colorRed, styleThick);

Graph2=Plot(CloseTotal, "Adv-Dec Line", colorBlack, styleDots);

//Graph3=Plot(C,"Close",colorBlack,styleCandle);

Filter=1;


AddColumn(CloseF1,"Above50MA",1.0);
AddColumn(CloseF2,"Below50MA",1.0);
AddColumn(CloseTotal,"Total",1.0);

_SECTION_END();

Issue is the Total Number of stocks (CloseTotal = CloseF1 + CloseF2) seems to be varying with dates. The sample of Watchlist is list of Top 500 stocks in Indian Equities and therefore possibility of new listings within the space is that much difficult.
So there seems to be something wrong out there. Whether it has to do with the flags, am bit perplexed

FWIW, you do not need ATC (AddToComposite) but can use StaticVarAdd() function.
Also since you have multiple MA in your code you can save multiple composites at same time.

And BTW, you just need to create single composite per MA for either above OR below.
E.g. the ones that are below MA can be calculated by num_below = num_all - num_above; where num_above is the data of composite and num_all being number of symbols in watchlist. So just one composite required per MA.


Anyway as for multiple composites via StaticVarAdd() see here:


As for changing index memberships and historical plot...You would need vendor providing historical membership array flag (or doing yourself -> more work).

So then you could use

above = C > MA200 AND is_index_member;


Don't do that. Graph* is legacy.

Simply write

Plot(CloseF1, "Adv Line", colorGreen, styleThick);

Plot(CloseF2, "Dec Line", colorRed, styleThick);

Plot(CloseTotal, "Adv-Dec Line", colorBlack, styleDots);

Thanks a lot @fxshrat for the guidance. However the total number of symbols don't seem to match as I go into older dates. The difference is more pronounced when I am utilising the longer term average (200 DMA).

I bifurcated the code in two parts for cross check. Code 1 is for stocks above the MA

/// Set symbol list in Analysis Filter - Include
/// And enable pad&align
/// Set Periodicity in analysis General settings
/// Create composite ARRAY via SCAN 
/// @link https://forum.amibroker.com/t/percentage-stock-price-nyse-above-the-200-day-moving-average/19377/8
/// by AmiBroker.com and fxshrat@gmail.com
list_name = CategoryGetName(categoryGroup, 5);
symbol_name = "~AboveMA_"+list_name;
cnt = "~cnt_"+list_name;
periods = MxFromString("[50;200]");// MA periods
rows = MxGetSize(periods, 0);
persist = False;
if ( Status( "action" ) == actionScan ) 
{
    /// derived from AB manual
    /// @link https://www.amibroker.com/guide/afl/staticvaradd.html
    if ( Status( "stocknum" ) == 0 ) 
    {
        // remove any earier composite values
        StaticVarRemove(symbol_name+"*");
        StaticVarRemove(cnt);
    }   
    // Iterating periods
    for ( i = 0; i < rows; i++ ) 
		StaticVarAdd(symbol_name+"_"+ i, C >= MA(C, periods[i][0]), True, persist);
		StaticVarAdd(cnt, 1, True, persist);
    Buy = 0;
}

colors = "colorBlue,colorRed";
// Iterating periods
for ( i = 0; i < rows; i++ ) 
{
	Stocks_aboveMA = Nz(StaticVarGet(symbol_name+"_"+i));
	pcnt_aboveMA = Nz(StaticVarGet(symbol_name+"_"+i) / StaticVarGet(cnt))*100;
	titles = StrFormat("Percentage > %g-day MA", periods[i][0]);
	Plot(pcnt_aboveMA, titles, VarGet(StrExtract(colors,i)), styleThick);
	Filter = 1;
	AddColumn(Stocks_aboveMA,"Count+"+periods[i][0],1.0);
	AddColumn(pcnt_aboveMA,"Percent"+periods[i][0],1.2);
}

The second code I modified for stocks below the MA

/// Set symbol list in Analysis Filter - Include
/// And enable pad&align
/// Set Periodicity in analysis General settings
/// Create composite ARRAY via SCAN 
/// @link https://forum.amibroker.com/t/percentage-stock-price-nyse-Below-the-200-day-moving-average/19377/8
/// by AmiBroker.com and fxshrat@gmail.com
list_name = CategoryGetName(categoryGroup, 5);
symbol_name = "~BelowMA_"+list_name;
cnt = "~cnt_"+list_name;
periods = MxFromString("[50;200]");// MA periods
rows = MxGetSize(periods, 0);
persist = False;
if ( Status( "action" ) == actionScan ) 
{
    /// derived from AB manual
    /// @link https://www.amibroker.com/guide/afl/staticvaradd.html
    if ( Status( "stocknum" ) == 0 ) 
    {
        // remove any earier composite values
        StaticVarRemove(symbol_name+"*");
        StaticVarRemove(cnt);
    }   
    // Iterating periods
    for ( i = 0; i < rows; i++ ) 
		StaticVarAdd(symbol_name+"_"+ i, C <= MA(C, periods[i][0]), True, persist);
		StaticVarAdd(cnt, 1, True, persist);
    Buy = 0;
}

colors = "colorBlue,colorRed";
// Iterating periods
for ( i = 0; i < rows; i++ ) 
{
	Stocks_BelowMA = Nz(StaticVarGet(symbol_name+"_"+i));
	pcnt_BelowMA = Nz(StaticVarGet(symbol_name+"_"+i) / StaticVarGet(cnt))*100;
	titles = StrFormat("Percentage > %g-day MA", periods[i][0]);
	Plot(pcnt_BelowMA, titles, VarGet(StrExtract(colors,i)), styleThick);
	Filter = 1;
	AddColumn(Stocks_BelowMA,"Count-"+periods[i][0],1.0);
	AddColumn(pcnt_BelowMA,"Percent"+periods[i][0],1.2);
}

Then I took the output in exploration. While the difference is not big in latest quotes, It's substantial in older quotes
Flaw 50-200 2

I am missing something there as same issue had arisen in the AddToComposite quotes.

However the total number of symbols don't seem to match as I go into older dates.

Have you enabled "Pad&align" as instructed in the code?

Yes I have
Flaw 50-200 2

Some of your symbols simply have SHORT history.

1 Like

@Tomasz indeed there is a SHORT history. The constituents are changed semi annual and almost 5% cases are those wherein such issue of SHORT history is there.

Will like to have suggestions on SCAN specifications. I was running it on 'All Quotes' by default. As a change do I run it on say "75 bars" (approx 3 months). Would this save the earlier values as indicator?

While I am toggling between indices, I am seeing the variations. So would 'AddToComposite' be better bet in terms of saving the historical values, while running it on 75 bars?

1 Like

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

Stocks above MA

Refering to above, the PLOT is working proper on Daily Time Scale

However when put on weekly scale it's getting distorted

Clearly the "Y-axis" scale is incorrect. Check your data in the period of August 2019 till July 2020.

To get better understanding of what is happening in your code and how functions work, use advice given here: How do I debug my formula?