
Manuale MQL5: Gestire gli eventi tipici dei grafici
Introduzione
Nel mio articolo vorrei descrivere le capacità e la pratica dell'utilizzo di OnChartEvent() con eventi tipici (standard) predefiniti dagli sviluppatori MQL5. Gli articoli MQL5 e Code Base contengono già esempi di utilizzo di questo gestore.
Tuttavia, il mio scopo è analizzare questo strumento nel contesto della programmazione orientata agli eventi (EOP). Credo che questo gestore possa essere utilizzato con successo per sistemi di trading completamente automatici e semi-automatici.
1. Evento "ChartEvent"
Quindi, prima vediamo cos'è questo tipo di evento.
Secondo la documentazione, l'evento ChartEvent può apparire quando si lavora con un grafico, in particolare quando:
- premendo un tasto sulla tastiera quando una finestra del grafico è a fuoco.
- creazione di un oggetto grafico.
- eliminazione di un oggetto grafico.
- cliccando su un oggetto grafico.
- trascinando un oggetto grafico con il mouse.
- finire di modificare il testo in un campo di testo di un oggetto grafico LabelEdit.
Pertanto, questo evento porta interattività e consente di interagire con un grafico. Inoltre, tale interazione può essere il risultato del trading manuale, oltre che di alcune operazioni algoritmiche (trading automatizzato).
Gli sviluppatori MQL5 classificano l'evento ChartEvent in base ai tipi specificati nell'enumerazione ENUM_CHART_EVENT.
È importante notare che questo elenco ha una gamma di eventi definiti dall'utente, che fungono da riserva nascosta, del quale il programmatore potrà fare uso. Gli sviluppatori MQL5 forniscono 65535 ID per eventi personalizzati.
Per lavorare con eventi personalizzati, è disponibile una funzione generatore speciale EventChartCustom() per le esigenze del programmatore. Tuttavia, questo articolo non considera gli eventi personalizzati.
2. Gestore e generatore di ChartEvent
Tutta l'elaborazione dell'evento ChartEvent viene eseguita da una speciale funzione di gestione OnChartEvent(). Ciò è coerente con il concetto di linguaggio MQL5, dove ad esempio l'evento Trade è gestito dalla funzione OnTrade(), l'evento Init è gestito dalla funzione OnInit(), ecc.
La funzione OnChartEvent() ha la seguente firma:
void OnChartEvent(const int id, // event identifier const long& lparam, // parameter of the event of type long const double& dparam, // parameter of the event of type double const string& sparam // parameter of the event of type string )
Tutti i parametri di input sono costanti e quando viene chiamato il gestore trasmettono alcune informazioni utili.
Pertanto, il valore del parametro id può rivelare quale particolare evento ha chiamato il gestore. Altri possono avere valori di tipo long, double e string. In questo modo è possibile ottenere ulteriori informazioni su un evento.
Successivamente, creeremo un esempio in cui i valori dei parametri specificati verranno utilizzati per analizzare cosa sta succedendo.
La parte personalizzata dell'evento ChartEvent, che deve essere implementata da un programmatore, è connessa alla funzione EventChartCustom(). Questa stessa funzione può generare l'evento. La firma della funzione è la seguente:
bool EventChartCustom(long chart_id, // receiving chart identifier ushort custom_event_id, // event identifier long lparam, // the long parameter double dparam, // the double parameter string sparam // the string parameter )
La funzione generatore, infatti, può creare un evento e inviarlo a qualsiasi grafico compreso quello corrente con qualsiasi valore dei parametri di input. Questi ultimi sono i tipi: ushort, long, double, string.
Le funzioni OnChartEvent() e EventChartCustom() insieme formano un potente strumento che è un buon esempio dei vantaggi della programmazione orientata agli eventi.
3. Modello di elaborazione degli eventi standard
Ora prenderò in considerazione i tipi di eventi del grafico e fornirò un esempio per ciascuno di essi. Ogni evento avrà la sua versione dedicata di EventProcessor.mq5 e il suo codice conterrà la gestione di un evento grafico. Ci sono 10 eventi tipici in MQL5.
Per tre di essi (evento del mouse, evento di creazione di oggetti grafici, evento di rimozione di oggetti grafici) dobbiamo preparare un grafico. Può essere eseguito utilizzando la funzione ChartSetInteger(). Consente a un grafico di rispondere a eventi specificati.
Un tipico blocco per l'elaborazione degli eventi del grafico potrebbe assomigliare a:
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { string comment="Last event: "; //--- select event on chart switch(id) { //--- 1 case CHARTEVENT_KEYDOWN: { comment+="1) keystroke"; break; } //--- 2 case CHARTEVENT_MOUSE_MOVE: { comment+="2) mouse"; break; } //--- 3 case CHARTEVENT_OBJECT_CREATE: { comment+="3) create graphical object"; break; } //--- 4 case CHARTEVENT_OBJECT_CHANGE: { comment+="4) change object properties via properties dialog"; break; } //--- 5 case CHARTEVENT_OBJECT_DELETE: { comment+="5) delete graphical object"; break; } //--- 6 case CHARTEVENT_CLICK: { comment+="6) mouse click on chart"; break; } //--- 7 case CHARTEVENT_OBJECT_CLICK: { comment+="7) mouse click on graphical object"; break; } //--- 8 case CHARTEVENT_OBJECT_DRAG: { comment+="8) move graphical object with mouse"; break; } //--- 9 case CHARTEVENT_OBJECT_ENDEDIT: { comment+="9) finish editing text"; break; } //--- 10 case CHARTEVENT_CHART_CHANGE: { comment+="10) modify chart"; break; } } //--- Comment(comment); }
In ogni caso ho aggiunto la stringa che descrive un evento selezionato. Di conseguenza, nella riga dei commenti possiamo vedere l'ultimo evento accaduto sul grafico. Se esegui il modello ed esegui varie manipolazioni con il grafico, noterai che la riga di commento potrebbe avere record diversi.
Ovviamente, si fa poco uso di un tale Expert Advisor che determina solo il tipo di evento. Dobbiamo ampliare le sue capacità.
4. Esempi di elaborazione di eventi standard
4.1. Evento di battitura
Prendiamo il primo caso e lavoriamo con i pulsanti sulla tastiera, in modo che il nostro EA risponda alle sequenze di tasti. Lascia che compri quando premi la "freccia su" e vendi quando premi la "freccia giù". Quindi questo caso sarà il seguente:
//--- 1 case CHARTEVENT_KEYDOWN: { //--- "up" arrow if(lparam==38) TryToBuy(); //--- "down" arrow else if(lparam==40) TryToSell(); comment+="1) keystroke"; //--- break; }
Vedere il codice sorgente EA allegato per i dettagli sull'implementazione di TryToBuy() e TryToSell(). I parametri di trading (lot size, Stop Loss, Take Profit, ecc.) sono specificati come variabili di input (InpLot, InpStopLoss, InpTakeProfit, ecc.). Va anche detto che il parametro lparam ottiene il codice del tasto premuto.
La versione aggiornata dell'EA si chiama EventProcessor1.mq5.
4.2. Evento del mouse
Questo tipo di evento verrà gestito solo se è stata specificata la proprietà CHART_EVENT_MOUSE_MOVE per il grafico. Per questo motivo il blocco di inizializzazione dell'EA contiene tali stringhe:
//--- mouse move bool is_mouse=false; if(InpIsEventMouseMove) is_mouse=true; ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,is_mouse);
Va notato che se usi un mouse, allora, naturalmente, si verificherà spesso un evento del mouse. Per questo motivo può essere utile avere la possibilità di disabilitare l'elaborazione di questo evento. I parametri lparam e dparam del gestore riportano le coordinate X e Y a seconda dei casi.
Discuteremo ora un esempio inventato. Supponiamo che ci sia uno spostamento della barra zero dal bordo destro. Passando il cursore sulla parte dello schermo a destra dello spostamento verrà visualizzata una finestra che suggerisce di acquistare o vendere.
Per farlo dobbiamo prima determinare lo spostamento. Introdurremo una variabile di input per determinare la dimensione di uno spostamento della barra zero dal bordo destro in percentuale (InpChartShiftSize).
Fig.1 Finestra di un'operazione di trading
Utilizzeremo le funzioni che abilitano lo spostamento e ne determineremo la dimensione ChartShiftSet() e ChartShiftSizeSet(). Quindi identificheremo se la coordinata X del cursore era precedentemente a sinistra dal bordo e se si è spostata a destra. In caso affermativo, apparirà una finestra che suggerisce di acquistare/vendere (Fig.1).
Il codice che implementa l'obiettivo impostato è simile a:
//--- 2 case CHARTEVENT_MOUSE_MOVE: { comment+="2) mouse"; //--- if a mouse event is processed if(InpIsEventMouseMove) { long static last_mouse_x; //--- enable shift if(ChartShiftSet(true)) //--- set shift size if(ChartShiftSizeSet(InpChartShiftSize)) { //--- chart width int chart_width=ChartWidthInPixels(); //--- calculate X coordinate of shift border int chart_shift_x=(int)(chart_width-chart_width*InpChartShiftSize/100.); //--- border crossing condition if(lparam>chart_shift_x && last_mouse_x<chart_shift_x) { int res=MessageBox("Yes: buy / No: sell","Trade operation",MB_YESNO); //--- buy if(res==IDYES) TryToBuy(); //--- sell else if(res==IDNO) TryToSell(); } //--- store mouse X coordinate last_mouse_x=lparam; } } //--- break; }
L'acquisto e la vendita vengono effettuati dalle funzioni di trading create in precedenza. La versione aggiornata dell'EA si chiamerà EventProcessor2.mq5.
4.3. Evento di creazione di oggetti grafici
Questo tipo di evento viene generato quando viene creato un oggetto su un grafico. Simile a un evento del mouse, questo tipo deve ricevere un'autorizzazione per la gestione con la proprietà CHART_EVENT_OBJECT_CREATE. Deve essere specificato solo una volta nel blocco di inizializzazione se vogliamo rispondere alla comparsa di un nuovo oggetto grafico.
//--- object create bool is_obj_create=false; if(InpIsEventObjectCreate) is_obj_create=true; ChartSetInteger(0,CHART_EVENT_OBJECT_CREATE,is_obj_create);
Solo un parametro del gestore conterrà informazioni. È un parametro di stringa sparam che contiene il nome dell'oggetto grafico creato. Possiamo trovare quell'oggetto in base al nome, gestirlo e poi decidere cosa fare dopo.
Qui c'è un semplice esempio. Disegneremo una linea orizzontale sul grafico e lasceremo che il robot la posizioni al prezzo massimo di tutte le barre riflesse sul grafico e disegneremo altre due linee. La riga inferiore sarà posta al prezzo minimo e la terza riga sarà tra le prime due equidistanti da entrambe.
Il codice per l'implementazione dell'attività:
//--- 3 case CHARTEVENT_OBJECT_CREATE: { comment+="3) create graphical object"; //--- if graphical object creation event is processed if(InpIsEventObjectCreate) { //--- capture creation of horizontal line int all_hor_lines=ObjectsTotal(0,0,OBJ_HLINE); //--- if this is the only line if(all_hor_lines==1) { string hor_line_name1=sparam; //--- calculate levels int visible_bars_num=ChartVisibleBars(); //--- arrays for high and low prices double highs[],lows[]; //--- int copied=CopyHigh(_Symbol,_Period,0,visible_bars_num-1,highs); if(copied!=visible_bars_num-1) { Print("Failed to copy highs!"); return; } copied=CopyLow(_Symbol,_Period,0,visible_bars_num-1,lows); if(copied!=visible_bars_num-1) { Print("Failed to copy lows!"); return; } //--- high and low prices double ch_high_pr,ch_low_pr,ch_mid_pr; //--- ch_high_pr=NormalizeDouble(highs[ArrayMaximum(highs)],_Digits); ch_low_pr=NormalizeDouble(lows[ArrayMinimum(lows)],_Digits); ch_mid_pr=NormalizeDouble((ch_high_pr+ch_low_pr)/2.,_Digits); //--- place created line on high if(ObjectFind(0,hor_line_name1)>-1) if(!ObjectMove(0,hor_line_name1,0,0,ch_high_pr)) { Print("Failed to move!"); return; } //--- create line on low string hor_line_name2="Hor_line_min"; //--- if(!ObjectCreate(0,hor_line_name2,OBJ_HLINE,0,0,ch_low_pr)) { Print("Failed to create the 2nd horizontal line!"); return; } //--- create line between high and low string hor_line_name3="Hor_line_mid"; //--- if(!ObjectCreate(0,hor_line_name3,OBJ_HLINE,0,0,ch_mid_pr)) { Print("Failed to create the 3rd horizontal line!"); return; } } } break; }
Il nome della versione aggiornata dell'EA è EventProcessor3.mq5.
Fig. 2. Risultato della gestione dell'evento di creazione di un oggetto grafico
Dopo aver completato la procedura, ho ricevuto la seguente immagine (Fig. 2). Quindi, le funzioni integrate danno a un EA la capacità di reagire alla creazione di un oggetto grafico e quindi agire su di esso.
4.4. Evento di modifica delle proprietà di un oggetto grafico tramite una finestra di dialogo delle proprietà
Questo tipo di evento è parzialmente simile al precedente. Si attiva quando una delle proprietà di un oggetto grafico viene modificata tramite una finestra di dialogo delle proprietà. Questo strumento potrebbe essere utile, ad esempio, per la sincronizzazione delle proprietà grafiche di oggetti dello stesso tipo.
Immagina un numero di alcuni oggetti su un grafico. Un trader di solito ha molte linee diverse su un grafico. Queste righe devono essere rese invisibili per un po' di tempo senza essere eliminate. Troveremo una soluzione a questo compito. La linea modificata può essere decolorata e lo stesso può essere fatto su altri oggetti grafici. Quindi il codice potrebbe essere il seguente:
//--- 4 case CHARTEVENT_OBJECT_CHANGE: { comment+="4) change object properties via properties dialog"; //--- string curr_obj_name=sparam; //--- find the changed object if(ObjectFind(0,curr_obj_name)>-1) { //--- get object color color curr_obj_color=(color)ObjectGetInteger(0,curr_obj_name,OBJPROP_COLOR); //--- total number of objects on chart int all_other_objects=ObjectsTotal(0); //--- find other objects for(int obj_idx=0;obj_idx<all_other_objects;obj_idx++) { string other_obj_name=ObjectName(0,obj_idx); if(StringCompare(curr_obj_name,other_obj_name)!=0) if(!ObjectSetInteger(0,other_obj_name,OBJPROP_COLOR,curr_obj_color)) { Print("Failed to change the object color!"); return; } } //--- redraw chart ChartRedraw(); } //--- break;
Supponiamo che ci sia un insieme di linee sul grafico (Fig.3).
Fig.3. Linee dinamiche multicolori
Se proviamo a cambiare il colore di una qualsiasi delle linee, o per essere precisi, a decolorarla (Fig.4) nella finestra di dialogo delle proprietà, non ci saranno linee visibili sul grafico. Allo stesso tempo, gli oggetti grafici saranno ancora presenti lì.
Fig.4. Modificare il colore di una linea
La versione aggiornata dell'EA si chiama EventProcessor4.mq5.
4.5. Evento di cancellazione di oggetti grafici
Come suggerisce il nome di questo tipo di evento, appare all'eliminazione di un oggetto da un grafico. È l'ultimo evento di un gruppo, che richiede un'autorizzazione preventiva diretta per la gestione. Può essere fatto tramite la proprietà CHART_EVENT_OBJECT_DELETE.
//--- object delete bool is_obj_delete=false; if(InpIsEventObjectDelete) is_obj_delete=true; ChartSetInteger(0,CHART_EVENT_OBJECT_DELETE,is_obj_delete);
Ecco un altro esempio ipotetico. Sul grafico in cui è allegato il tuo EA, c'è una serie di oggetti grafici di diversi tipi. Supponiamo di dover eliminare oggetti di un solo tipo particolare. Ad esempio, linee verticali (Fig.5).
Fig.5. Cinque verticali e altre linee
Dobbiamo rimuovere solo una verticale e l'Esperto rimuoverà le altre (Fig.6).
Fig.6. Linee rimanenti
Le seguenti voci appariranno nel registro "Esperti":
NS 0 10:31:17.937 EventProcessor5 (EURUSD.e,W1) Vertical lines before removing: 4 MD 0 10:31:17.937 EventProcessor5 (EURUSD.e,W1) Vertical lines removed from the chart: 4 QJ 0 10:31:18.078 EventProcessor5 (EURUSD.e,W1) Vertical lines after removing: 0
Un aspetto importante deve essere menzionato. Una volta rimosso un oggetto, non è possibile accedere alle sue proprietà. Significa che se non recuperiamo in anticipo i dati richiesti sull'oggetto, non sarà accessibile dopo che è stato rimosso. Pertanto, se abbiamo bisogno di scoprire il tipo di un oggetto rimosso, dobbiamo memorizzarlo prima che l'oggetto stesso venga rimosso. Ho un suggerimento per gli sviluppatori MQL5 di creare una cronologia di un grafico disponibile nel terminale. Questo ci permetterà di fare riferimento alle proprietà degli oggetti rimossi.
Chiameremo l'ultima versione di Expert EventProcessor5.mq5.
4.6. Evento di clic del mouse sul grafico
Questo evento verrà generato se si fa clic sul grafico con il tasto sinistro del mouse. Fare clic con il pulsante destro del mouse sul grafico per aprire un menu di scelta rapida e facendo clic con il pulsante centrale verrà visualizzato un mirino. I parametri lparam e dparam del gestore riportano le coordinate X e Y a seconda dei casi.
Il seguente semplice compito servirà come esempio. Dobbiamo fare in modo che una freccia 'acquista' venga disegnata nel punto in cui avviene il clic del mouse. L'oggetto 'freccia' ha un solo punto di ancoraggio. Di conseguenza è necessaria una sola trasformazione delle coordinate X e Y ai valori del tempo e del prezzo del punto di ancoraggio.
Il codice per l'esempio sopra:
//--- 6 case CHARTEVENT_CLICK: { comment+="6) mouse click on chart"; //--- object counter static uint sign_obj_cnt; string buy_sign_name="buy_sign_"+IntegerToString(sign_obj_cnt+1); //--- coordinates int mouse_x=(int)lparam; int mouse_y=(int)dparam; //--- time and price datetime obj_time; double obj_price; int sub_window; //--- convert the X and Y coordinates to the time and price values if(ChartXYToTimePrice(0,mouse_x,mouse_y,sub_window,obj_time,obj_price)) { //--- create object if(!ObjectCreate(0,buy_sign_name,OBJ_ARROW_BUY,0,obj_time,obj_price)) { Print("Failed to create buy sign!"); return; } //--- redraw chart ChartRedraw(); //--- increase object counter sign_obj_cnt++; } //--- break; }
La versione corrente dell'esperto è denominata EventProcessor6.mq5.
4.7. Evento di clic del mouse su un oggetto grafico
Questo tipo di eventi del grafico differisce dal precedente solo per il fatto che un clic del mouse avviene su un oggetto grafico. Il parametro stringa sparam conterrà il nome dell'oggetto cliccato. Nell'esempio precedente abbiamo creato le frecce 'acquista'. Facciamo in modo che un clic sull'oggetto di questo tipo lo trasformi in una freccia di "vendita".
Il codice di questo blocco del gestore può essere simile a:
//--- 7 case CHARTEVENT_OBJECT_CLICK: { comment+="7) mouse click on graphical object"; //--- string sign_name=sparam; //--- delete buy arrow if(ObjectDelete(0,sign_name)) { //--- redraw chart ChartRedraw(); //--- static uint sign_obj_cnt; string sell_sign_name="sell_sign_"+IntegerToString(sign_obj_cnt+1); //--- coordinates int mouse_x=(int)lparam; int mouse_y=(int)dparam; //--- time and price datetime obj_time; double obj_price; int sub_window; //--- convert the X and Y coordinates to the time and price values if(ChartXYToTimePrice(0,mouse_x,mouse_y,sub_window,obj_time,obj_price)) { //--- create object if(!ObjectCreate(0,sell_sign_name,OBJ_ARROW_SELL,0,obj_time,obj_price)) { Print("Failed to create sell sign!"); return; } //--- redraw chart ChartRedraw(); //--- increase object counter sign_obj_cnt++; } } //--- break; }
Per il bene di questo esempio ho mantenuto intatto il caso della gestione del clic del mouse. Avviando l'EA, ho fatto clic con il pulsante sinistro del mouse tre volte e ho ottenuto tre frecce da acquistare (Fig.7). Ho evidenziato la loro posizione in giallo.
Fig.7. "Compra" frecce
Se ora clicchiamo su ciascuna freccia 'acquista', riceveremo la seguente immagine (Fig.8).
Fig.8. Frecce "Compra" e "vendi"
Le frecce "Vendi" sono apparse come previsto, ma le frecce "Compra" non erano progettate per apparire. C'è un motivo per cui sto portando un elenco di oggetti sul grafico in cui ho evidenziato in giallo i nomi delle frecce "compra".
È facile notare che l'EA ha creato la 4a, la 5a e la 6a freccia "compra". Perché è successo? È successo perché il primo clic sull'oggetto ha attivato due eventi: il primo è stato il clic effettivo sull'oggetto e il secondo - un clic sul grafico. L'ultimo evento genera la creazione di una freccia 'acquista'. Qui sorge la necessità di aggiungere un meccanismo che impedisca la gestione del secondo evento, che è un clic sul grafico. Mi sembra che il controllo del tempo possa svolgere tale funzione.
Aggiungiamo una variabile globale gLastTime. Faciliterà un controllo sul tempo di creazione di una freccia "acquista". Se un semplice click handler viene chiamato per meno di 250 ms dopo che è stata creata una freccia 'sell', allora questa chiamata deve essere passata.
Prima che il grafico venga ridisegnato, la stringa sottostante deve essere aggiunta al blocco di gestione di un clic sull'oggetto:
//--- store the moment of creation gLastTime=GetTickCount();
La verifica del tempo va aggiunta al blocco di movimentazione con un click sul grafico.
uint lastTime=GetTickCount(); if((lastTime-gLastTime)>250) { //--- click handling }
Creiamo ancora tre frecce sul grafico del tipo 'buy' (Fig.9).
Fig.9. "Compra" frecce
Cercheremo di cliccarci sopra nonostante le loro piccole dimensioni. Le frecce si sono trasformate in 'vendi' al clic (Fig.10).
Fig.10. Frecce "vendi"
Simile a quelli precedenti, chiameremo la nuova versione EventProcessor7.mq5.
4.8. Evento di spostamento di un oggetto grafico con il mouse
Questo evento si verifica quando un oggetto viene spostato all'interno di un'area del grafico. Il gestore riceve il nome dell'oggetto spostato sotto forma di un parametro stringa sparam.
Ecco un altro esempio. I trader intraday molto spesso fanno trading entro un certo intervallo di tempo. Le linee verticali saranno i limiti di un intervallo di tempo. L'immagine assomiglierà approssimativamente alla Fig.11. L'intervallo di interesse è evidenziato.
Fig.11. Limiti di un intervallo di tempo
L'intervallo di tempo può essere modificato manualmente. Quindi il nostro semi-automa dovrà reagire a un tale cambiamento.
A livello globale creeremo delle variabili che descrivono i nomi dei due verticali - gTimeLimit1_name e gTimeLimit2_name. Dobbiamo anche creare un paio di variabili per i nomi dei rettangoli, che oscurano il tempo di non negoziazione sul grafico. Dovranno essere create anche le variabili globali per i punti di ancoraggio. Poiché abbiamo due rettangoli, avremo quattro punti.
Il codice del caso del gestore CHARTEVENT_OBJECT_DRAG:
//--- 8 case CHARTEVENT_OBJECT_DRAG: { comment+="8) move graphical object with mouse"; string curr_obj_name=sparam; //--- if one of the vertical lines is moved if(!StringCompare(curr_obj_name,gTimeLimit1_name) || !StringCompare(curr_obj_name,gTimeLimit2_name)) { //--- the time coordinate of vertical lines datetime time_limit1=0; datetime time_limit2=0; //--- find the first vertical line if(ObjectFind(0,gTimeLimit1_name)>-1) time_limit1=(datetime)ObjectGetInteger(0,gTimeLimit1_name,OBJPROP_TIME); //--- find the second vertical line if(ObjectFind(0,gTimeLimit2_name)>-1) time_limit2=(datetime)ObjectGetInteger(0,gTimeLimit2_name,OBJPROP_TIME); //--- if vertical lines are found if(time_limit1>0 && time_limit2>0) if(time_limit1<time_limit2) { //--- update properties of rectangles datetime start_time=time_limit1; datetime finish_time=time_limit2; //--- if(RefreshRecPoints(start_time,finish_time)) { //--- if(!ObjectMove(0,gRectLimit1_name,0,gRec1_time1,gRec1_pr1)) { Print("Failed to move the 1st point!"); return; } if(!ObjectMove(0,gRectLimit1_name,1,gRec1_time2,gRec1_pr2)) { Print("Failed to move the 2nd point!"); return; } //--- if(!ObjectMove(0,gRectLimit2_name,0,gRec2_time1,gRec2_pr1)) { Print("Failed to move the 1st point!"); return; } if(!ObjectMove(0,gRectLimit2_name,1,gRec2_time2,gRec2_pr2)) { Print("Failed to move the 2nd point!"); return; } } } } //--- break; }
Questo codice contiene una funzione personalizzata RefreshRecPoints(). Si tratta di aggiornare i valori dei punti di ancoraggio per due rettangoli. Il blocco dell'inizializzazione EA può fornire informazioni sulla creazione di oggetti grafici. La versione aggiornata si chiamerà EventProcessor8.mq5.
4.9. Fine della modifica di un testo nell'evento del campo di testo
Questo tipo di evento ha una natura altamente specializzata e compare quando si modifica il testo nel campo di inserimento dati. Il parametro sparam contiene il nome dell'oggetto su cui si lavora.
Ecco un esempio da considerare. Nel campo di inserimento dati inseriremo l'operazione di trading che stiamo per eseguire. Lascia che ci siano solo due operazioni: compra e vendi. Se inseriamo la parola 'Acquista' nel campo di immissione, l'EA acquisterà un asset e se inseriamo 'Sell', l'asset verrà venduto. Faremo in modo che questo campo non faccia distinzione tra maiuscole e minuscole, ovvero possiamo digitare "comprare" e "vendere". Il testo e il campo di input saranno colorati di rosso in vendita e blu in acquisto (Fig.12).
Fig.12. Acquista attraverso il campo di testo
Il codice nel caso CHARTEVENT_OBJECT_ENDEDIT:
//--- 9 case CHARTEVENT_OBJECT_ENDEDIT: { comment+="9) end of editing a text in the data entry field"; //--- string curr_obj_name=sparam; //--- if specified text field is being edited if(!StringCompare(curr_obj_name,gEdit_name)) { //--- get object description string obj_text=NULL; if(ObjectGetString(0,curr_obj_name,OBJPROP_TEXT,0,obj_text)) { //--- check value if(!StringCompare(obj_text,"Buy",false)) { if(TryToBuy()) //--- set text color ObjectSetInteger(0,gEdit_name,OBJPROP_COLOR,clrBlue); } else if(!StringCompare(obj_text,"Sell",false)) { if(TryToSell()) //--- set text color ObjectSetInteger(0,gEdit_name,OBJPROP_COLOR,clrRed); } else { //--- set text color ObjectSetInteger(0,gEdit_name,OBJPROP_COLOR,clrGray); } //--- redraw chart ChartRedraw(); } } //--- break; }
La versione aggiornata dell'EA si chiama EventProcessor9.mq5. Puoi trovare il blocco della creazione del campo di testo nel file sorgente.
4.10. Evento di modifica del grafico
L'ultimo evento che considereremo in questo articolo è legato alla modifica delle impostazioni del grafico. Questo è un evento particolare perché a questo punto ci occupiamo del grafico stesso, non degli oggetti sul grafico. Gli sviluppatori affermano che questo evento viene generato quando viene modificata la dimensione di un grafico o viene introdotta una nuova impostazione.
Ecco un altro esempio. Supponiamo che ci sia il divieto di alterare alcune delle impostazioni del grafico. Quindi tutti i tentativi di modificare le impostazioni sotto restrizione verranno ignorati. In effetti, l'EA restituirà semplicemente i valori precedenti. Esistono i seguenti parametri dell'oggetto "Chart":
- griglia di visualizzazione;
- tipo di visualizzazione del grafico;
- Colore dello sfondo
Codice per questo caso:
//--- 10 case CHARTEVENT_CHART_CHANGE: { //--- current height and width of the chart int curr_ch_height=ChartHeightInPixelsGet(); int curr_ch_width=ChartWidthInPixels(); //--- if chart height and width have not changed if(gChartHeight==curr_ch_height && gChartWidth==curr_ch_width) { //--- fix the properties: //--- display grid if(!ChartShowGridSet(InpToShowGrid)) { Print("Failed to show grid!"); return; } //--- type of chart display if(!ChartModeSet(InpMode)) { Print("Failed to set mode!"); return; } //--- background color if(!ChartBackColorSet(InpBackColor)) { Print("Failed to set background сolor!"); return; } } //--- store window dimensions else { gChartHeight=curr_ch_height; gChartWidth=curr_ch_width; } //--- comment+="10) modify chart"; //--- break; }
L'ultima versione si chiamerà EventProcessor10.mq5.
Conclusione
In questo articolo ho cercato di illustrare la diversità degli eventi tipici dei grafici in MetaTrader 5. Spero che questi esempi di gestione degli eventi saranno utili per i programmatori che iniziano a programmare in MQL5.
Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/689





- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Accetti la politica del sito e le condizioni d’uso