# RRG for Amibroker

For what it is worth, mathematical formula is NOT patent-able therefore indicator in the meaning of mathematical expression can't be "proprietary". Anyone is free to implement ANY mathematical formula in ANY language of their choice.

The program or formula (specific written expression of algorithm in given programming language) itself is a subject of copyright, but underlying mathematical formula isn't.

For this reason, anyone is free to write original formula by him/herself to implement anything using mathematical expressions in given programming language.

3 Likes

@DeAmit, Welcome to the forum.

You really need to get your "Verified Badge". That shows that you have purchased AmiBroker. Just search for "Verified Badge" and follow the instructions. Only Verified owners are supposed to post questions in the forum.

Also, search for "How to use this site". It will cover many additional aspects of how to get helpful responses to your query. Things like Posting your code (using Code Blocks </>).

When starting out with AmiBroker AFL, it can take a while to get a handle on the programming using Arrays. If you are not a programmer it can take even longer. Once you do "get it", it is extremely powerful.

So, Get Verified and then Post your Code. Then you should get more activity on your question.

1 Like

Thanks for your suggesting @fxshrat! I have just finished with my attempt.

9 Likes

@ danielkhanhnguyen
Cám ơn bác trước

The first, you need understand about 'normal distribution', refer on wiki at Normal distribution - Wikipedia
The second, read carefully about RRG Charts in order to gain knowledge about calculate: RS Ratio and RS Momentum at link Relative Rotation Graphs (RRG Charts) [ChartSchool]
Moreover, using the gfx* functions on Amibroker, other functions: CategoryGetSymbols, AddToComposite

2 Likes

hi, may i ask how to make the center point of the rrgd chart dynamic ?

Discovered online version at some website, got AFL to finally work. I then added some GFX text and parameters for adjusting watchlist and time periods. Everything is good for a couple days and then it does not work/display. Appears to have ticker symbols stacking members of watchlist at the upper left part of the chart. Maybe it still work but is printing 3 letter symbols in an approximate pixel area of 15 x 30 pixels. Not sure if I should post AFL code since others are not, suggestions for assitance?

1 Like

RS11= Param("period 1 short", 8,2,50,1);
RS22= Param("period 2 long",21,3,180,1);
tbar = Param( "Trailing Bar", 5, 1, 100, 1 );
_N( base = ParamStr( "Base Symbol", "SPY" ) );

_SECTION_BEGIN("Watch List");
//////////////////////////////////////////////
// Params -
// first is Select Watch List
// House keeping first
// Build String containing
// Watchlist Names
///////////////////////////////////////////////

String = "" ;
x = 0; //count WatchList
//pRemoveListNames = ParamToggle("Remove List xx - WL Names","No|Yes",0);
do{
WList = CategoryGetName( categoryWatchlist, x );
if (WList != "" ){
// if (!((pRemoveListNames) & (StrFind(WList,"List")==1))){
String = String + WList +",";
// }
}
x++;
} while(WList !="");

_N(pWatchList = ParamList ( "Watch List", String ));
_SECTION_END();

_SECTION_BEGIN( "RRG rev 4" );

color1 = ParamColor("Symbol 1:", colorRed);
color2 = ParamColor("Symbol 2:", colorOrange);
color3 = ParamColor("Symbol 3:", colorBrightGreen);
color4 = ParamColor("Symbol 4:", colorDarkGreen);
color5 = ParamColor("Symbol 5:", colorBlue);
color6 = ParamColor("Symbol 6:", colorCustom10);
color7 = ParamColor("Symbol 7:", colorPlum);
color8 = ParamColor("Symbol 8:", colorBrown);
color9 = ParamColor("Symbol 9:", colorViolet);
color10 = ParamColor("Symbol 10:", colorCustom12);
color11 = ParamColor("Symbol 11:", colorPink);
color12 = ParamColor("Symbol 12:", colorIndigo);
color13 = ParamColor("Symbol 13:", colorDarkGrey);
color14 = ParamColor("Symbol 14:", colorTeal);
color15 = ParamColor("Symbol 15:", colorTan);
color16 = ParamColor("Symbol 16:", colorCustom16);
color17 = ParamColor("Symbol 17:", colorBrightGreen);
color18 = ParamColor("Symbol 18:", colorDarkBlue);
color19 = ParamColor("Symbol 19:", colorDarkOliveGreen);
color20 = ParamColor("Symbol 20:", colorYellow);

