Relative Performance watchlist, separate those symbols on top of each other

The code below lets you select one of your own watchlists if you type their names in ParamList.
When there are many symbols, some tend to print on top of each other. Using a smaller label font size helps separate them, but sometimes some are still on top of each other.
I have used modulus to randomly shift every nth label to the right. As you move the "Shift nth label" slider, some of the labels shift to the right and you can often identify each line plotted.
This works but is not elegant - perhaps someone can write some code so that every symbol that would have printed on top of another will instead print to the right?

/// Relative Performance.afl by AmiBroker.com 
/// to be found in Charts window -> Basic Charts

_SECTION_BEGIN("watchlist");
WatchlistName = ParamList("WatchList", "0 Portfolio,1 Buys,2 Watch,3 Supertrenders,5 Exchange Rates,6 Indices World,10 Metals Precious,22 Cryptos,23,24");
category = categoryWatchlist;
listnum = CategoryFind( WatchListName, category );
TickerList = CategoryGetSymbols( category, listnum);
_SECTION_END();

_SECTION_BEGIN("FontSize");
fontsize = Param("Label font size", 7, 4, 10, 1 );
_SECTION_END();

_SECTION_BEGIN("RelativePerformance");
fvb = Status( "firstvisiblebar" );

for( i = 0; ( symbol = StrExtract( Name() + "," + TickerList, i ) ) != ""; i++ )
{
    fc = Foreign( symbol, "C" );
    if( ! IsNull( fc[ 0 ] ) )
    {
        relP = 100 * ( fc - fc[ fvb ] ) / fc[ fvb ];
        Plot( relP , symbol, color = colorOrange + ( ( 2 * i ) % 15 ), styleLine );

        x = LastValue( BarIndex() ) + 1;
        y = LastValue( relP );

		//Several labels overlap. Use modulus to shift every nth label to the right.
		n = Param("Shift nth label right", 2, 2, 9, 1 );
	    PlotTextSetFont( symbol, "Arial", fontsize, IIf( i % n == 0, x, x+3), y, 		 	GetChartBkColor(), color, -fontsize/2 );
    }
}

PlotGrid( 0, colorDarkGrey );
_N( Title = "{{NAME}} - Relative Performance [%]: {{VALUES}}" );
_SECTION_END();

1 Like

You may want to explore this idea further:

Animation

/// Relative Performance.afl by AmiBroker.com
/// to be found in Charts window -> Basic Charts

_SECTION_BEGIN( "watchlist" );
WatchlistName = ParamList( "WatchList", "1 Buys,2 Watch,3 Supertrenders,5 Exchange Rates,6 Indices World,10 Metals Precious,22 Cryptos,23,24" );
category = categoryWatchlist;
listnum = CategoryFind( WatchListName, category );
TickerList = CategoryGetSymbols( category, listnum );
_SECTION_END();

_SECTION_BEGIN( "FontSize" );
fontsize = Param( "Label font size", 7, 4, 10, 1 );
_SECTION_END();

_SECTION_BEGIN( "RelativePerformance" );
fvb = Status( "firstvisiblebar" );

PlotGrid( 0, colorDarkGrey );
_SECTION_END();
Title = "";

mx = Matrix( StrCount( TickerList, "," ) + 1, 3 );

for( i = 0; ( symbol = StrExtract( TickerList, i ) ) != ""; i++ )
{
    fc = Foreign( symbol, "C" );

    if( ! IsNull( fc[ 0 ] ) )
    {
        relP = 100 * ( fc - fc[ fvb ] ) / fc[ fvb ];
        color = colorLightOrange + ( ( 2 * i ) % 15 );
        Plot( relP , "", color, styleLine | styleNoLabel );
        mx[i][0] = i; // index
        mx[i][1] = LastValue( relP ); // performance
        mx[i][2] = color; // color
    }
}

// build buttons
mx = MxSortRows( mx, False, 1 );
x0 = Status( "pxchartleft" );
y0 = 20;
btnWidth = 150;
btnHeight = 25;
x = x0;

for( i = 0; i < StrCount( TickerList, "," ) + 1; i++ )
{
    performance = Nz( mx[i][1] );

    if( NOT performance ) continue;

    symbol = StrExtract( TickerList, mx[i][0] );
    y = y0 + i * btnHeight;
    GuiButton( StrFormat( "%s  %.2f%%", symbol, performance ), i + 1, x, y, btnWidth, btnHeight, notifyMouseEnter );
}

// highlight line with mouse over its respective button
for( n = 0; id = GuiGetEvent( n, 0 ); n++ )
{
    event = GuiGetEvent( n, 1 );

    if( event == notifyMouseEnter )
    {
        i = id - 1;
        symbol = StrExtract( TickerList, mx[i][0] );
        fc = Foreign( symbol, "C" );
        relP = 100 * ( fc - fc[ fvb ] ) / fc[ fvb ];
        color = mx[i][2];
        Plot( relP , "" , color, styleLine, Null, Null, 0, 1, 3 );
    }
}


8 Likes

Thank you bysoaa,
You have demonstrated an elegant solution, both conceptually and with your afl code.

Can the line be given a Name Label?. Thanks

Sorry, but I do not understand your question. Which line are you referring to?

With my original question, if you used the symbol's name rather than the symbol, it would be even more cluttered.

With bysoaa's code, the symbol's names are in the box on the top left.

@Batupermata, one slight "visual" improvement to better distinguish the lines is to "color" the buttons (like I showed in this screenshot).

Another idea, using OLE, is to "link" an associated chart that changes depending on the current selection like did @Milosz in that same thread.

With AmiBroker, your creativity is the limit!

4 Likes

I totally agree Amibroker makes creativity without limits :heart_eyes:, but not everyone has good programming skills. I am a reliable type of trader, but not a reliable programmer :joy:

I am also sure that in this forum there are many reliable AFL Programmers, but not necessarily a reliable Trader. How as a Trader wants to make a good and suitable Afl according to the user's taste, I hope this AB forum is kind enough to help or there is a service to make a reasonable AFL :heart_eyes:. Thanks

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