MQL5 Cookbook : Gestion des événements du graphique typiques
Introduction
Dans mon article, je voudrais décrire les capacités et la pratique de l'utilisation d'OnChartEvent() avec des événements (standard) typiques prédéfinis par les développeurs MQL5. Les articles MQL5 et Code Base contiennent déjà des exemples d'utilisation de ce gestionnaire.
Cependant, mon but est d'analyser cet instrument dans le contexte de la programmation orientée événement (EOP). Je pense que ce gestionnaire peut être utilisé avec succès pour les systèmes de trading entièrement automatiques et semi-automatiques.
1. Événement "ChartEvent"
Voyons donc d'abord ce qu'est ce type d'événement.
Selon la Documentation, l'événement ChartEvent peut apparaître lors de l'utilisation d'un graphique, notamment lors de :
- l’appui sur une touche du clavier lorsqu'une fenêtre graphique est active.
- la création d’un objet graphique.
- la suppression un objet graphique.
- le clic sur un objet graphique.
- le glissement d’un objet graphique avec une souris.
- la finition pour l'édition de texte dans un champ de texte d'un objet graphique LabelEdit.
Ainsi, cet événement apporte de l'interactivité et permet d'interagir avec un graphique. De plus, une telle interaction peut être le résultat d'un trading manuel, ainsi que de certaines opérations algorithmiques (trading automatisé).
Les développeurs MQL5 classent l'événement ChartEvent par types spécifiés dans l'énumération ENUM_CHART_EVENT.
Il est important de noter que cette liste contient une gamme d'événements définis par l'utilisateur, qui agissent comme une réserve cachée pour servir le programmeur. Les développeurs MQL5 fournissent 65535 ID pour les événements personnalisés.
Pour travailler avec des événements personnalisés, une fonction de générateur spéciale EventChartCustom() est disponible pour les besoins du programmeur. Cependant, cet article ne prend pas en compte les événements personnalisés.
2. Gestionnaire et générateur de ChartEvent
Tout le traitement de l'événement ChartEvent est effectué par une fonction de gestion spéciale OnChartEvent(). Ceci est cohérent avec le concept du langage MQL5, où par exemple l'événement Trade est géré par la fonction OnTrade(), l'événement Init est géré par la fonction OnInit(), etc.
La fonction OnChartEvent() a la signature suivante :
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 )
Tous les paramètres d'entrée sont constants et lorsque le gestionnaire est appelé, ils transmettent des informations utiles.
Ainsi, la valeur du paramètre id peut révéler quel événement particulier a appelé le gestionnaire. D'autres peuvent avoir des valeurs de types long, double et string. De cette façon, des informations supplémentaires sur un événement peuvent être obtenues.
Plus tard, nous créerons un exemple où les valeurs des paramètres spécifiés seront utilisées pour analyser ce qui se passe.
La partie personnalisée de l'événement ChartEvent, qui doit être implémentée par un programmeur, est connectée à la fonction EventChartCustom(). Cette fonction même peut générer l'événement. La signature de la fonction est la suivante :
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 )
En fait, la fonction génératrice peut créer un événement et l'envoyer à n'importe quel graphique, y compris le graphique actuel avec toutes les valeurs des paramètres d'entrée. Ces derniers sont les types : ushort, long, double, string.
Les fonctions OnChartEvent() et EventChartCustom() forment ensemble un outil puissant qui est un bon exemple des avantages de la programmation orientée événement.
3. Modèle de traitement d'événement standard
Maintenant, je vais considérer les types des événements du graphique et donner un exemple pour chacun d'eux. Chaque événement aura sa propre version dédiée de EventProcessor.mq5 et son code contiendra la gestion d'un événement du graphique. Il y a 10 événements typiques dans MQL5.
Pour trois d'entre eux (événement de souris, événement de création d'objet graphique, événement de suppression d'objet graphique), nous devons préparer un graphique. Cela peut être fait en utilisant la fonction ChartSetInteger(). Il permet à un graphique de répondre à des événements spécifiés.
Un bloc typique pour le traitement des événements du graphique pourrait ressembler à :
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); }
Dans chaque cas, j'ai ajouté la chaîne décrivant un événement sélectionné. En conséquence, dans la ligne de commentaire, nous pouvons voir le dernier événement survenu sur le graphique. Si vous exécutez le modèle et effectuez diverses manipulations avec le graphique, vous remarquerez que la ligne de commentaire peut avoir des enregistrements différents.
Évidemment, il y a peu d'utilité d'un tel Expert Advisor qui ne détermine que le type d'événement. Nous devons étendre ses capacités.
4. Exemples de traitement d'événement standard
4.1. Événement de frappe de clavier
Prenons le premier cas et travaillons avec les boutons du clavier, afin que notre EA réponde aux frappes au clavier. Laissez-le acheter en appuyant sur la "flèche vers le haut" et vendre en appuyant sur la "flèche vers le bas". Alors ce cas ressemblera à ceci :
//--- 1 case CHARTEVENT_KEYDOWN: { //--- "up" arrow if(lparam==38) TryToBuy(); //--- "down" arrow else if(lparam==40) TryToSell(); comment+="1) keystroke"; //--- break; }
Voir le code source EA ci-joint pour plus de détails sur l'implémentation TryToBuy() et TryToSell(). Les paramètres de trading (taille du lot, Stop Loss, Take Profit, etc.) sont spécifiés en tant que variables d'entrée (InpLot, InpStopLoss, InpTakeProfit, etc.). Il convient également de mentionner que le paramètre lparam obtient le code de la touche enfoncée.
La version mise à jour de l'EA s'appelle EventProcessor1.mq5.
4.2. Événement de souris
Ce type d'événement ne sera géré que si la propriété CHART_EVENT_MOUSE_MOVE a été spécifiée pour le graphe. Pour cette raison, le bloc d'initialisation de l'EA contient de telles chaînes de caractères :
//--- mouse move bool is_mouse=false; if(InpIsEventMouseMove) is_mouse=true; ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,is_mouse);
Il convient de noter que si vous utilisez une souris, alors, naturellement, un événement souris aura souvent lieu. Pour cette raison, une opportunité de désactiver le traitement de cet événement peut être utile. Les paramètres lparam et dparam du gestionnaire rapportent les coordonnées X et Y en conséquence.
Nous allons discuter d'un exemple inventé. Supposons qu'il y ait un décalage de zéro barre à partir du bord droit. En passant le curseur sur la partie de l'écran située à droite du décalage, vous ferez apparaître une fenêtre vous proposant d'acheter ou de vendre.
Pour ce faire, nous devons d'abord déterminer le décalage. Nous allons introduire une variable d'entrée pour déterminer la taille d'un décalage de la barre zéro à partir de la bordure droite en pourcentages (InpChartShiftSize).
Fig.1 Fenêtre d'une opération de trade
Nous allons utiliser les fonctions qui activent le décalage et déterminent sa taille ChartShiftSet() et ChartShiftSizeSet(). Ensuite, nous identifierons si l'abscisse du curseur était auparavant à gauche de la bordure et si elle s'est déplacée vers la droite. Si c'est le cas, une fenêtre suggérant d'acheter/vendre apparaîtra (Fig.1).
Le code implémentant la cible définie ressemble à :
//--- 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'achat et la vente se font par les fonctions de trade précédemment créées. La version mise à jour de l'EA sera nommée EventProcessor2.mq5.
4.3. Événement de création d'objet graphique
Ce type d'événement est généré lorsqu'un objet est créé sur un graphique. Semblable à un événement de souris, ce type doit recevoir une autorisation de gestion avec la propriété CHART_EVENT_OBJECT_CREATE. Il n'a besoin d'être spécifié qu'une seule fois dans le bloc d'initialisation si l'on va répondre à l'apparition d'un nouvel objet graphique.
//--- object create bool is_obj_create=false; if(InpIsEventObjectCreate) is_obj_create=true; ChartSetInteger(0,CHART_EVENT_OBJECT_CREATE,is_obj_create);
Un seul paramètre du gestionnaire va contenir des informations. C'est un paramètre de chaîne sparam qui contient le nom de l'objet graphique créé. Nous pouvons trouver cet objet par son nom, le traiter et ensuite décider quoi faire ensuite.
Voici un exemple simple. Nous allons tracer une ligne horizontale sur le graphique et laisser le robot la placer au prix maximum de toutes les barres reflétées sur le graphique et tracer deux autres lignes. La ligne inférieure sera placée au prix minimum et la troisième ligne sera entre les deux premières à égale distance des deux.
Le code pour la mise en œuvre de la tâche :
//--- 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; }
Le nom de la version mise à jour de l'EA est EventProcessor3.mq5.
Fig. 2. Résultat de la gestion de l'événement de création d'objet graphique
Après avoir terminé la procédure, j'ai reçu l'image suivante (Fig. 2). Ainsi, les fonctions intégrées donnent à un EA la capacité de réagir à la création d'un objet graphique et d'agir ensuite dessus.
4.4. Événement de modification des propriétés d'un objet graphique via une boîte de dialogue Propriétés
Ce type d'événement est partiellement similaire au précédent. Il se déclenche lorsque l'une des propriétés d'un objet graphique est modifiée via une boîte de dialogue de propriétés. Cet outil peut être utile, par exemple, pour synchroniser les propriétés graphiques d'objets du même type.
Imaginez un certain nombre d'objets sur un graphique. Un trader a généralement beaucoup de lignes différentes sur un graphique. Ces lignes doivent être rendues invisibles pendant un certain temps sans être supprimées. Nous allons trouver une solution à cette tâche. La ligne modifiée peut être décolorée et la même chose peut être faite pour d'autres objets graphiques. Le code pourrait alors être le suivant :
//--- 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;
Supposons qu'il y ait un ensemble de lignes sur le graphique (Fig.3).
Fig.3. Lignes dynamiques multicolores
Si nous essayons de changer la couleur de l'une des lignes, ou pour être précis, la décolorer (Fig.4) dans la boîte de dialogue des propriétés, alors il n'y aura aucune ligne visible sur le graphique. En même temps, les objets graphiques y seront toujours présents.
Fig.4. Changement d’une couleur de ligne
La version mise à jour de l'EA s'appelle EventProcessor4.mq5.
4.5. Événement de suppression d'objet graphique
Comme le nom de ce type d'événement l'indique, il apparaît lors de la suppression d'un objet d'un graphique. C'est le dernier événement d'un groupe, qui nécessite une autorisation préalable directe pour la manipulation. Cela peut être fait via la propriété 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);
Voici un autre exemple hypothétique. Sur le graphique où votre EA est attaché, il y a un ensemble d'objets graphiques de différents types. Supposons que nous ayons besoin de supprimer des objets d'un seul type particulier. Par exemple, les lignes verticales (Fig.5).
Fig.5. Cinq verticales et autres lignes
Nous n'avons besoin de supprimer qu'une seule verticale et l'expert supprimera les autres (Fig.6).
Fig.6. Lignes restantes
Les entrées suivantes apparaîtront dans le registre "Experts" :
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 aspect important doit être mentionné. Une fois qu'un objet est supprimé, il n'y a plus d'accès à ses propriétés. Cela signifie que si nous ne récupérons pas les données requises sur l'objet au préalable, il ne sera pas accessible après sa suppression. Par conséquent, si nous avons besoin de connaître le type d'un objet supprimé, nous devons le stocker avant que l'objet lui-même ne soit supprimé. J'ai une suggestion pour les développeurs MQL5 de créer un historique d'un graphique disponible dans le terminal. Cela nous permettra de nous référer aux propriétés des objets supprimés.
Nous appellerons la dernière version de l'Expert EventProcessor5.mq5.
4.6. Événement de clic de souris sur le graphique
Cet événement sera généré si le graphique est cliqué avec le bouton gauche de la souris. Un clic droit sur le graphique ouvrira un menu contextuel et un clic avec le bouton du milieu fera apparaître un réticule. Les paramètres lparam et dparam du gestionnaire rapportent les coordonnées X et Y en conséquence.
La tâche simple suivante servira d'exemple. Nous devons faire en sorte qu'une flèche « acheter » soit dessinée à l'endroit où le clic de souris a lieu. L'objet 'flèche' n'a qu'un seul point d'ancrage. Par conséquent, une seule transformation des coordonnées X et Y en valeurs du temps et du prix du point d'ancrage est nécessaire.
Le code de l'exemple ci-dessus :
//--- 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 version actuelle de l'expert s'appelle EventProcessor6.mq5.
4.7. Événement de clic de souris sur un objet graphique
Ce type d'événements du graphique ne diffère du précédent que par le fait qu'un clic de souris se produit sur un objet graphique. Le paramètre de chaîne sparam contiendra le nom de l'objet sur lequel vous avez cliqué. Dans l'exemple précédent, nous avons créé des flèches 'acheter'. Faisons en sorte qu'un clic sur l'objet de ce type le transforme en flèche 'vendre'.
Le code de ce bloc du gestionnaire peut ressembler à :
//--- 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; }
Pour les besoins de cet exemple, j'ai gardé le cas d'un clic de souris inchangé. En lançant l'EA, j'ai cliqué trois fois avec le bouton gauche de la souris et j'ai obtenu trois flèches à acheter (Fig.7). J'ai surligné leur emplacement en jaune.
Fig.7. Flèches "Acheter"
Si maintenant nous cliquons sur chaque flèche 'acheter', nous recevrons l'image suivante (Fig.8).
Fig.8. Flèches 'Acheter' et 'Vendre'
Les flèches 'Vendre' sont apparues comme prévu, mais les flèches 'Acheter' n'étaient pas conçues pour apparaître. Il y a une raison pour laquelle j'apporte une liste d'objets sur le graphique où j'ai surligné en jaune les noms des flèches 'Acheter'.
Il est facile de remarquer que l'EA a créé les 4e, 5e et 6e flèches 'Acheter'. Pourquoi cela s'est-il produit ? C'est arrivé parce que le premier clic sur l'objet a déclenché deux événements : le premier était le clic réel sur l'objet et le second - un clic sur le graphique. Le dernier événement génère la création d'une flèche 'Acheter'. Ici se pose la nécessité d'ajouter un mécanisme qui empêchera la gestion du deuxième événement, qui est un clic sur le graphique. Il me semble que le contrôle du temps peut être un tel mécanisme.
Ajoutons une variable globale gLastTime. Cela facilitera un contrôle sur le temps de création d'une flèche 'acheter'. Si un simple gestionnaire de clics est appelé pendant moins de 250 ms après la création d'une flèche 'vente', alors cet appel doit être transmis.
Avant que le graphe ne soit redessiné, la chaîne ci-dessous est à ajouter au bloc de traitement d'un clic sur l'objet :
//--- store the moment of creation gLastTime=GetTickCount();
La vérification de l'heure doit être ajoutée au bloc de manipulation d'un clic sur le graphique.
uint lastTime=GetTickCount(); if((lastTime-gLastTime)>250) { //--- click handling }
Créons à nouveau trois flèches sur le graphique de type 'acheter' (Fig.9).
Fig.9. Flèches 'Acheter'
Nous essaierons de cliquer dessus malgré leur petite taille. Les flèches se sont transformées en type "vente" au clic (Fig.10).
Fig.10. Flèches 'Vendre'
Semblable aux précédents, nous allons nommer la nouvelle version EventProcessor7.mq5.
4.8. Événement de déplacement d'un objet graphique avec la souris
Cet événement se produit lorsqu'un objet est déplacé dans une zone de graphique. Le gestionnaire reçoit le nom de l'objet déplacé sous la forme d'un paramètre de chaîne sparam.
Voici un autre exemple. Les traders intra-journaliers tradent très souvent dans un certain intervalle de temps. Les lignes verticales seront les limites d'un intervalle de temps. L'image ressemblera approximativement à la Fig.11. L'intervalle d'intérêt est mis en évidence.
Fig.11. Limites d'un intervalle de temps
L'intervalle de temps peut être modifié manuellement. Ensuite, notre semi-automate devra réagir à un tel changement.
Au niveau global, nous allons créer des variables décrivant les noms des deux verticales - gTimeLimit1_name et gTimeLimit2_name. Nous devons également créer quelques variables pour les noms des rectangles, qui assombrissent le temps de non-échange sur le graphique. Des variables globales pour les points d'ancrage devront également être créées. Puisque nous avons deux rectangles, nous aurons quatre points.
Le code du cas du gestionnaire 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; }
Ce code contient une fonction personnalisée RefreshRecPoints(). Il s'agit de mettre à jour les valeurs des points d'ancrage pour deux rectangles. Le bloc d'initialisation EA peut fournir des informations sur la création d'objets graphiques. La version mise à jour s'appellera EventProcessor8.mq5.
4.9. Fin de l'événement d'édition d'un texte dans le champ de texte
Ce type d'événement a une nature hautement spécialisée et apparaît lorsque le texte dans le champ de saisie de données est en cours d'édition. Le paramètre sparam contient le nom de l'objet sur lequel on travaille.
Voici un exemple à considérer. Dans le champ de saisie des données, nous saisirons l'opération de trade que nous sommes sur le point d'exécuter. Qu'il n'y ait que deux opérations - acheter et vendre. Si nous entrons le mot « Acheter » dans le champ de saisie, l'EA achètera un actif et si nous entrons « Vendre », l'actif sera vendu. Nous allons faire en sorte que ce champ ne soit pas sensible à la casse, c'est-à-dire que nous pouvons taper « acheter » et « vendre ». Le texte et le champ de saisie seront de couleur rouge à la vente et bleu à l'achat (Fig.12).
Fig.12. Acheter via le champ de texte
Le code dans le cas 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 version mise à jour de l'EA s'appelle EventProcessor9.mq5. Vous pouvez trouver le bloc de création du champ de texte dans le fichier source.
4.10. Événement de modification de graphique
Le dernier événement que nous allons considérer dans cet article est lié à la modification des paramètres du graphique. Il s'agit d'un événement particulier car à ce stade, nous nous occupons du graphique lui-même, et non des objets du graphique. Les développeurs disent que cet événement est généré lorsque la taille d'un graphique est modifiée ou qu'un nouveau paramètre est introduit.
Voici un autre exemple. Supposons qu'il existe une interdiction de modifier certains paramètres du graphique. Ensuite, toutes les tentatives de modification des paramètres sous restriction seront ignorées. En fait, l'EA renverra simplement les valeurs précédentes. Fixons les paramètres suivants du graphique :
- grille d'affichage ;
- type d'affichage graphique ;
- Couleur de fond.
Code pour ce cas :
//--- 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; }
La dernière version s'appellera EventProcessor10.mq5.
Conclusion
Dans cet article, j'ai essayé d'illustrer la diversité des événements du graphique typiques dans MetaTrader 5. J'espère que ces exemples de gestion d'événements seront utiles aux programmeurs qui commencent à coder en MQL5.
Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/689
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation