Impostazione dell'Indicatore
Per configurare il nostro indicatore ZigZag, avremo bisogno di:
- Un grafico ZigZag
- Due buffer dati per i massimi e i minimi
- Parametri di input
- Un insieme di variabili di sistema che si resetta ogni volta che l'indicatore ricalcola
Il buffer upWaves memorizzerà i massimi, mentre il buffer dwWaves memorizzerà i minimi.
Variabili di sistema:
Dobbiamo tenere traccia del tipo di onda, dove inizia e dove termina, e la distanza in barre tra l'inizio e la fine.
//--- tracciamento del zigzag int wave_type=0; double wave_start_price=0.0; double wave_end_price=0.0; int wave_start_distance=0; int wave_end_distance=0; double high_mem=0.0; int distance_from_high=0; double low_mem=0.0; int distance_from_low=0; double rollingAtr=0.0; int rollingAtrs=0;
Adesso creiamo una funzione per resettare il sistema:
void resetSystem() {
ArrayFill(upWaves, 0, ArraySize(upWaves), 0.0);
ArrayFill(dwWaves, 0, ArraySize(dwWaves), 0.0);
wave_type=0;
wave_start_price=0.0;
wave_end_price=0.0;
wave_start_distance=0;
wave_end_distance=0;
high_mem=0.0;
low_mem=0.0;
distance_from_high=0;
distance_from_low=0;
rollingAtr=0.0;
rollingAtrs=0;
}
Riempie le matrici con zeri e resetta le variabili di sistema.
All'inizio, impostiamo i buffer, il grafico e chiamiamo il reset per la prima volta:
SetIndexBuffer(0, upWaves, INDICATOR_DATA); SetIndexBuffer(1, dwWaves, INDICATOR_DATA); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_ZIGZAG); PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, Color); PlotIndexSetInteger(0, PLOT_LINE_WIDTH, Width); PlotIndexSetInteger(0, PLOT_LINE_STYLE, Style); resetSystem();
Cominciamo con il calcolo.
La prima cosa da gestire è il rolling ATR. Fino a quando non abbiamo raccolto più barre del periodo ATR, non faremo altro.
- Se non abbiamo raccolto più del periodo, continuiamo ad aggiungere l'intervallo delle barre trovate a una somma
- Una volta raggiunto il periodo, facciamo la prima divisione (media)
- Dopo, togliamo una porzione del rolling ATR e aggiungiamo una nuova porzione che è l'intervallo della barra / periodo
Gestiamo il rolling ATR:
rollingAtrs++;
if(rollingAtrs>rollingAtrPeriod) {
double new_portion=((high[i]-low[i])/_Point)/((double)rollingAtrPeriod);
rollingAtr=(rollingAtr)-(rollingAtr/((double)rollingAtrPeriod))+new_portion;
} else if(rollingAtrs<=rollingAtrPeriod) {
rollingAtr+=(high[i]-low[i])/_Point;
if(rollingAtrs==rollingAtrPeriod) {
rollingAtr/=((double)rollingAtrs);
high_mem=high[i];
low_mem=low[i];
distance_from_high=0;
distance_from_low=0;
}
}
Perfetto, ora affrontiamo il problema iniziale.
Per un retracement ci deve essere almeno un'onda. Dobbiamo partire con una sequenza. Ecco cosa facciamo:
- Appena l'ATR si riempie, prendiamo il massimo e il minimo nelle nostre variabili di sistema
- Qualsiasi lato che riesce a formare un'onda valida e forma un nuovo massimo (onda in su) o un nuovo minimo (onda in giù) vince
Questo modo ci permette di iniziare la sequenza.
else {
if(high[i]>high_mem && low[i]>=low_mem) {
double new_wave_size_in_atr_units=((high[i]-low_mem)/_Point)/rollingAtr;
if(new_wave_size_in_atr_units>=minSizeInAtrUnits) {
wave_type=1;
wave_start_price=low_mem;
wave_start_distance=distance_from_low;
wave_end_price=high[i];
wave_end_distance=0;
dwWaves[i-wave_start_distance]=low_mem;
upWaves[i]=high[i];
high_mem=high[i];
distance_from_high=0;
low_mem=low[i];
distance_from_low=0;
}
}
} Se abbiamo un'onda in su:
- Se viene fatto un nuovo massimo, spostiamo il zigzag dalla posizione massima precedente a quella nuova.
- Se viene fatto un nuovo minimo, calcoliamo la distanza dal picco al basso e verifichiamo se il retracement è sufficiente per avviare una nuova onda in giù.
Qui c'è il codice pertinente:
if(wave_type==1) {
if(high[i]>wave_end_price) {
upWaves[i-wave_end_distance]=0.0;
upWaves[i]=high[i];
wave_end_price=high[i];
wave_end_distance=0;
high_mem=high[i];
distance_from_high=0;
low_mem=low[i];
distance_from_low=0;
}
if(low[i]0.0) {
double retraced=(size_of_retracement/size_of_wave)*100.0;
double new_wave_size_in_atr_units=((wave_end_price-low_mem)/_Point)/rollingAtr;
if(new_wave_size_in_atr_units>=minSizeInAtrUnits) {
if(retraced>=retracement) {
wave_type=-1;
wave_start_price=high[i-distance_from_high];
wave_start_distance=distance_from_high;
wave_end_price=low[i];
wave_end_distance=0;
upWaves[i-wave_start_distance]=high_mem;
dwWaves[i]=low[i];
high_mem=high[i];
distance_from_high=0;
low_mem=low[i];
distance_from_low=0;
}
}
}
}
Ed ecco il nostro zigzag con 23.6% di retracement e 0.0 min size di onde in unità ATR.

Qui c'è lo stesso zigzag con 3 min size di onde in unità ATR.

Quindi, ora avete tutte le informazioni necessarie per utilizzare questo potente indicatore ZigZag sul vostro MetaTrader 5!
Post correlati
- Volatilità Stocastica: Indicatore per MetaTrader 5 da Utilizzare sul Grafico
- Notis: L'Indicatore per Misurare la Volatilità su MetaTrader 5
- Indicatore di Equità e Bilancio per MetaTrader 5: Monitoraggio della Tua Performance di Trading
- Utilità per le Informazioni su Barre e Tassi per MetaTrader 5
- Indicatore GARCH: Un Estimatore di Volatilità per il Trading Professionale