list = Name()+","+pWatchList;

EnableTextOutput( False );
GfxSetOverlayMode( 2 );

pxl = Status( "pxchartleft" );
pxr = Status( "pxchartright" );
pxt = Status( "pxcharttop" );
pxb = Status( "pxchartbottom" );
pxw = ( pxr - pxl ) / 2;
pxh = ( pxb - pxt ) / 2;
xm = pxl + pxw;
ym = pxt + pxh;

GfxMoveTo( pxl, ym );
GfxLineTo( pxr, ym );
GfxMoveTo( xm, pxt );
GfxLineTo( xm, pxb );
GfxSelectSolidBrush(ColorRGB(102,255,102));
GfxRectangle( xm, ym, pxr, pxt );
GfxSelectSolidBrush(ColorRGB(255,101,102));
GfxRectangle( xm, ym, pxl, pxb );
GfxSelectSolidBrush(ColorRGB(255,255,204));
GfxRectangle( xm, ym, pxr, pxb );
GfxSelectSolidBrush(ColorRGB(135,206,235));
GfxRectangle( xm, ym, pxl, pxt );

/////// Hash Marks Horizontal and then Vertical
GfxSelectPen(colorBlack,1);
hashHzCount = 34;
widthHzHash = pxw/17;
for(j=0; (j <hashHzCount);j++)
{
GfxMoveTo(pxl+(widthHzHashj), pxh-5);
GfxLineTo(pxl+(widthHzHash
j), pxh+15);
}

hashVCount = 22;
widthVHash = pxh/11;
for(k=0; (k <hashVCount);k++)
{
GfxMoveTo(pxw-5, pxt + widthVHashk);
GfxLineTo(pxw +15, pxt + widthVHash
k);
}
/////////////////////////////////////////////////////////////

GfxSelectFont("Arial", Status("pxheight")/60 );
GfxSetTextColor( ParamColor( "Text Color", colorBlack ) );
GfxSetBkMode(0); // transparent
//GfxTextOut("O B" ,pxw-12,pxt+55);
//GfxTextOut("O S" ,pxw-12,pxb-55);
// On screen descriptions
//GfxTextOut("Periods selected ='s "+tbar +" for "+pWatchlist +" WL vs " + base ,pxl+850,pxb-65);
//GfxTextOut( "Hz hash ='s price/base ratio" + " Vertical hash ='s 1pd /9pd momo of \$ ratio",pxl+850,pxb-25);
//////////////////
GfxSetBkColor(colorPaleGreen);
GfxSetBkColor(colorPink);
GfxTextOut( "DOG", pxl+15, pxb-55 ); // Lagging
GfxSetBkColor(colorLightYellow);
GfxTextOut( "FADING ", pxr-100, pxb-65); // Weakening
GfxSetBkColor(colorLightBlue);
GfxTextOut( "Improving", pxl+15, pxt+60 ); // Improving
GfxSelectFont("", Status("pxheight")/90 );

