John F. Ehlers Rocket RSI

Greetings All,

Below is a piece of code that I have translated to AFL from this month's TASC issue. If interested, may I request you to kindly validate (if required) modify it for better results.

Thank you

//Based on TASC May 2018 RocketRSI EasyLanguage code
//All Rights Resevered by John F. Ehlers (C) 2005-2018
//AFL coded by Lennon May 2018

_SECTION_BEGIN( "Rocket RSI" );
	 LenRSI = Param( "RSI Length", 10, 10, 89, 1 );
	 LenSmth = Param( "Smooth Length", 8, 8, 89, 1 );
	 OBSGrid = Param( "Grid Location", 3, 2, 4, 0.5 );
	 ChrtStyle = ParamToggle( "Chart Style", "Gradient|Cloud", 1 );
	 
	 a1 = exp( -1.414 * 3.14159 / ( LenSmth ) );
	 b1 = 2 * a1 * Cos( 1.414 * 180 / ( LenSmth ) );
	 c2 = b1;
	 c3 = -a1 * a1;
	 c1 = 1 - c2 - c3;
	
	 Mom[ 0 ] = 0;
	 Filt[ 0 ] = 0;
	 CU[ 0 ] = 0;
	 CD[ 0 ] = 0;
	 MyRSI[ 0 ] = 0;
	 RocketRSI[ 0 ] = 0;
	 for( i = BarCount - 1; i >= LenRSI; i-- )
	 {
		 //Create half dominant cycle momentum
		 Mom[ i ] = C[ i ] - C[ i - LenRSI ];
		 
		 //SuperSmoother Filter
		 Filt[ i ] = c1 * ( Mom[ i ] + Mom[ i - 1 ] ) / 2 + c2 * Nz( Filt[ i - 1 ] ) + c3 * Nz( Filt[ i - 2 ] );
		 
		 //Accumulate "Closes Up" and "Closes Down"
		 if( Filt[ i - 1 ] - Filt[ i ] > 0 ) CU[ i ] = CU[ i - 1 ] + Filt[ i - 1 ] - Filt[ i ];
		 if( Filt[ i - 1 ] - Filt[ i ] < 0 ) CD[ i ] = CD[ i - 1 ] + Filt[ i ] - Filt[ i - 1 ];
		 if( CU[ i ] + CD[ i ] != 0 ) MyRSI = ( CU[ i ] - CD[ i ] ) / ( CU[ i ] + CD[ i ] );
		 
		 MyRSI[ i ] = Min( Max( MyRSI[ i ], -0.999 ), 0.999 );
		 RocketRSI[ i ] = 0.5 * log( ( 1 + MyRSI[ i ] ) / ( 1 - MyRSI[ i ] ) );
	 }
	 
	 Title = "Rocket RSI:  " + RocketRSI;
	 
	 BkClr = ParamColor( "Chart Back Color", colorBlack );
	 SetChartBkColor( BkClr );
	 Plot( 100, "Ribbon", BkClr, styleOwnScale | styleArea | styleNoLabel, 0, 100, 100, -5 );
	 
	 PlotGrid( OBSGrid, ParamColor( "OverBought Grid Color", colorRed ), 10 ); //OverBought
	 PlotGrid( -OBSGrid, ParamColor( "OverSold Grid Color", colorGreen ), 10 ); //OverSold
	 
	 if( ChrtStyle )
	 {
		 Plot( RocketRSI, "RocketRSI", ParamColor( "RocketRsiClr", colorWhite ), styleLine );
		 PlotOHLC( RocketRSI, RocketRSI, OBSGrid, RocketRSI, "", IIf( RocketRSI > 3, colorRed, colorGreen ), styleCloud | styleClipMinMax | styleNoLabel, -OBSGrid, OBSGrid );
	 }
	 else
	 {
		 SetGradientFill( colorRed, colorGreen, 0, GetChartBkColor() );
		 Plot( RocketRSI, "RocketRSI", ParamColor( "RocketRsiClr", colorLightOrange ), styleGradient | styleNoLabel );
	 }
_SECTION_END();

P.S.
Happy Anniversary to the forum. It is such a great joy to learn new things here with this beautiful community. Many thanks again !

2 Likes

Thanks but I've already written the code for RocketRSI and it is loop-less (fast) and available on Traders site: http://traders.com/Documentation/FEEDbk_docs/2018/05/TradersTips.html#item5 (and in AB members zone as well http://www.amibroker.com/members/traders/04-2018.html).

6 Likes

@Lennon thanks for the effort!

I'm afraid, that if it has been already coded by Tomasz, you won't beat that :wink: For this reason I'm not going to analyse your whole code, but I've noticed one important thing that you (and other users) should take into account when writting next codes. You initialize arrays in a wrong way. Don't initialize arrays like that:

Int

I quote Tomasz explanation from the first thread below:

Your code is incorrect. You should not write to single element of uninitialized array.

NW[0] = 0; // wrong, if array is never initialized before

If you do this, you will get an array with first element (index 0) initialized but all the other will hold just random "garbage" (uninitialized RAM content). Of course it does not matter much if you simply ignore/ not use uninitialized content.

Correct usage is to write

NW = 0; // this initializes variable correctly, i.e. ALL bars, not one.


Besides it's good to know, that there are more AmiBroker Stocks & Commodities Traders' Tips codes available, because on the main member's site http://amibroker.com/members/ the last code is from June 2017. Here you can find all available codes - also the newer ones: http://www.amibroker.com/members/traders/

Regards

3 Likes

@Milosz great post, but one minor note, technically, you can initialize just first element, if you later write remaining ones in the loop, like this:

x[ 0 ] = 0; // initialize first element
for( i = 1; i < BarCount; i++ )
{ 
   x[ i ] = x[ i - 1 ] + 1; // all remaining elements are written inside loop
}

It is worth noting though, that doing so isn't any faster in AFL than just doing x = 0; in first line.

4 Likes

So @Tomasz if I understand this correctly, you are saying that initializing the first element of the array by writing x[ 0 ] = 0; then specifying the other elements using a loop - is correct, but, ideally x = 0; also holds true in the first place as well.

Anybody like me who has limited programming skills (High School C, C++ to be precise), it is a bit odd to imagine a variable as an array and vice-versa. But Understanding how AFL works and this image (Quick AFL Facts) conceptualizes your genius.

P.S. In the code, first tried to write without the loops but was unable to, since, I was not aware of IIR().

David, you are still lucky, because at that stage I was learning coding in Basic and later in Turbo Pascal which are definitely far from AFL and C/C++ :wink:

When it comes to this subject (variables, scalars, arrays) these posts are also definitely worth reading:

2 Likes

Yes that is correct.

1 Like