Guarda come scaricare robot di trading gratuitamente
Ci trovi su Telegram!
Unisciti alla nostra fan page
Script interessante?
Pubblica il link!
lasciare che altri lo valutino
Ti è piaciuto lo script? Provalo nel Terminale MetaTrader 5
Visualizzazioni:
18
Valutazioni:
(6)
Pubblicato:
2025.06.14 11:57
Freelance MQL5 Hai bisogno di un robot o indicatore basato su questo codice? Ordinalo su Freelance Vai a Freelance

La configurazione

Avremo bisogno di :

  • 1 grafico a zig-zag
  • 2 buffer di dati per i massimi e i minimi
  • parametri di input
  • un insieme continuo di variabili di sistema che si azzerano ogni volta che l'indicatore viene ricalcolato.

#property indicator_buffers 2
#property indicator_plots 1
input double retracement=23.6;//importo del ritracciamento
input double minSizeInAtrUnits=0.0;/min dimensione delle onde in unità atr
input int rollingAtrPeriod=14;//periodo di rotazione dell'atr
input color Color=clrDodgerBlue;//colore dell'onda
input int Width=3;//larghezza dell'onda
input ENUM_LINE_STYLE Style=STYLE_SOLID;//stile onda
//+------------------------------------------------------------------+




//| Funzione di inizializzazione dell'indicatore personalizzata |
//+------------------------------------------------------------------+
//--- onde ascendenti e onde discendenti
  double upWaves[],dwWaves[];

L'array upWaves memorizzerà i massimi e l'array dwWaves i minimi.

Variabili di sistema :

Dobbiamo conoscere il tipo di ultima onda, dove è iniziata, dove si è conclusa, la distanza in barre dall'inizio e dalla fine.

Abbiamo poi bisogno di una variabile locale alta e locale bassa e delle distanze in barre da ciascun punto.

//--- tenendo traccia dello zig-zag
  //--- il tipo di onda che abbiamo [0] nessuna [1] in alto [2] in basso
    int wave_type=0;
  //--- il prezzo dell'onda (prezzo di partenza) 
    double wave_start_price=0.0;
  //--- il prezzo dell'onda (prezzo finale)
    double wave_end_price=0.0;
  //--- la distanza in barre dal prezzo di partenza
    int wave_start_distance=0;
  //--- la distanza in barre dal prezzo finale
    int wave_end_distance=0;
  //--- tracciamento dei prezzi elevati
    double high_mem=0.0;
    int distance_from_high=0;
  //--- tracciamento del prezzo basso
    double low_mem=0.0;
    int distance_from_low=0;
  //--- rolling atr
    double rollingAtr=0.0;
       int rollingAtrs=0;

Infine, è necessario calcolare l'unità di rolling atr e il numero di barre.

Creiamo quindi una funzione di reset del 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;
}

roba standard, riempire gli array con degli zeri e resettare le variabili di sistema.

Oninit configuriamo 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();

Quindi passiamo subito al calcolo.

La prima cosa di cui dobbiamo occuparci è il rolling atr.

Finché non avremo raccolto più barre del periodo dell'atr non faremo nient'altro.

La parte che gestisce il rolling atr è la seguente:

  • se non abbiamo raccolto più barre del periodo continuiamo a sommare l'intervallo delle barre trovate
  • una volta raggiunto il periodo eseguiamo la prima divisione (media)
  • dopodiché tagliamo una parte del rolling atr, che è atr/periodo, e poi aggiungiamo una nuova parte che è range di barre / periodo
Mettiamo l'ultima parte per prima perché si verificherà più spesso e non avremo bisogno di accedere a 2 dichiarazioni if.

     //--- gestire l'atr
       rollingAtrs++;
       if(rollingAtrs>rollingAtrPeriod){
       double new_portion=((high[i]-low[i])/_Point)/((double)rollingAtrPeriod);
       //--- rimuoviamo una vecchia porzione e ne aggiungiamo una nuova
       rollingAtr=(rollingAtr)-(rollingAtr/((double)rollingAtrPeriod))+new_portion;
       }
       else if(rollingAtrs<=rollingAtrPeriod){
         rollingAtr+=(high[i]-low[i])/_Point;
         if(rollingAtrs==rollingAtrPeriod){
           rollingAtr/=((double)rollingAtrs);
           //--- avviare la memoria per alti e bassi e il sistema
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
         }

Ora c'è un altro problema.

Il fondamento di questo zig zag è un ritracciamento.

Ma perché si verifichi un ritracciamento deve esserci almeno un'onda.

Ma quale sarà il ritracciamento della prima onda? xD

Per questo motivo faremo quanto segue:

  • non appena l'atr si riempie (atr raccolto = periodo), prenderemo il massimo e il minimo nelle nostre variabili di sistema
  • chiunque riesca a formare un'onda che abbia una dimensione valida in unità atr, e che formi un nuovo massimo (upwave) o un nuovo minimo (down wave) vince

in questo modo non abbiamo un ritracciamento come onda iniziale, ma dobbiamo iniziare la sequenza in qualche modo.

Si potrebbe anche optare per un approccio frattale classico solo per la prima onda e poi continuare con i ritracciamenti.

Questo è ciò che facciamo finché non abbiamo un'onda:

   //--- se non abbiamo ancora un tipo di onda
     else{
       //--- se abbiamo rotto il massimo e non il minimo
         if(high[i]>high_mem&&low[i]>=low_mem){
         double new_wave_size_in_atr_units=((high[i]-low_mem)/_Point)/rollingAtr;
         //--- se la nuova dimensione dell'onda è valida
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
           //--- avviare una nuova onda ascendente 
             wave_type=1;
           //--- il prezzo iniziale è il mem basso 
             wave_start_price=low_mem;
             wave_start_distance=distance_from_low;
           //--- il prezzo finale è il nuovo massimo
             wave_end_price=high[i];
             wave_end_distance=0;
           //--- disegnare l'onda 
             dwWaves[i-wave_start_distance]=low_mem;
             upWaves[i]=high[i];
           //--- cambiare il valore alto
             high_mem=high[i];
             distance_from_high=0;
           //--- cambiare il basso 
             low_mem=low[i];
             distance_from_low=0;
           }
           } 
       //--- se abbiamo rotto il minimo e non il massimo
         else if(low[i]<low_mem&&high[i]<=high_mem){
         double new_wave_size_in_atr_units=((high_mem-low[i])/_Point)/rollingAtr;
         //--- se la nuova dimensione dell'onda è valida
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){         
           //--- inizia una nuova onda discendente 
             wave_type=-1;
           //--- il prezzo iniziale è il mem alto 
             wave_start_price=high_mem;
             wave_start_distance=distance_from_high;
           //--- il prezzo finale è il nuovo minimo
             wave_end_price=low[i];
             wave_end_distance=0;
           //--- disegnare l'onda 
             upWaves[i-wave_start_distance]=high_mem;
             dwWaves[i]=low[i];
           //--- cambiare il valore alto
             high_mem=high[i];
             distance_from_high=0;
           //--- cambiare il basso 
             low_mem=low[i];
             distance_from_low=0;
           }
           }
       //--- se abbiamo rotto entrambi
         else if(low[i]<low_mem&&high[i]>high_mem){
           //--- cambiarli
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
       }

Ottimo. Ora il pezzo finale.

  • Se abbiamo un'onda ascendente:
  1. se si verifica un nuovo massimo, spostiamo lo zigzag dalla posizione del massimo precedente a quella del nuovo massimo, cosa che possiamo fare dal momento che conserviamo le distanze tra le barre. Aggiorniamo anche il minimo e la distanza dal minimo. Lo facciamo in modo da poter cogliere il minimo più basso dal picco e controllare se ritraccia abbastanza per iniziare un nuovo minimo
  2. se viene fatto un nuovo minimo, o se viene impostato un nuovo minimo, calcoliamo la distanza dal picco al minimo e la dividiamo per la dimensione dell'onda. Quindi, se la dimensione dell'onda è di 100 punti e il ritracciamento è di 24 punti, otteniamo 24/100 0,24, quindi x 100 24%. Se la dimensione della nuova "futura" onda che ritraccia la precedente è valida anche rispetto alle unità atr, iniziamo una nuova onda discendente, impostiamo i nuovi massimi e minimi locali, impostiamo le distanze delle barre.

