Sectoral Relative Strength - Only update on Weekend

"Inspired by William O'Neil's theory that a stock's relative strength is significantly influenced by its industry and sector performance, I have coded extensive and successfully developed a method to calculate sectoral Relative Strength (RS).

Currently, my 1-month sectoral RS rankings update with each daily bar. However, O'Neil emphasizes that daily group movements introduce considerable noise into the analysis, making weekly rankings far more reliable.

I would like to maintain the current display while ensuring that the rankings update only at weekly intervals rather than daily. I have attempted to implement this using timeframe parameters but have been unable to achieve the desired outcome."

Enclosed chart you would find the Sector Rank.

_SECTION_BEGIN(" Sector RS Exploration");

// More robust sector handling
LastSectorNumber = 23;

// Pre-calculate sector RS only once using StaticVar
if(Status("stocknum") == 0)
{
    for(i = 1; i <= LastSectorNumber; i++)
    {
        SECTORName = CategoryGetName(categorySector, i);
        if(SECTORName != "")
        {
            SectorTickerlist = CategoryGetSymbols(categorySector, i);
            SectorChange = 0;
            CountSectorSymbols = 0;
            
								for(j = 0; (SectorTicker = StrExtract(SectorTickerlist, j)) != ""; j++)
								{
									  if ( Status("actionex") != actionExEditVerifyFormula )
									 SetForeign(SectorTicker, 1);  // 1 = pad with Null for missing data
									notnull = NOT IsNull(C) AND NOT IsNull(Ref(C,-126));
									CountSectorSymbols += IIf(notnull,1, 0 );
									printf("\n CountSectorSymbols == %f", SelectedValue(CountSectorSymbols));
							
									CloseAtBar = SelectedValue(C);
									CloseAt21Bar = SelectedValue(Ref(C, -21));
									SectorChange += IIf(notnull,  SafeDivide(CloseAtBar, CloseAt21Bar), 0);
									RestorePriceArrays();
								}
							
					if(SelectedValue(CountSectorSymbols) > 0)
					{
						SectorRS = (SelectedValue(SafeDivide(SectorChange, CountSectorSymbols)) - 1) * 100;
						StaticVarSet("SectorRS_" + i, SectorRS);
						StaticVarSet("SectorCount_" + i, CountSectorSymbols);
					}
		}
    }
  
}
 GfxTextOut("Sector Rank   "+StaticVarGet("SectorRank_" + SectorID()),300,40);
 

There is no portion in the code that sets the "SectorRank_" + SectorID() variable.

Anyway, if you are using a chart, why dont you use AB Batch or a scheduling mechanism to run your EXPLORATION APX file every weekly period?

Once this executed EoD on Fri for example, you set persistent Static Variables and then use them whenever you want in your Charting code.
This is the part where you do StaticVarGet()
So you can access unchanged variable everyday. There is NO need to calculate RANK everyday.

Even if Friday is a holiday, the most recent bars of that week will compute your RANK.

PS: When you post a question, look at it from a 3rd person view, and figure out if what you have posted is sufficient for the others to understand.

For Example:
Posted code is related to Exploration, or chart or what?
in what timeframe is your chart running.
The Formula you posted seems to be for Analysis window. Again what timeframe, other details ?
Highlight or circle your sector rank in the image, its hard to guess
And personally, focus more on the problem at hand in the post than what Mr O'Neil said.

My intention is not to be rude, but in your previous post Matt and I were left guessing on what you meant.

1 Like

Sorry it was pulling Ranks from and Include Function

The workable code on a Daily Time Frame is below

_SECTION_BEGIN("Optimized Sector RS Exploration");

// More robust sector handling
LastSectorNumber = 23;

