Exploration RSI Monthly with any of the 3 conditions

Hi Team,

Need help again. My requirement is:
Exploration result includes 3 conditions

  1. The stocks go above RSI 70 on the monthly charts for the first time in its lifetime.
  2. The stocks go above RSI 70 on the monthly charts after a gap of 2 years.
  3. The stock is already in the RSI > 70 Zone and makes a fresh high in the RSI.

Included my novice attempt. Need help from experts on

  1. how to get the filter to meet any of the above 3 conditions
  2. populate columns in exploration with missing data/help
/*
Requirement:

Exploration result includes 3 conditions
1) The stocks go above RSI 70 on the monthly charts for the first time in its lifetime.
2) The stocks go above RSI 70 on the monthly charts after a gap of 2 years.
3) The stock is already in the RSI > 70 Zone and makes a fresh high in the RSI.
*/
_SECTION_BEGIN("RSI");

nOverBought = 70;
nOverSold = 40;
nPeriodRSI = Param( "RSI period", 13, 2, 30, 1 );;

mRSI = TimeFrameExpand(RSI (nPeriodRSI),inMonthly);
Buy = mRSI > nOverBought;
Sell = mRSI < nOverSold;
Filter = Buy OR Sell;   //<help>

// Exploration //
AddColumn(IIf(Buy,Close,Null)," Buy ", 6.2,1.2,colorGreen);
AddColumn(IIf(Sell,Close,Null)," Sell ",6.2,1.2,colorOrange);
AddColumn( mRSI, "RSI Monthly ( " + nPeriodRSI + ") ");
AddColumn( nOverBought, "OverBought", 1.0);
AddColumn( nOverSold, "OverSold", 1.0);
AddColumn( 0, "Prev OverBought (months ago)",1.0 ); //<help>Reached OverBought Area after a Gap of (months/years)
AddColumn(0, "Prev OverSold (months ago)",1.0 ); //<help>
AddTextColumn("Condition 1/2/3","Criteria"); //<help> which condition met 1 2 or 3

// Chart //
PlotOHLC( mRSI, mRSI, 50, mRSI, "", IIf(mRSI > 70, colorRed, colorGreen ), styleCloud | styleClipMinMax, 30, 70 );
Plot( mRSI, "RSI( " + nPeriodRSI + ") ", colorWhite );
_SECTION_END();

Dear All,
Please let me know if the above requirement is not clear or need further clarification.
Thanks
Bobby

@_Bobby that is a pretty limited effort on your part. Start slowly by building your code one piece at a time. Then debug what you have created and when you have your first piece correct then move on to the next part.

For example you are not properly calculating the monthly RSI. You have not told us what time frame you are running your analysis in (monthly, weekly, daily, 15 minute bars, etc)? But since you are interested in only Monthly readings why not use Monthly in your AA settings? Then you would not need the TimeFrame functions . Similarly the other calculations would be simple if you are using monthly analysis.

Otherwise learn how to use the functions correctly.

So for example

TimeFrameSet( inMonthly ); // switch to Monthly time frame
R = RSI(13);
TimeFrameRestore(); //restore time frame to original 

MonthlyRSI = TimeFrameExpand( R, inMonthly, expandLast );

Good luck.

3 Likes

Thanks @portfoliobuilder for your help and guidance.

I am new to AFL hence knowledge is limited.
Please guide how to calculate if RSI has crossed 70 1st time in its lifetime?

Best
Bobby

@_Bobby maybe try something like this,

Condition 		= Cross( MonthlyRSI, 70 ); // your indicator;
CountConditions = Cum( Condition );
FirstCross		= CountConditions == 1;

Had the opportunity to check the code above and it could be

Condition 		= Cross( MonthlyRSI, 70 ); // your indicator;
CountConditions = Cum( Condition );
FirstCross		= CountConditions == 1 AND Ref( CountConditions, -1 ) == 0;

This requires a "cross" of the RSI from below to above the threshold of 70. If your first RSI reading is already above 70 this code wouldn't pick that up.

1 Like

Or simply use expandPoint instead of expandLast.

