Individual Report Charts - Help please

Hello dear AmiBroker friends,

I’ve been experimenting with the report charts and unfortunately didn’t create a backup beforehand — a mistake I won’t make again.

Could you please provide me with the original AmiBroker code for the two highlighted charts, namely Portfolio Equity and Underwater Equity?

Thank you very much!

I think it turned out quite well, and I’ll admit that I had some help from artificial intelligence.

I’m aware that the use of AI is often discouraged in this forum, mainly because it can limit a deeper understanding of the underlying code. That’s a fair point. However, I’m still learning, and with the help of AI I’m making significantly faster progress than I used to.

I would really appreciate your support, and in return I’m happy to share my own developments with you.

Here is a profit table that evaluates the results of the trading system based on the S&P 500, including the performance difference. I hope it’s useful and that I can contribute something of value to the forum as well.

EnableTextOutput( 3 ); // enable HTML output into report (Version 5.84 or higher!)

eq = C;

// SPX Buy & Hold Kurse laden (mit Fallbacks)
spxTicker = "$SPX";
spxClose  = Foreign( spxTicker, "C" );

if( LastValue( spxClose ) == 0 OR IsNull( LastValue( spxClose ) ) )
    spxClose = Foreign( "^GSPC", "C" );

if( LastValue( spxClose ) == 0 OR IsNull( LastValue( spxClose ) ) )
    spxClose = Foreign( "SPY", "C" );

yr = Year();
mo = Month();

YearChange = yr != Ref( yr, 1 );
MonChange = mo != Ref( mo, 1 );

FirstYr = 0;
LastYr = 0;

startbar = 0;

////////////////////////////
// SKIP non-trading bars
////////////////////////////

for ( i = 0; i < BarCount; i++ )
{
    if ( eq[ i ] )
    {
        startbar = i;
        break;
    }
}

////////////////////////////
// collect yearly / monthly changes in equity
// into dynamic variables
////////////////////////////

LastYrValue    = eq[ startbar ];
LastMoValue    = eq[ startbar ];
LastYrValueSPX = spxClose[ startbar ];

MaxYrProfit = MinYrProfit = 0;
MaxMoProfit = MinMoProfit = 0;

// Gesamt-Compound-Return vorbereiten
TotalSysMultiplier = 1.0;
TotalSpxMultiplier = 1.0;
YearCount          = 0;

for ( i = startbar + 1; i < BarCount; i++ )
{
    if ( YearChange[ i ] || i == BarCount - 1 )
    {
        Chg = 100 * ( -1 + eq[ i ] / LastYrValue );
        VarSet( "ChgYear" + yr[ i ], Chg );

        // SPX-Jahresrendite
        if( LastYrValueSPX > 0 AND spxClose[ i ] > 0 )
        {
            ChgSPX = 100 * ( -1 + spxClose[ i ] / LastYrValueSPX );
            VarSet( "ChgYearSPX" + yr[ i ], ChgSPX );

            TotalSpxMultiplier = TotalSpxMultiplier * ( 1 + ChgSPX/100 );
        }

        TotalSysMultiplier = TotalSysMultiplier * ( 1 + Chg/100 );
        YearCount++;

        MaxYrProfit = Max( MaxYrProfit, Chg );
        MinYrProfit = Min( MinYrProfit, Chg );

        if ( FirstYr == 0 )
            FirstYr = yr[ i ];

        LastYr = yr[ i ];

        LastYrValue    = eq[ i ];
        LastYrValueSPX = spxClose[ i ];
    }

    if ( MonChange [ i ] || i == BarCount - 1 )
    {
        mon = mo[ i ];

        Chg = 100 * ( -1 + eq[ i ] / LastMoValue );

        VarSet( "ChgMon" + yr[ i ] + "_" + mon, Chg );
        VarSet( "SumChgMon" + mon, Chg + Nz( VarGet( "SumChgMon" + mon ) ) );
        VarSet( "SumMon" + mon, 1 + Nz( VarGet( "SumMon" + mon ) ) );

        MaxMoProfit = Max( MaxMoProfit, Chg );
        MinMoProfit = Min( MinMoProfit, Chg );

        LastMoValue = eq[ i ];
    }
}

MonthNames = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec";


