DRAW_CANDLES

Lo stile DRAW_CANDLES disegna candele sui valori di quattro buffer di indicatori, che contengono i prezzi Open, High, Low and Close prices. E' utilizzato per la creazione di indicatori personalizzati come una sequenza di candele, comprese quelle in una sottofinestra separata di un grafico e su altri strumenti finanziari.

Il colore delle candele può essere impostato tramite le direttive del compilatore o in modo dinamico utilizzando la funzione PlotIndexSetInteger(). Cambiamenti dinamici delle proprietà di plotting permettono di "animare" gli indicatori, in modo che il loro aspetto cambia a seconda della situazione attuale.

L'indicatore è disegnato solo per queste barre, per cui i valori non vuoti di tutti e quattro i buffer indicatore sono impostati. Per specificare quale valore deve essere considerato come "vuoto", impostare questo valore nelle proprietà PLOT_EMPTY_VALUE:

/ / --- Il valore 0 (vuoto) parteciperà al disegno
   PlotIndexSetDouble(index_of_plot_DRAW_CANDLES,PLOT_EMPTY_VALUE,0);

Riempie esplicitamente i valori dei buffer indicatori, imposta un valore vuoto in un buffer per saltare le barre.

Il numero di buffer richiesti per il plotting di DRAW_CANDLES è 4. Tutti i buffer per il plotting dovrebbero andare uno dopo l'altro, nell'ordine: Open, High, Low e Close. Nessuno dei buffer può contenere solo valori vuoti, perché in questo caso nulla è tracciato.

È possibile impostare fino a tre colori per lo stile DRAW_CANDLES che influisce sull'aspetto della candela. Se un solo colore è impostato, viene applicata a tutte le candele sul chart.

//--- candele identiche con un unico colore applicato ad esse
#property indicator_label1  "Candele a colore unico"
#property indicator_type1   DRAW_CANDLES
//--- viene specificato un solo colore, quindi tutte le candele sono dello stesso colore
#property indicator_color1  clrGreen  

Se vengono specificati due colori separati da virgola, il primo viene applicato al bordo della candela, mentre il secondo è applicato al corpo.

//--- Colori diversi per candele e stoppini
#property indicator_label1  "Candele a due colori"
#property indicator_type1   DRAW_CANDLES
//--- il verde viene applicato stoppini e contorni, mentre il bianco è applicato al corpo
#property indicator_color1  clrGreen,clrWhite 

Specificare tre colori separati da virgola in modo che le candele che salgono e scendono vengono visualizzate in modo diverso. In tal caso, il primo colore viene applicato ai contorni candela, mentre il secondo e il terzo - a candele rialzista e ribassista.

//--- Colori diversi per candele e stoppini
#property indicator_label1  "Candele a colore unico"
#property indicator_type1   DRAW_CANDLES
//--- stoppini e contorni sono di colore verde, il corpo della candela rialzista è bianco, mentre il corpo della candela ribassista è rosso
#property indicator_color1  clrGreen,clrWhite,clrRed

Quindi, lo stile DRAW_CANDLES permette di creare opzioni di colorazione personalizzata della candela. Inoltre, tutti i colori possono essere modificati dinamicamente durante il funzionamento dell'indicatore utilizzando la funzione PlotIndexSetInteger (composition_index_DRAW_CANDLES, PLOT_LINE_COLOR, modifier_index, color), dove modifier_index può avere i seguenti valori:

  • 0 – colori di contorni e stoppini
  • 1– colore del corpo della candela rialzista
  • 2 – colore del corpo della candela ribassista

// --- impostare il colore dei contorni e stoppini
PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,clrBlue);
// --- impostare il colore del corpo della rialzista
PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,clrGreen);
// --- imposta il colore del corpo della ribassista
PlotIndexSetInteger(0,PLOT_LINE_COLOR,2,clrRed);

Un esempio di indicatore che disegna candele per uno strumento finanziario selezionato in una finestra separata. Il colore delle candele cambia dinamicamente ogni N ticks. Il parametro N è impostato nei parametri esterni dell'indicatore per la possibilità di configurazione manuale (la scheda Parametri nella finestra Proprietà dell' indicatore).