TimeFrameSet( inMonthly ); // switch to Monthly time frame
R = RSI(13);
TimeFrameRestore(); //restore time frame to original 
MonthlyRSI = TimeFrameExpand( R, inMonthly, expandPoint );

Condition 		= Cross( MonthlyRSI, 70 ); // your indicator;
CountConditions = Cum( Condition );
FirstCross		= MonthlyRSI AND CountConditions == 1;

Filter = FirstCross;
2 Likes

As for FirstCross line I actually meant:

//.... code of before above
FirstCross		= Condition AND CountConditions == 1;

(Does not change the result though because MonthlyRSI is just a single non-Null (RSI-)value per each month at the end of each month. So it would act as impulse signal too because of being > 0 at desired position in the array.)

1 Like

@portfoliobuilder Thanks for your time and help. It works as expected.

@fxshrat Thanks for your time and help. It works as expected.
Any advice on how do I achieve if the stock has made a fresh high since the first cross.

Version(6.38);
_SECTION_BEGIN("RSI");

nOverBought = 70;
nOverSold = 40;
nPeriodRSI = Param( "RSI period", 14, 2, 30, 1 );;

TimeFrameSet( inMonthly ); // switch to Monthly time frame
R = RSI(nPeriodRSI);
TimeFrameRestore(); //restore time frame to original 
MonthlyRSI = TimeFrameExpand( R, inMonthly, expandPoint );

Condition 		= Cross( MonthlyRSI, 70 ); // your indicator;
CountConditions = Cum( Condition );
FirstCross		= Condition AND CountConditions == 1;
Filter = FirstCross;

// Exploration //
AddColumn( MonthlyRSI, "RSI Monthly ( " + nPeriodRSI + ") ");
AddColumn(Close, "Close",1.0 );
AddColumn(FirstCross, "IsFirstCross",1.0 );
AddColumn( nOverBought, "OverBought", 1.0);
AddColumn( nOverSold, "OverSold", 1.0);
AddColumn(0, "HasMadeFreshHighSinceSinceFirstRsiOver70",1.0 );
AddColumn( 0, "Prev OverBought (months ago)",1.0 ); 
AddColumn(0, "Prev OverSold (months ago)",1.0 );

_SECTION_END();

What is a "fresh high since..."?
There might be "Fresh High (People) of Bel-Air" but in an array there are many high elements. In short your description is vague to say the least.

Apparently you mean that you look for high value(s) being higher than the high at first cross (?)
That being said take look at HighestSince() function and then compare it against the high of the first cross via > operator (high at first cross ValueWhen(FirstCross,H) ).

Note: in addition you would need to change the Filter then.

1 Like

FWIW: He might meant new high since. @_Bobby that is precisely why you should follow this advice: How to ask a good question

1 Like