// Pre-calculate sector RS only once using StaticVar
if(Status("stocknum") == 0)
{
    for(i = 1; i <= LastSectorNumber; i++)
    {
        SECTORName = CategoryGetName(categorySector, i);
        if(SECTORName != "")
        {
            SECTORtickerlist = CategoryGetSymbols(categorySector, i);
            SectorChange = 0;
            CountSectorSymbols = 0;
            
								for(j = 0; (SectorTicker = StrExtract(SECTORtickerlist, j)) != ""; j++)
								{
									  if ( Status("actionex") != actionExEditVerifyFormula )
									 SetForeign(SectorTicker, 1);  // 1 = pad with Null for missing data
									notnull = NOT IsNull(C) AND NOT IsNull(Ref(C,-126));
									CountSectorSymbols += IIf(notnull,1, 0 );
									printf("\n CountSectorSymbols == %f", SelectedValue(CountSectorSymbols));
							
									CloseAtBar = SelectedValue(C);
									CloseAt21Bar = SelectedValue(Ref(C, -21));
									SectorChange += IIf(notnull,  SafeDivide(CloseAtBar, CloseAt21Bar), 0);
									RestorePriceArrays();
								}
							
					if(SelectedValue(CountSectorSymbols) > 0)
					{
						SectorRS = (SelectedValue(SafeDivide(SectorChange, CountSectorSymbols)) - 1) * 100;
						StaticVarSet("SectorRS_" + i, SectorRS);
						StaticVarSet("SectorCount_" + i, CountSectorSymbols);
					}
		}
    }
    
    // Calculate rankings
    for(i = 1; i <= LastSectorNumber; i++)
    {
        if(StaticVarGet("SectorRS_" + i) != 0)
        {
            rank = 1;
            for(j = 1; j <= LastSectorNumber; j++)
            {
                if(StaticVarGet("SectorRS_" + j) > StaticVarGet("SectorRS_" + i))
                    rank = rank + 1;
            }
            StaticVarSet("SectorRankk_" + i, rank);
        }
    }
}

 GfxTextOut("Sector Rankk_"+StaticVarGet("SectorRank_" + SectorID()),300,40);

I have marked on the image the output I'm seeking for the sector rank should change on the weekend bar on a chart not exploration.

As a Indian we always have high regard from whom we learn may it be from books or physical form may it be O Neil or Warren Buffet. Its our culture to respect Gurus (Teachers) . I mentioned O Neil coz if you dont understand his concept you cant understand my problem.

And at the end of the day no one is born genius , everyone learns from some one or the other, everyone gains knowledge from somewhere.

The issue is not about mentioning a person, you wrote just 1 line in 4 paragraphs about your issue.
It is more important to describe your issue, and importantly, you missed the main part of code of setting the RANK static variable.

Anyway, I leave it there. BUT, you have not replied to the idea of calculating the rank separately every week.
This should solve the problem, even if you used Daily TF to calculate it Friday EoD.

1 Like

Achieved what I was looking for . The ranking changes on every week end.

_SECTION_BEGIN("Sector RS");

// More robust sector handling
LastSectorNumber = 23;

// Pre-calculate sector RS only once using StaticVar
if(Status("stocknum") == 0)
{
    for(i = 1; i <= LastSectorNumber; i++)
    {
        SectorName = CategoryGetName(categorySector, i);
        if(SectorName != "")
        {
            SectorTickerList = CategoryGetSymbols(categorySector, i);
            SectorChange = 0;
         
            CountSectorSymbols = 0;
            
            TickerCount = 0;
             printf("\n ===================================  ");
             printf("\n SectorName  =\t"+SectorName);
             printf("\n ===================================  ");
            
								for(j = 0; (SectorTicker = StrExtract(SectorTickerList, j)) != ""; j++)
								{
									 if ( Status("actionex") != actionExEditVerifyFormula )
									  SetForeign(SectorTicker, 1);  // 1 = pad with Null for missing data
										  printf("\n SectorTicker  =\t"+SectorTicker);
										  printf("\n CountSectorSymbols "+CountSectorSymbols);
										  TimeFrameSet(inWeekly);
										  VALIDATION = NOT IsNull(Ref(C,-126)) AND NOT IsNull(Ref(C,-21)) AND NOT IsNull(C);
										  CountSectorSymbols  = IIf( IsTrue(VALIDATION), CountSectorSymbols+1,   CountSectorSymbols+0 );
										  CloseAtBar =C;
										  CloseAtPreviousBar = Ref(C, -21);
										  SectorChange += IIf(IsTrue(VALIDATION),  SafeDivide(CloseAtBar, CloseAtPreviousBar), 0);
										  printf("\n CloseAtBar  =\t"+CloseAtBar + "\n CloseAtPreviousBar  =\t"+CloseAtPreviousBar  + "\n SectorChange  =\t"+SectorChange);
										  printf("\n");
									 RestorePriceArrays();
								}
							    printf("\n Total CountSectorSymbols  = \t "+CountSectorSymbols);
				       	if(SelectedValue(CountSectorSymbols) > 0)
							{
								SectorRSW = ((SafeDivide(SectorChange, CountSectorSymbols)) - 1) * 100;
								SectorRS = TimeFrameExpand(SectorRSW,inWeekly,expandLast);
								StaticVarSet("SectorRSW_" + i, SectorRS);
								StaticVarSet("SectorCountW_" + i, CountSectorSymbols);
							}
		}
    }
 StaticVarGenerateRanks( "Rank", "SectorRSW_", 0, 1234 );
}