//create data for arrays
function getrs ( sc, t )
{
bc = Foreign( base, "C" );
sbr = sc / bc;

``````rs1 = EMA( sbr, RS11 );
rs2 = EMA( sbr, RS22 );
rs = 100 * ( ( rs1 - rs2 ) / rs2 + 1 );

rm1 = MA( rs, 1 );
rm2 = MA( rs, 9 );
rm = 100 * ( ( rm1 - rm2 ) / rm2 + 1 );

return IIf( t, rs , rm ) - 100;
``````

}
// drawing function for arrays
function drawpos ( x, y, sym, text )
{
rsl = VarGet( "rsl" );
rsh = VarGet( "rsh" );
rml = VarGet( "rml" );
rmh = VarGet( "rmh" );

``````xx = pxl + pxw + x * ( pxw / ( Max( rsh, -rsl ) * 1.10 ) );
yy = pxb - pxh - y * ( pxh / ( Max( rmh, -rml ) * 1.10 ) );

xp = Nz( VarGet( "xp" + sym ), xx );
yp = Nz( VarGet( "yp" + sym ), yy );

VarSet( "xp" + sym, xx );
VarSet( "yp" + sym, yy );

GfxMoveTo( xp, yp );
GfxLineTo( xx, yy );

GfxCircle( xx, yy, IIf( text == "", 2, 4 ) );

if ( text != "" ) GfxTextOut( sym, xx + 6 , yy - 3 );
``````

}
// get UnSorted Watch list
_N(UnSortlist = CategoryGetSymbols( categoryWatchlist, CategoryFind(pWatchList, categoryWatchlist )));
//establish "tbar param" arrays of RS and RM
for ( i = 0; ( sym = StrExtract( UnSortlist, i ) ) != ""; i++ )
{
SetForeign( sym );

``````rs = getrs( C, 1 );
rm = getrs( C, 0 );

for ( ii = BarCount - tbar; ii < BarCount; ii++ )
{
rs_ = rs[ ii ];
rm_ = rm[ ii ];

rsh = Nz( VarGet( "rsh" ), rs_ );
if ( rs_ >= rsh )
VarSet( "rsh", rs_ );

rsl = Nz( VarGet( "rsl" ), rs_ );
if ( rs_ <= rsl )
VarSet( "rsl", rs_ );

rmh = Nz( VarGet( "rmh" ), rm_ );
if ( rm_ >= rmh )
VarSet( "rmh", rm_ );

rml = Nz( VarGet( "rml" ), rm_ );
if ( rm_ <= rml )
VarSet( "rml", rm_ );
}

RestorePriceArrays( True );
``````

}

for ( i = 0; ( sym = StrExtract( UnSortlist, i ) ) != ""; i++ )
{
SetForeign( sym );

``````rs = getrs( C, 1 );
rm = getrs( C, 0 );
``````

// make a new color for each symbol iterated
GfxSelectPen(color1+i,1,1);
GfxSelectSolidBrush(color1+i);
////////////////////////////////////

// Drawing function employed with arrays

``````for ( ii = BarCount - tbar; ii < BarCount; ii++ )
{
drawpos( rs[ ii ], rm[ ii ], sym, WriteIf( ii == BarCount - 1, sym, "" ) );
}

RestorePriceArrays( True );
``````

}

_SECTION_END();

1 Like

Your post is a mess. Some of the code is in 'Code Blocks' while some are not.

Only users with "Verified Badge" are allowed to post on this forum.

Programming skills are adequate, but not professionally trained. Amibroker user of over 15 years, even attended the Las Vegas Convention and met Tomasz. If there is generally accepted principles relative to program formats, then I am unaware of them.

Honestly, creating some "for" loops, commenting my code and some GFX is pretty good for my level of programming skills.

As I commented previously, the code I uploaded worked. Now it does not and I am seeking a means or process to remediate previously function code.

1 Like

Did you purchase AmiBroker?

2 Likes

Don't know when I need to update, but running 6.49.1. Assuming license is current, I have renewed in the past.

Functionality of AFL has returned, life is good

You have a lot of code there, and as @TrendSurfer pointed out it's not all within code blocks and it's also poorly formatted. As @Tomasz has explained many times, one of the best ways to get help is to make it as easy as possible for others to help you. An excellent first step would be to create the simplest version of the code that still exhibits the problem. You can also use the "Prettify" feature in the AFL Editor to get some consistent indentation. After you've done that, post the updated code here inside code tags.

The next step would be to see if you can find a way to make the issue occur more often than "after a couple of days", because it's a good bet that no one else will want to wait that long to see if they can even reproduce the issue, much less offer suggestions for improvement.

2 Likes

When posting the formula, please make sure that you use Code Tags (using `</>` code button) as explained here: How to use this site.

Code tags are required so formulas can be properly displayed and copied without errors.