@bobby I am guessing this goes back to the original post (and it doesn't look like you are trying to code anything but waiting for us to code everything for you).

Maybe something like this,

HigherRSI = MonthlyRSI > Ref( MonthlyRSI, -1) AND Ref( MonthlyRSI, -1) > 70;
1 Like

@fxshrat Thanks once again for your help. I understand your point about the vague requirement. I'll try and improve that moving forward. Once again much appreciate your help.
Best
Bobby

@Tomasz Thanks for your time and suggestion :slightly_smiling_face:. Being new to AFL I am on a learning curve. I will take your feedback on board and improve.

I would like to take this opportunity to thank you for the amazing software :ok_hand:. Also, thank you for the forum with a pool of amazing experts :star: who spend their valuable time/effort to support/help the users by sharing their expertise.

Much appreciated your's and all the expert's help/suggestions.
Best
Bobby

@portfoliobuilder Thanks once again for your time/help. You are right I didn't try to code the #3 as my knowledge is limited hence asking for help to get the pointers.
Since I am on a learning curve so please bear with me. I can assure you that I have no intention of getting everything coded by experts like you. I would like to try lots of ideas with this amazing software so just looking for some pointers where I am getting stuck.

Once again much appreciate your help. :ok_hand:
Best
Bobby

1 Like

@_Bobby

I already told you to take whatever "fresh" thing and then compare it against value at first cross (using ValueWhen).

Note: RSI (or whatever) might go lower first so using Ref(.., -1) won't catch your so called "fresh" high since first cross if new higher RSI comes later (after more than one bar after first cross). That's why ValueWhen.


TimeFrameSet( inMonthly ); // switch to Monthly time frame
R = RSI();
TimeFrameRestore(); //restore time frame to original 
// Monthly RSI
mRSI = TimeFrameExpand( R, inMonthly, expandPoint );

Condition 		= Cross(mRSI, 70 );
CountConditions = Cum( Condition );
FirstCross		= Condition AND CountConditions == 1;

// RSI at first cross
first_rsi = ValueWhen(FirstCross, mRSI);
//New higher monthly RSI since first cross
is_new_high = mRSI > first_rsi;// or use Cross(mRSI, first_rsi);

Plot(ValueWhen(!IsNull(mRSI), mRSI), "mRSI", colorRed );
PlotShapes( FirstCross * shapeUpArrow, colorGreen, 0, y = mRSI );
PlotShapes( is_new_high * shapeUpArrow, colorYellow, 0, y );

might go lower first

14

1 Like

@portfoliobuilder/@fxshrat Thanks for your expertise and the code snippets.
I accept my definition for #3 of fresh high is not clear. I'll try and be more clear on my requirement in the future.

Both the solutions work as expected.

Following is the complete exploration code with a screenshot.
Much appreciated your help.
Best
Bobby

/*
Requirement:
Exploration result includes 2 conditions
1) The stocks go above RSI 70 on the monthly charts for the first time in its lifetime.
2) The stock is already in the RSI > 70 Zone and makes a fresh high in the RSI.
*/
Version(6.38);
_SECTION_BEGIN("RSI");

nOverBought = 70;
nOverSold = 40;
nPeriodRSI = Param( "RSI period", 14, 2, 30, 1 );;

TimeFrameSet( inMonthly ); // switch to Monthly time frame
R = RSI(nPeriodRSI);
TimeFrameRestore(); //restore time frame to original 
MonthlyRSI = TimeFrameExpand( R, inMonthly, expandPoint );
Condition 		= Cross( MonthlyRSI, nOverBought ); // your indicator;
CountConditions = Cum( Condition );
isFirstCrossRsi		= Condition AND CountConditions == 1;
HigherMonthlyRSI = MonthlyRSI > Ref( MonthlyRSI, -1) AND Ref( MonthlyRSI, -1) > nOverBought; //FreshHighMonthlyRsiWhenStockAlreadyOverboughtZone
// RSI at first cross
firstCrossRsiValue = ValueWhen(isFirstCrossRsi, MonthlyRSI);
//New higher monthly RSI since first cross
is_new_high_rsi = MonthlyRSI > firstCrossRsiValue;// or use Cross(MonthlyRSI, firstCrossRsiValue);
Filter = firstCrossRsiValue OR is_new_high_rsi;

// Exploration //
AddColumn(Close, "Close",1.0 );
AddColumn(isFirstCrossRsi, "IsFirstCrossRsi70",1.0 );
AddColumn(MonthlyRSI, "MonthlyRSI",1.0 );
AddColumn(firstCrossRsiValue, "firstCrossRsiValue",1.0 );
AddColumn(is_new_high_rsi, "is_new_high_rsi",1.0 );
AddColumn( HigherMonthlyRSI, "HigherRSI", 1.0); //FreshHighMonthlyRsiWhenStockAlreadyOverboughtZone
AddColumn( nOverBought, "OverBought Level", 1.0);
AddColumn( nOverSold, "OverSold Level", 1.0);
_SECTION_END();

image

No, they are not the same.
As I said before using Ref() line will fail to mark new high in the pictured example I posted above.

1 Like

@fxshrat Thanks for your solution, much appreciated. I tried both the suggestions and understand the difference now. I think the ref solution was due to my vague description on the requirement. Since I am on a learning curve both suggestions helped me a lot.