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
