//+--------------------------------------------------------------------------------+ //| DRAW_BARS.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_BARS" #property description "Disegna le barre di un simbolo selezionato in una finestra separata" #property description "Il colore e lo spessore delle barre, così come il simbolo, vengono cambiati dinamicamente" #property description "ogni N ticks" #property indicator_separate_window #property indicator_buffers 4 #property indicator_plots 1 //--- plot Bars #property indicator_label1 "Bars" #property indicator_type1 DRAW_BARS #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 degli "Expert Advisors" //--- Buffer Indicatore double BarsBuffer1[]; double BarsBuffer2[]; double BarsBuffer3[]; double BarsBuffer4[]; //--- 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,BarsBuffer1,INDICATOR_DATA); SetIndexBuffer(1,BarsBuffer2,INDICATOR_DATA); SetIndexBuffer(2,BarsBuffer3,INDICATOR_DATA); SetIndexBuffer(3,BarsBuffer4,INDICATOR_DATA); //--- 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_BARS("+symbol+")"); //--- Un valore vuoto PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); //--- 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=0; //--- 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 le proprietà della linea ChangeLineAppearance(); int tries=0; //--- Fa 5 tentativi per riempire il buffer con i prezzi dal simbolo while(!CopyFromSymbolToBuffers(symbol,rates_total) && 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 i buffer indicatore con i prezzi | //+--------------------------------------------------------------------------------+ bool CopyFromSymbolToBuffers(string name,int total) { //--- 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(messages) PrintFormat("%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(0,PLOT_LABEL,name+" Open;"+name+" High;"+name+" Low;"+name+" Close"); IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_BARS("+name+")"); } //--- Inizializza i buffers con valori vuoti ArrayInitialize(BarsBuffer1,0.0); ArrayInitialize(BarsBuffer2,0.0); ArrayInitialize(BarsBuffer3,0.0); ArrayInitialize(BarsBuffer4,0.0); //--- Copia prezzi nei 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 BarsBuffer1[buffer_index]=rates[i].open; BarsBuffer2[buffer_index]=rates[i].high; BarsBuffer3[buffer_index]=rates[i].low; BarsBuffer4[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 della linea comm=comm+"\r\n"+(string)colors[color_index]; //--- Un blocco per il cambio della larghezza delle barre number=MathRand(); //--- Ottiene la larghezza del resto della divisione intera int width=number%5; // La larghezza è impostata da 0 a 4 //--- Imposta il colore come proprietà PLOT_LINE_WIDTH PlotIndexSetInteger(0,PLOT_LINE_WIDTH,width); //--- Scrive lo spessore della linea comm=comm+"\r\nWidth="+IntegerToString(width); //--- Scrive il nome del simbolo comm="\r\n"+symbol+comm; //--- Imposta le informazioni del grafico usando un commento Comment(comm); } |