Ecco il codice relativo a quanto sopra:

       //--- se abbiamo un'onda positiva 
         if(wave_type==1){
           //--- se l'onda si espande verso l'alto 
             if(high[i]>wave_end_price){
               //--- rimuovere il prezzo finale precedente dalla sua posizione nell'array (0.0=vuoto)
                upWaves[i-wave_end_distance]=0.0;
               //--- posizionarlo nella nuova posizione
                upWaves[i]=high[i];
                wave_end_price=high[i];
                wave_end_distance=0;
               //--- cambiare il valore alto
                high_mem=high[i];
                distance_from_high=0;
               //--- cambiare il basso 
                low_mem=low[i];
                distance_from_low=0;
               }
           //--- controllare il ritracciamento
             if(low[i]<low_mem||distance_from_low==0){
               low_mem=low[i];
               distance_from_low=0;
               double size_of_wave=(wave_end_price-wave_start_price)/_Point;
               double size_of_retracement=(wave_end_price-low_mem)/_Point;
               if(size_of_wave>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;
               //--- se la nuova dimensione dell'onda è valida
               if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
                 //--- se il ritracciamento è significativo, inizia un'onda discendente
                   if(retraced>=retracement){
                    //--- inizia una nuova onda discendente 
                      wave_type=-1;
                    //--- il prezzo iniziale è il mem alto 
                      wave_start_price=high[i-distance_from_high];
                      wave_start_distance=distance_from_high;
                    //--- il prezzo finale è il nuovo minimo
                      wave_end_price=low[i];
                      wave_end_distance=0;
                    //--- disegnare l'onda 
                      upWaves[i-wave_start_distance]=high_mem;
                      dwWaves[i]=low[i];
                    //--- cambiare il valore alto
                      high_mem=high[i];
                      distance_from_high=0;
                    //--- cambiare il basso 
                      low_mem=low[i];
                      distance_from_low=0;                     
                     }
                   }
                 }
               }
           }

Facciamo il contrario quando abbiamo un'onda discendente.

E abbiamo finito, il nostro zig zag di ritracciamento è pronto.

Ecco lo zig zag con un ritracciamento del 23,6% e una dimensione minima delle onde di 0,0 in unità atr


ed ecco lo stesso zig zag con onde di dimensione 3 min in unità atr






Tradotto dall’inglese da MetaQuotes Ltd.
Codice originale https://www.mql5.com/en/code/56619

Esportatore di relazioni commerciali Esportatore di relazioni commerciali

Lo script TradeReportExporter è progettato per esportare la cronologia delle operazioni (trade) in un comodo file CSV. Raccoglie automaticamente i dati di tutte le operazioni dell'ultimo anno per lo strumento su cui è installato. Il file include dati quali data e ora, tipo di transazione (acquisto/vendita), prezzo, volume, commissione e profitto/perdita. Il risultato viene salvato in un file che può essere aperto in Excel o in qualsiasi altro editor di fogli di calcolo.

A Really Random Robot A Really Random Robot

Questo robot utilizza un generatore di numeri casuali per simulare il semplice lancio di una moneta per decidere la direzione di ogni operazione. Fornisce un esempio di expert advisor minimale programmato in stile object-oriented. Fornisce inoltre una base per quantificare il valore aggiunto da metodi alternativi di entrata.

Indice di forza relativa della volatilità Indice di forza relativa della volatilità

RSI calcolato in base ai valori di deviazione standard.

TicksFile TicksFile

Un Expert Advisor che consente non solo di salvare le informazioni sui tick in un file, ma anche di registrare i tick modellati dal tester.