Un esempio di stile DRAW_CANDLES

Si prega di notare che per plot1, il colore è impostato usando la direttiva del compilatore #property, e poi nella funzione OnCalculate() il colore è impostato in modo casuale da una lista precedentemente preparata.

//+--------------------------------------------------------------------------------+
//|                                                               DRAW_CANDLES.mq5 |
//|                                      Copyright 2011, MetaQuotes Software Corp. | 
//|                                                           https://www.mql5.com |
//+--------------------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#property description "Un indicatore per mostrare DRAW_CANDLES."
#property description "Disegna le candele di un simbolo selezionato in una finestra separata"
#property description " "
#property description "Il colore e lo spessore delle candele, così come il simbolo vengono cambiati"
#property description "dinamicamente ogni N ticks"
 
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   1
//--- plot Bars
#property indicator_label1  "DRAW_CANDLES1"
#property indicator_type1   DRAW_CANDLES
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
 
//--- parametri di input
input int      N=5;              // Il numero di ticks per cambiare il tipo
input int      bars=500;         // Il numero di barre da mostrare
input bool     messages=false;   // Mostra i messaggi nel log "Expert Advisors" 
//--- Buffer Indicatore
double         Candle1Buffer1[];
double         Candle1Buffer2[];
double         Candle1Buffer3[];
double         Candle1Buffer4[];
//--- Nome simbolo
string symbol;
//--- Un array per salvare i colori
color colors[]={clrRed,clrBlue,clrGreen,clrPurple,clrBrown,clrIndianRed};
//+--------------------------------------------------------------------------------+
//| Funzione di inizializzazione Indicatore Personalizzato                         |
//+--------------------------------------------------------------------------------+
int OnInit()
  {
/ / --- Se bars è molto piccolo - completa il lavoro prima del tempo
   if(bars<50)
     {
      Comment("Prego specificare un gran numero di barre! L'operazione dell'indicatore è stata terminata ");
      return(INIT_PARAMETERS_INCORRECT);
     }
//--- mappatura buffers indicatore
   SetIndexBuffer(0,Candle1Buffer1,INDICATOR_DATA);
   SetIndexBuffer(1,Candle1Buffer2,INDICATOR_DATA);
   SetIndexBuffer(2,Candle1Buffer3,INDICATOR_DATA);
   SetIndexBuffer(3,Candle1Buffer4,INDICATOR_DATA);
//--- Un valore vuoto
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//--- Il nome del simbolo, per cui le barre vengono disegnate
   symbol=_Symbol;
//--- Imposta il display del simbolo
   PlotIndexSetString(0,PLOT_LABEL,symbol+" Open;"+symbol+" High;"+symbol+" Low;"+symbol+" Close");
   IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_CANDLES("+symbol+")");
//---
   return(INIT_SUCCEEDED);
  }
//+--------------------------------------------------------------------------------+
//| Funzione di iterazione indicatore personalizato                                |
//+--------------------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   static int ticks=INT_MAX-100;
//--- Calcola i ticks per cambiare lo stile, il colore e lo spessore della linea
   ticks++;
//--- Se un numero sufficiente di ticks è stato accumulato
   if(ticks>=N)
     {
      //--- Imposta un nuovo simbolo dalla finestra Market Watch
      symbol=GetRandomSymbolName();
      //--- Cambia la forma
      ChangeLineAppearance();
      //--- Imposta un nuovo simbolo dalla finestra Market Watch
      int tries=0;
      //--- Fa 5 tentativi per riempire i buffers di plot1 con i prezzi dal simbolo
      while(!CopyFromSymbolToBuffers(symbol,rates_total,0,
            Candle1Buffer1,Candle1Buffer2,Candle1Buffer3,Candle1Buffer4)
            && tries<5)
        {
         //--- Un contatore delle chiamate della funzione CopyFromSymbolToBuffers()
         tries++;
        }
      //--- Resetta il contatore dei ticks a zero
      ticks=0;
     }
//--- restituisce il valore di prev_calculated per la prossima chiamata
   return(rates_total);
  }
//+--------------------------------------------------------------------------------+
//| Riempie le candele specificate                                                 |
//+--------------------------------------------------------------------------------+
bool CopyFromSymbolToBuffers(string name,
                             int total,
                             int plot_index,
                             double &buff1[],
                             double &buff2[],
                             double &buff3[],
                             double &buff4[]
                             )
  {
//--- Nell'array rates[], copieremo Open, High, Low e Close
   MqlRates rates[];
//--- Il contatore dei tentativi
   int attempts=0;
//--- Quanto è stato copiato
   int copied=0;
//--- Fa 25 tentativi per ottenere una timeseries sul simbolo desiderato
   while(attempts<25 && (copied=CopyRates(name,_Period,0,bars,rates))<0)
     {
      Sleep(100);
      attempts++;
      if(messagesPrintFormat("%s CopyRates(%s) attempts=%d",__FUNCTION__,name,attempts);
     }
//--- Se non è riuscito a copiare un numero sufficiente di barre
   if(copied!=bars)
     {
      //--- Forma un messaggio stringa
      string comm=StringFormat("Per il simbolo %s, è riuscito a ricevere solo %d barre delle %d richieste",
                               name,
                               copied,
                               bars
                               );
      //--- Mostra un messaggio in un commento nella finestra del grafico principale
      Comment(comm);
      //--- Mostra il messaggio
      if(messagesPrint(comm);
      return(false);
     }
   else
     {
      //--- Imposta il display del simbolo 
      PlotIndexSetString(plot_index,PLOT_LABEL,name+" Open;"+name+" High;"+name+" Low;"+name+" Close");
     }
//--- Inizializza i buffers con valori vuoti
   ArrayInitialize(buff1,0.0);
   ArrayInitialize(buff2,0.0);
   ArrayInitialize(buff3,0.0);
   ArrayInitialize(buff4,0.0);
//--- Su ogni tick, copia i prezzi dei buffers
   for(int i=0;i<copied;i++)
     {
      //--- Calcola l'indice appropriato per i buffers
      int buffer_index=total-copied+i;
      //--- Scrive i prezzi nei buffers
      buff1[buffer_index]=rates[i].open;
      buff2[buffer_index]=rates[i].high;
      buff3[buffer_index]=rates[i].low;
      buff4[buffer_index]=rates[i].close;
     }
   return(true);
  }
//+--------------------------------------------------------------------------------+
//| Restituisce in modo casuale il simoblo dal Market Watch                        |
//+--------------------------------------------------------------------------------+
string GetRandomSymbolName()
  {
//--- Il numero dei simboli mostrati nella finestra Market Watch
   int symbols=SymbolsTotal(true);
//--- La posizione di un simbolo nella lista - un numero casuale da 0 a simboli
   int number=MathRand()%symbols;
//--- Restituisce il nome di un simbolo nella posizione specificata
   return SymbolName(number,true);
  }
//+--------------------------------------------------------------------------------+
//| Cambia l'apparenza delle barre                                                 |
//+--------------------------------------------------------------------------------+
void ChangeLineAppearance()
  {
//--- Una stringa per la formazione delle informazioni riguardo le proprietà della barra
   string comm="";
//--- Un blocco per il cambio di colore delle barre
   int number=MathRand(); // Ottiene un numero casuale
//--- Il divisore è uguale alla grandezza dell'array colors [] 
   int size=ArraySize(colors);
//--- Ottiene l'indice per selezionare un nuovo colore, come il resto della divisione intera
   int color_index=number%size;
//--- Imposta il colore come la proprietà PLOT_LINE_COLOR
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,colors[color_index]);
//--- Scrive il colore
   comm=comm+"\r\n"+(string)colors[color_index];
//--- Scrive il nome del simbolo
   comm="\r\n"+symbol+comm;
//--- Imposta le informazioni del grafico usando un commento
   Comment(comm);
  }