function GenProfitTableHTML( )
{
    printf( "<table border='1' bordercolor='#000000' cellspacing='0' cellpadding='3'style='border-collapse:collapse;'>\n" );

    printf( "<tr bgcolor='#eeffee' >\n" );

    Header = "Year," + MonthNames + ",Yr%%,SPX%%,Diff%%";

    for ( Col = 0; ( Colname = StrExtract( Header, Col ) ) != ""; Col++ )
    {
        printf( "<td><b>" + Colname + "</b></td>" );
    }

    printf( "</tr>\n" );

    for ( y = FirstYr; y <= LastYr; y++ )
    {
        // new row
        if ( y % 2 )
            printf( "<tr bgcolor='#ffffff'>\n<td bgcolor='#eeffff'>" );
        else
            printf( "<tr bgcolor='#ffffee'>\n<td bgcolor='#eeffee'>" );

        printf( "<b>%g</b></td>", y );

        for ( m = 1; m <= 12; m++ )
        {
            Chg = VarGet( "ChgMon" + y + "_" + m );

            if ( NOT IsNull( Chg ) )
            {
                if ( Chg >= 0 )
                    printf( "<td nowrap>%.1f%%</td>", Chg );
                else
                    printf( "<td nowrap><font color='880000'>%.1f%%</font></td>", Chg );
            }
            else
                printf( "<td>N/A</td>" );
        }

        // === Jahresrendite System ===
        if ( y % 2 )
            printf( "<td nowrap bgcolor='#eeffff'>" );
        else
            printf( "<td nowrap bgcolor='#eeffee'>" );

        xSys = VarGet( "ChgYear" + y );

        if ( xSys >= 0 )
            printf( "<b>%.1f%%</b></td>", xSys );
        else
            printf( "<font color='880000'><b>%.1f%%</b></font></td>", xSys );

        // === Jahresrendite SPX Buy & Hold ===
        if ( y % 2 )
            printf( "<td nowrap bgcolor='#e6f0ff'>" );
        else
            printf( "<td nowrap bgcolor='#d9e6ff'>" );

        xSpx = VarGet( "ChgYearSPX" + y );

        if ( NOT IsNull( xSpx ) )
        {
            if ( xSpx >= 0 )
                printf( "<font color='0000aa'>%.1f%%</font></td>", xSpx );
            else
                printf( "<font color='880000'>%.1f%%</font></td>", xSpx );
        }
        else
            printf( "N/A</td>" );

        // === Differenz System - SPX (Outperformance) ===
        if ( y % 2 )
            printf( "<td nowrap bgcolor='#fffbe6'>" );
        else
            printf( "<td nowrap bgcolor='#fff5cc'>" );

        if ( NOT IsNull( xSpx ) )
        {
            diff = xSys - xSpx;
            if ( diff >= 0 )
                printf( "<b><font color='008800'>+%.1f%%</font></b></td>", diff );
            else
                printf( "<b><font color='880000'>%.1f%%</font></b></td>", diff );
        }
        else
            printf( "N/A</td>" );

        printf( "</tr>\n" ); // end row
    }


    // === Durchschnittszeile ===
    printf( "<tr bgcolor='#eeffee' >\n" );

    printf( "<td><b>Avg</b></td>" );

    for ( m = 1; m <= 12; m++ )
    {
        x = Nz( VarGet( "SumChgMon" + m ) / VarGet( "SumMon" + m ) );

        if ( x >= 0 )
            printf( "<td nowrap><b>%.1f%%</b></td>", x );
        else
            printf( "<td nowrap><font color='880000'><b>%.1f%%</b></font></td>", x );
    }

    // CAGR System
    if( YearCount > 0 )
    {
        CagrSys = 100 * ( ( TotalSysMultiplier ^ ( 1 / YearCount ) ) - 1 );
        CagrSpx = 100 * ( ( TotalSpxMultiplier ^ ( 1 / YearCount ) ) - 1 );
        CagrDiff = CagrSys - CagrSpx;

        // CAGR System Zelle
        if( CagrSys >= 0 )
            printf( "<td nowrap bgcolor='#eeffee'><b>%.1f%%</b></td>", CagrSys );
        else
            printf( "<td nowrap bgcolor='#eeffee'><font color='880000'><b>%.1f%%</b></font></td>", CagrSys );

        // CAGR SPX Zelle
        if( CagrSpx >= 0 )
            printf( "<td nowrap bgcolor='#d9e6ff'><b><font color='0000aa'>%.1f%%</font></b></td>", CagrSpx );
        else
            printf( "<td nowrap bgcolor='#d9e6ff'><b><font color='880000'>%.1f%%</font></b></td>", CagrSpx );

        // CAGR Diff Zelle
        if( CagrDiff >= 0 )
            printf( "<td nowrap bgcolor='#fff5cc'><b><font color='008800'>+%.1f%%</font></b></td>", CagrDiff );
        else
            printf( "<td nowrap bgcolor='#fff5cc'><b><font color='880000'>%.1f%%</font></b></td>", CagrDiff );
    }
    else
    {
        printf( "<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>" );
    }

    printf( "</tr></table>\n" );

    // === Legende unter der Tabelle ===
    printf( "<p style='font-size:11px;color:#555;'>" );
    printf( "<b>Yr%%</b> = Jahresrendite System &nbsp;&nbsp; " );
    printf( "<b>SPX%%</b> = Jahresrendite SPX Buy & Hold &nbsp;&nbsp; " );
    printf( "<b>Diff%%</b> = Outperformance (System - SPX) &nbsp;&nbsp; " );
    printf( "Letzte Zeile: CAGR über gesamten Backtest-Zeitraum." );
    printf( "</p>" );
}

