Drawdrown info

Hi,
I wanted to have a report chart showing the Drawdown, including the Current, Maximum, and Average.
I also wanted to be able to see it in absolute value and as a percentage.

By taking bits and pieces from various sources: https://forum.amibroker.com/t/average-drawdown-calculation-cbt/27568/3
and with the help of Gemini, I came up with the attached chart, but I'm not sure if it's correct.

/*
CÓDIGO FINAL VERSIÓN ULTRA ROBUSTA 2: Con todos los detalles de cálculo en el título
*/

SetChartBkColor(colorWhite);
GraphLabelDecimals = 0;
SetChartOptions(1, chartShowDates);

// =======================================================
// 1. CÁLCULO DEL DRAWDOWN Y VARIABLES DE IDENTIFICACIÓN
// =======================================================

EQ = C; 
MaxEQ = Highest( EQ );

//  Absoluto
DD_absolute = ( EQ - MaxEQ ); 
MaxDD_absolute = Lowest( DD_absolute );

//  Porcentaje
DD_percent = 100 * (EQ - MaxEQ) / MaxEQ;
MaxDD_percent = Lowest(DD_percent);


// Variables base para la lógica de ciclos
bi = BarIndex();
is_last_bar = bi == LastValue( bi );
is_zero = DD_absolute == 0; 


// =======================================================
// 2. CÁLCULO DEL DD PROMEDIO (CICLOS, ABSOLUTO $)
// =======================================================

// A. Lógica de Identificación de Ciclos (Pico a Valle)
hh_abs_tracker = LowestSince( is_zero, DD_absolute );
DD_Peaks_Valleys_Abs = IIf( is_zero OR is_last_bar, Ref( hh_abs_tracker, -1 ), 0.0 ); 

// B. Conteo y Suma Totales
DD_es_ciclo_final = IIf( DD_Peaks_Valleys_Abs < 0, 1, 0 );
num_cycles_abs = LastValue( Cum( DD_es_ciclo_final ) ); 

Sumandos_DD = IIf( DD_es_ciclo_final == 1, DD_Peaks_Valleys_Abs, 0.0 );
sum_cycles_abs = LastValue( Cum( Sumandos_DD ) ); 

AvgDD_Cycle_Abs = 0;

if( num_cycles_abs > 0 )
{
    AvgDD_Cycle_Abs = sum_cycles_abs / num_cycles_abs; 
}


// =======================================================
// 2. CÁLCULO DEL DD PROMEDIO (CICLOS, PORCENTAJE %)
// =======================================================

// A. Lógica de Identificación de Ciclos (Pico a Valle)
hh_pct_tracker = LowestSince( is_zero, DD_percent );
DD_Peaks_Valleys_Pct = IIf( is_zero OR is_last_bar, Ref( hh_pct_tracker, -1 ), 0.0 ); 

// B. Conteo y Suma Totales
DD_es_ciclo_final_pct = IIf( DD_Peaks_Valleys_Pct < 0, 1, 0 );
num_cycles_pct = LastValue( Cum( DD_es_ciclo_final_pct ) ); 

Sumandos_DD_Pct = IIf( DD_es_ciclo_final_pct == 1, DD_Peaks_Valleys_Pct, 0.0 );
sum_cycles_pct = LastValue( Cum( Sumandos_DD_Pct ) ); 

AvgDD_Cycle_Pct = 0;

if( num_cycles_pct > 0 )
{
    AvgDD_Cycle_Pct = sum_cycles_pct / num_cycles_pct; 
}



// =======================================================
// 3. PLOTEO
// =======================================================


//Títulos
Title = EncodeColor(colorBlack) + " MaxDD: " + NumToStr( LastValue(MaxDD_percent), 1.2, True ) + "(%)"+ "      DDActual: " + NumToStr( LastValue(DD_percent), 1.2, True ) + "(%)"
+ "        DDPromedio: " + NumToStr( AvgDD_Cycle_Pct, 1.2, True ) + " (%)" + "        [ Sum DD: " + NumToStr( sum_cycles_abs, 1.2, True ) + " / n: " + NumToStr( num_cycles_abs, 0 ) + " ]";

// Pintamos Portfolio
SetGradientFill( ColorRGB( 255, 225, 225 ), ColorRGB( 255, 50, 50 ), 0);
Plot( DD_absolute, "", ColorBlend( ColorRGB( 255, 50, 50 ), colorBlack ), styleGradient |styleLine , Null, Null, 0, -1 );
Plot(MaxDD_absolute, "", colorRed, styleLine  | styleDashed );

// LÍNEA DEL DD PROMEDIO (AÑADIDA)
Plot(AvgDD_Cycle_Abs, "DD Promedio Absoluto $", colorLightOrange, styleLine | styleDashed );


if (Name() != "~~~EQUITY" AND Name() != "~~~OSEQUITY")
    Title = "?? Warning: this chart should be applied to ~~~EQUITY or ~~~OSEQUITY only!";

I'd appreciate it if someone more experienced could give me the go-ahead.

The chart looks good and shows what I want, but... I'm not sure if the code calculates it correctly.

In the chart title, you can see the values ​​it uses to calculate the average: in this example, it takes (-42,002.26($)), which is the sum of all the drawdowns during the backtest, and divides it by the total number of drawdown cycles (n = 212). This is what I'm unsure about.

Thanks

The first thing to consider is what you are trying to learn from an “average drawdown” value. That will determine how it should be calculated. I can think of at least two different ways that one might calculate an average drawdown:

  1. For every bar that the system equity is in drawdown (i.e. not at an all-time high), add one to the count of periods and add the drawdown amount to a running sum of drawdowns. After processing all bars, divide the DD sum by the count of periods. I believe this is what you’ve implemented in your code.
  2. Count the number of complete drawdown cycles, where each drawdown begins when the equity falls below an all-time high and ends when it makes a new all-time high. For each of those drawdowns, add the MAX drawdown during that cycle to a running sum of max drawdowns. After processing all drawdown cycles, divide the Max DD sum by the count of drawdowns.

In simplest terms, the first method tells you how far the system is typically underwater (average drawdown). The second method tells you how deep a drawdown typically goes (average max drawdown).

1 Like

Thank you very much, mradtke.

I don't quite understand the first calculation method you mentioned.

I'm more inclined to use the second method you mentioned, the average of the maximum drop (in complete cycles of decline and recovery).

To put it in context:
I start with an initial capital of 10,000 in equity.

  1. On the first day, I close equity at 9,990.
  2. On the second day, I close equity at 9,950.
  3. On the third day, I close equity at 9,975.
  4. On the fourth day, I close equity at 10,005.
    This was a single drawdown cycle with a drop of 50.

I'm not sure how it would work with your first method.

With the first method, you would find the average of -0.1%, -0.5%, and -0.25%, giving you an average of -0.85% / 3 = -0.2833%. The question is whether that tells you anything interesting about your system. For me, the second method seems more useful.

As for validating your results, I suggest exporting your equity curve to Excel and repeating the calculations there.

1 Like