// Get current stock's sector info with error handling
CurrentSectorID = SectorID();
ValidSector = CurrentSectorID >= 1 AND CurrentSectorID <= LastSectorNumber;

if(ValidSector)
{
    SectorRS_Value = StaticVarGet("SectorRSW_" + CurrentSectorID);
    SectorRank_Value = StaticVarGet("RankSectorRSW_" + CurrentSectorID);
    SectorCount_Value = StaticVarGet("SectorCountW_" + CurrentSectorID);
    SectorName_Value = CategoryGetName(categorySector, CurrentSectorID);
}
else
{
    SectorRS_Value = 0;
    SectorRank_Value = 0;
    SectorCount_Value = 0;
    SectorName_Value = "Unknown Sector";
}


GfxTextOut("SectorNameW   ="+SectorName_Value,20,20);
GfxTextOut("SectorRS_ValueW   ="+ NumToStr(SectorRS_Value, 1.2) + "%", 20, 40);
GfxTextOut("SectorRank_ValueW   ="+SectorRank_Value,20,60);
GfxTextOut("SectorSymbolsW  ="+SectorCount_Value,20,80);
 
 
1 Like

And Ultimately a Table to Display Sector Wise Ranks on a Daily Basis and Weekly Basis. The Rank(D) will change on every bar but the Rank(W) will only change on the last trading day of the week.

The above image is the interface Table on the Interface.

Below is the exploration of the Sectoral Ranking Daily that matches with the Interface Table. RS is the Relative Strength.

2 Likes

@PASH Thanks a lot for sharing.

Hi @PASH ,

Few questions if you dont mind answering.

How are you getting the table to display secor rankings on chart and exploration? When I run your code, I dont get any.

Also, How are you getting sectors for stocks form BSE website?

Please advise. Thanks in advance.

Hi @vdtedla1 ,

Initially I tried both NSE and BSE but somehow the BSE Classification sounded more rational. So I took the list of NSE Stocks and initially did the classification manually. Its a one time process. After that its just a matter of updating at regular intervals.

Here's the link for the Sectoral Classification of NSE Stocks. You need to import this into your database.

NSE Sectoral Classification

@vdtedla1 to import in your database use the menu option to import ASCII files using the Import Wizard (File/Import Wizard...)

In the documentation, there is the following example about the proper way to do it:


Importing Sector/Industry structure

Let's assume we have a text file with Stock tickers, Full names, Sector name and industry name listed line by line, as follows:

"DDD","3D Systems Corporation","Technology","Computer Software: Prepackaged Software"
"MMM","3M Company","Health Care","Medical/Dental Instruments"
"SVN","7 Days Group Holdings Limited","Consumer Services","Hotels/Resorts"
"AHC","A.H. Belo Corporation","Consumer Services","Newspapers/Magazines"

To import such file we use the following format definition:

$FORMAT Ticker, FullName,SectorName,IndustryName
$SEPARATOR ,
$AUTOADD 1
$NOQUOTES 1
$OVERWRITE 1
$CLEANSECTORS 1
$SORTSECTORS 1

$NOQUOTES 1 tells the importer that we will be importing non-quotation data. $AUTOADD 1/$OVERWRITE 1 is required to automatically add new symbols and overwrite existing symbol information. $CLEANSECTORS 1 wipes existing stock/industry structure prior to importing and $SORTSECTORS 1 - sorts sectors/industries after importing so they will be listed in alphabetical order in the Symbol window. $FORMAT command just specifies the order and types of field to import

AmiBroker will read such ASCII file one-by one, then it will check whenever given sector name/industry name already exists, if not - it will create new sector/industry. Then it will assign given symbol to specified sector/industry.

The result will be a database with new sector/industry structure being set up and symbols assigned to proper sectors and industries.


1 Like

Thanks @PASH & @beppe for your help. Appreciate your time.

1 Like

@vdtedla1
Here's a video link that would help you

Importing Sector Classification to Amibroker

1 Like

Thanks @PASH . Will look into it.