///////////////////////////
// This function checks if currently selected symbol
// is portfolio equity
//////////////////////////
function CheckSymbol()
{
    if ( Name() != "~~~EQUITY" AND Name() != "~~~OSEQUITY" )
    {
        printf( "For accurate results switch to ~~~EQUITY symbol<br>" );
    }
}

CheckSymbol();

////////////////////////////
// Main program
////////////////////////////
GenProfitTableHTML();
![Help_2|663x500](upload://gLcyJm0lhqbEIiKDfU2vQSxBucY.jpeg)

I would be very grateful if you could provide me with the original code for the Equity curve and the Underwater Equity.

I’m having some issues with my own programming, especially with the scaling. I’d also be happy to share this code with you.

At the moment, I have plotted the equity curve on a logarithmic scale and overlaid the S&P 500 performance on top of it, but unfortunately I’m missing both the time axis and the wealth axis.

If someone could help me fix this, I would really appreciate it.

// Portfolio Equity Chart mit SPX Buy & Hold Benchmark
// Logarithmische Skala, grün->orange Gradient, weißer Hintergrund

SetChartOptions( 1, chartShowArrows | chartShowDates | chartLogarithmic );
SetChartBkColor( colorWhite );
SetChartBkGradientFill( colorWhite, colorWhite );

// === Portfolio Equity (grün -> orange Gradient) ===
EQ = C;
Title = EncodeColor( colorBlack ) + "Portfolio Equity = " + NumToStr( LastValue( EQ ), 1.0 );

SetGradientFill( colorPaleGreen, colorLightOrange, 0.3 );
Plot( EQ, "Portfolio Equity", ColorBlend( colorPaleGreen, colorBlack ),
      styleGradient | styleLine | styleNoLabel, Null, Null, 0, -1 );

// === SPX Buy & Hold Benchmark ===
// Versucht verschiedene gängige SPX-Ticker, nutzt den ersten der Daten liefert
spxTicker = "$SPX";   // Norgate-Standard fuer S&P 500 Index
spxClose  = Foreign( spxTicker, "C" );

// Fallbacks falls $SPX nicht vorhanden
if( LastValue( spxClose ) == 0 OR IsNull( LastValue( spxClose ) ) )
    spxClose = Foreign( "^GSPC", "C" );

if( LastValue( spxClose ) == 0 OR IsNull( LastValue( spxClose ) ) )
    spxClose = Foreign( "SPY", "C" );

// Benchmark auf gleiches Startkapital skalieren
startBar    = 0;
for( i = 0; i < BarCount; i++ )
{
    if( spxClose[i] > 0 AND NOT IsNull( spxClose[i] ) )
    {
        startBar = i;
        break;
    }
}

spxStart   = spxClose[ startBar ];
eqStart    = EQ[ startBar ];
spxEquity  = IIf( spxClose > 0, ( spxClose / spxStart ) * eqStart, Null );

Plot( spxEquity, "SPX Buy & Hold", colorBlue, styleLine | styleThick | styleNoLabel );

// === Legende rechts unten ===
Title = Title +
        EncodeColor( colorGreen ) + "  System: " + NumToStr( LastValue( EQ ), 1.0 ) +
        EncodeColor( colorBlue )  + "  SPX B&H: " + NumToStr( LastValue( spxEquity ), 1.0 );

Re run the setup. Setup contains all original files.

Hi @Tomasz
thank you for your quick reply.
Even though I’m working with AI, I still want to continue improving my learning curve in AmiBroker and gradually learn real programming alongside it.

I have a question regarding the installation:

Should I go for an upgrade setup or a full installation?

And in that context — will my existing trading systems, databases, etc. be reset so that I have to start from scratch, or will the original files simply be added/restored alongside my existing ones?

I tested the Upgrad Installation - but i didnet get the system default Reports.
Now i try - a full installation. :slight_smile:


Thank you for this Tip. I made a full Installation from the Beta Version - now i have the default Report Charts again.

Thank you.

I never change this now - without backup :slight_smile: