DRAW_COLOR_CANDLES

Lo stile DRAW_COLOR_CANDLES, come DRAW_CANDLES, disegna candele utilizzando i valori dei quattro buffer di indicatori, che contengono i prezzi Open, High, Low e Close. Inoltre, esso permette di specificare un colore per ogni candela da un dato insieme. A questo scopo, lo stile ha un colore speciale buffer che memorizza indici di colore per ogni barra. 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 numero di colori delle candele può essere impostato utilizzando 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 quelle barre per cui sono impostati valori non vuoti di quattro buffer di prezzi dell'indicatore. Per specificare quale valore deve essere considerato come "vuoto", impostare questo valore nella proprietà PLOT_EMPTY_VALUE:

/ / --- Il valore 0 (vuoto) parteciperà al disegno
   PlotIndexSetDouble(index_of_plot_DRAW_COLOR_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 necessari per il plotting di DRAW_COLOR_CANDLES è di 5:

  • quattro buffer per memorizzare i valori di Open, High, Low e Close;
  • un buffer per memorizzare l'indice del colore, che viene utilizzato per disegnare una candela (ha senso impostarlo solo per le candele che verranno disegnate).

Tutti i buffer per il tracciamento dovrebbero andare uno dopo l'altro, nell'ordine: Open, High, Low, Close e il buffer del colore. Nessuno dei buffer di prezzo possono contenere solo valori vuoti, poiché in questo caso nulla è disegnato.

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_COLOR_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_COLOR_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 dimostrare DRAW_COLOR_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 5
#property indicator_plots   1
//--- plot ColorCandles
#property indicator_label1  "ColorCandles"
#property indicator_type1   DRAW_COLOR_CANDLES
//--- Definisce 8 colori per colorare le candele (sono memorizzati nell'array speciale)
#property indicator_color1  clrRed,clrBlue,clrGreen,clrYellow,clrMagenta,clrCyan,clrLime,clrOrange
#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 candele da mostrare
input bool     messages=false;   // Mostra i messaggi nel log "Expert Advisors" 
//--- Buffer Indicatore
double         ColorCandlesBuffer1[];
double         ColorCandlesBuffer2[];
double         ColorCandlesBuffer3[];
double         ColorCandlesBuffer4[];
double         ColorCandlesColors[];
int            candles_colors;
//--- Nome simbolo
string symbol;
//--- Un array per memorizzare i colori contiene 14 elementi
color colors[]=
  {
   clrRed,clrBlue,clrGreen,clrChocolate,clrMagenta,clrDodgerBlue,clrGoldenrod,
   clrIndigo,clrLightBlue,clrAliceBlue,clrMoccasin,clrMagenta,clrCyan,clrMediumPurple
  };
//+--------------------------------------------------------------------------------+
//| 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,ColorCandlesBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,ColorCandlesBuffer2,INDICATOR_DATA);
   SetIndexBuffer(2,ColorCandlesBuffer3,INDICATOR_DATA);
   SetIndexBuffer(3,ColorCandlesBuffer4,INDICATOR_DATA);
   SetIndexBuffer(4,ColorCandlesColors,INDICATOR_COLOR_INDEX);
//--- 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_COLOR_CANDLES("+symbol+")");
//---- Il numero di colori di candele colore
   candles_colors=8;     //  see. un commento alla proprietà #property indicator_color1
//--- 
   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;
//--- Conteggio di ticks per cambiare lo stile ed il colore
   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();
      //--- Cambia i colori usati per disegnare le candele
      ChangeColors(colors,candles_colors);
 
      int tries=0;
      //--- Fa 5 tentativi per riempire i buffers di plot1 con i prezzi dal simbolo
      while(!CopyFromSymbolToBuffers(symbol,rates_total,0,
            ColorCandlesBuffer1,ColorCandlesBuffer2,ColorCandlesBuffer3,
            ColorCandlesBuffer4,ColorCandlesColors,candles_colors)
            && 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[],
                             double &col_buffer[],
                             int    cndl_colors
                             )
  {
//--- 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(messages) Print(comm);
      return(false);
     }
   else
     {
      //--- Imposta il display del simbolo 
      PlotIndexSetString(plot_index,PLOT_LABEL,name+" Open;"+name+" High;"+name+" Low;"+name+" Close");
      IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_COLOR_CANDLES("+symbol+")");
     }
//--- 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;
      //--- Imposta il colore della candela
      int color_index=i%cndl_colors;
      col_buffer[buffer_index]=color_index;
     }
   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 il colore dei segmenti delle candele                                    |
//+--------------------------------------------------------------------------------+
void  ChangeColors(color  &cols[],int plot_colors)
  {
//--- Il numero dei colori
   int size=ArraySize(cols);
//--- 
   string comm=ChartGetString(0,CHART_COMMENT)+"\r\n\r\n";
 
//--- Per ogni indice colore definisce un nuovo colore casualmente
   for(int plot_color_ind=0;plot_color_ind<plot_colors;plot_color_ind++)
     {
      //--- Ottiene un valore casuale
      int number=MathRand();
      //--- Ottiene un indice nell'array col[] come resto della divisione dell'intero
      int i=number%size;
      //--- Imposta il colore per ogni indice che ha proprietà PLOT_LINE_COLOR
      PlotIndexSetInteger(0,                    //  Il numero di stili grafici
                          PLOT_LINE_COLOR,      //  Identificatore proprietà
                          plot_color_ind,       //  Lìindice del colore, dove scriviamo il colore
                          cols[i]);             //  Un nuovo colore
      //--- Scrivi i colori
      comm=comm+StringFormat("CandleColorIndex[%d]=%s \r\n",plot_color_ind,ColorToString(cols[i],true));
      ChartSetString(0,CHART_COMMENT,comm);
     }
//---
  }
//+--------------------------------------------------------------------------------+
//| Cambia l'apparenza delle candele                                               |
//+--------------------------------------------------------------------------------+
void ChangeLineAppearance()
  {
//--- Una stringa per la formazione di informazioni sulle proprietà delle candele
   string comm="";
//--- Scrive il nome del simbolo
   comm="\r\n"+symbol+comm;
//--- Imposta le informazioni del grafico usando un commento
   Comment(comm);
  }