English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Modifier les paramètres de l'Expert Advisor à partir du panneau de l'utilisateur "On The Fly"

Modifier les paramètres de l'Expert Advisor à partir du panneau de l'utilisateur "On The Fly"

MetaTrader 5Exemples | 13 janvier 2022, 09:30
584 0
Anatoli Kazharski
Anatoli Kazharski

Contenu

Introduction
1. Questions en bref
2. Structure de l’Expert Advisor
3. Interaction avec le panneau de l'utilisateur
Conclusion


Introduction

Lors du développement d'Expert Advisors complexes, le nombre de paramètres externes peut être très important. Et les paramètres doivent très souvent être modifiés manuellement, ce qui rend l'ensemble du processus très chronophage, étant donné une liste massive de paramètres. On peut, bien sûr, préparer des sets à l'avance et les sauvegarder, mais ce n'est peut-être pas exactement ce qui est requis dans certains cas. C'est là que MQL5 est utile, comme toujours.

Essayons de créer un panel d'utilisateurs qui nous permettra de modifier les paramètres d'un Expert Advisor "On The Fly" pendant le trading. Cela peut être pertinent pour ceux qui tradent manuellement ou en mode semi-automatique. Lors de toute modification apportée, les paramètres seront écrits dans un fichier à partir duquel ils seront ensuite lus par l'Expert Advisor pour être ensuite affichés sur le panneau.


1. Questions en bref

A titre d'illustration, nous allons développer une EA simple qui ouvre une position en direction de l'indicateurJMA adaptatif. L'EA travaillera sur les barres terminées sur le symbole et la période actuels. Les paramètres externes incluront la période de l'indicateur, le stop loss, le take profit, l'inversion et le lot. Ces options seront tout à fait suffisantes dans notre exemple.

Ajoutons deux paramètres supplémentaires pour pouvoir activer/désactiver le panneau (On/Off Info Panel) et activer/désactiver le mode de paramétrage de l'Expert Advisor (réglage "On The Fly"). Lorsque le nombre de paramètres est important, il est toujours plus pratique de placer des options supplémentaires au tout début ou à la fin de la liste pour un accès facile et rapide.

Fig. 1. Panneau d'information avec les paramètres de l'Expert Advisor

Fig. 1. Panneau d'information avec les paramètres de l'Expert Advisor

Le mode de réglage "On The Fly" est désactivé par défaut. Lorsque vous activez ce mode pour la première fois, l'Expert Advisor crée un fichier afin de sauvegarder tous les paramètres dont il dispose actuellement. La même chose se produira si le fichier est accidentellement supprimé. L'Expert Advisor détectera la suppression et recréera le fichier. Le mode de réglage "On The Fly" étant désactivé, l'Expert Advisor sera guidé par des paramètres externes.

Si ce mode est activé, l'Expert Advisor lira les paramètres du fichier et, en cliquant simplement sur n'importe quel paramètre du panneau d'informations, vous pourrez soit sélectionner la valeur requise, soit saisir une nouvelle valeur dans la fenêtre de dialogue contextuelle. . Les données du fichier seront mises à jour chaque fois qu'une nouvelle valeur est sélectionnée.


2. Structure de l’Expert Advisor

Bien que le programme soit petit et que toutes les fonctions puissent facilement tenir dans un seul fichier, il est toujours beaucoup plus pratique de parcourir toutes les informations du projet lorsqu'elles sont correctement classées. Par conséquent, il est préférable de classer les fonctions par type et de les avoir dans différents fichiers dès le début pour les inclure plus tard dans le fichier principal. La figure ci-dessous montre un dossier de projet partagé avec l'Expert Advisor OnTheFly et tous les fichiers inclus. Les fichiers inclus sont placés dans un dossier séparé (Inclure).

Fig. 2. Fichiers de projet dans la fenêtre Navigateur de MetaEditor

Fig. 2. Fichiers de projet dans la fenêtre Navigateur de MetaEditor

Lorsque les fichiers à inclure se trouvent dans le même dossier que le fichier maître, le code est le suivant :

//+------------------------------------------------------------------+
//| CUSTOM LIBRARIES                                                 |
//+------------------------------------------------------------------+
#include "Include/!OnChartEvent.mqh"
#include "Include/CREATE_PANEL.mqh"
#include "Include/FILE_OPERATIONS.mqh"
#include "Include/ERRORS.mqh"
#include "Include/ARRAYS.mqh"
#include "Include/TRADE_SIGNALS.mqh"
#include "Include/TRADE_FUNCTIONS.mqh"
#include "Include/GET_STRING.mqh"
#include "Include/GET_COLOR.mqh"
#include "Include/ADD_FUNCTIONS.mqh"

Vous trouverez plus d'informations sur la façon d'inclure des fichiers dans Référence MQL5.

Nous aurons besoin de variables globales - des copies de paramètres externes. Leurs valeurs seront soit attribuées à partir des paramètres externes ou du fichier, selon le mode de l'Expert Advisor. Ces variables sont utilisées dans tout le code du programme, par exemple dans l'affichage des valeurs sur le panneau d'information, dans les fonctions de trading, etc.

// COPY OF EXTERNAL PARAMETERS
int    gPeriod_Ind = 0;
double gTakeProfit = 0.0;
double gStopLoss   = 0.0;
bool   gReverse    = false;
double gLot        = 0.0;

Comme dans tous les autres Expert Advisors, nous aurons les principales fonctions : OnInit, OnTick et OnDeinit. Et il y aura aussi la fonction OnTimer. Chaque seconde, il vérifiera l'existence du fichier de paramètres et le restaurera au cas où il aurait été accidentellement supprimé. Puisque nous devons interagir avec le panneau utilisateur, la fonction OnChartEvent sera également utilisée. Cette fonction avec d'autres fonctions connexes a été placée dans un fichier séparé (!OnChartEvent.mqh).

Le code de base du fichier maître est le suivant :

#define szArrIP 5 // Size of the parameter array
#define NAME_EXPERT MQL5InfoString(MQL5_PROGRAM_NAME) // Name of EA
#define TRM_DP TerminalInfoString(TERMINAL_DATA_PATH) // Folder that contains the terminal data
//+------------------------------------------------------------------+
//| STANDARD LIBRARIES                                               |
//+------------------------------------------------------------------+
#include <Trade/SymbolInfo.mqh>
#include <Trade/Trade.mqh>
//+------------------------------------------------------------------+
//| CUSTOM LIBRARIES                                                 |
//+------------------------------------------------------------------+
#include "Include/!OnChartEvent.mqh"
#include "Include/CREATE_PANEL.mqh"
#include "Include/FILE_OPERATIONS.mqh"
#include "Include/ERRORS.mqh"
#include "Include/ARRAYS.mqh"
#include "Include/TRADE_SIGNALS.mqh"
#include "Include/TRADE_FUNCTIONS.mqh"
#include "Include/GET_STRING.mqh"
#include "Include/GET_COLOR.mqh"
#include "Include/ADD_FUNCTIONS.mqh"
//+------------------------------------------------------------------+
//| CREATING CLASS INSTANCES                                         |
//+------------------------------------------------------------------+
CSymbolInfo mysymbol; // CSymbolInfo class object 
CTrade      mytrade;  // CTrade class object
//+------------------------------------------------------------------+
//| EXTERNAL PARAMETERS                                              |
//+------------------------------------------------------------------+
input int    Period_Ind      = 10;    // Indicator Period
input double TakeProfit      = 100;   // Take Profit (p)
input double StopLoss        = 30;    // Stop Loss (p)
input bool   Reverse         = false; // Reverse Position
input double Lot             = 0.1;   // Lot
//---
input string slash="";       // * * * * * * * * * * * * * * * * * * *
sinput bool  InfoPanel       = true;  // On/Off Info Panel
sinput bool  SettingOnTheFly = false; // "On The Fly" Setting
//+------------------------------------------------------------------+
//| GLOBAL VARIABLES                                                 |
//+------------------------------------------------------------------+
int hdlSI=INVALID_HANDLE; // Signal indicator handle
double lcheck=0;  // For the check of parameter values
bool isPos=false; // Position availability
//--- COPY OF EXTERNAL PARAMETERS
int    gPeriod_Ind = 0;
double gTakeProfit = 0.0;
double gStopLoss   = 0.0;
bool   gReverse    = false;
double gLot        = 0.0;
//+------------------------------------------------------------------+
//| EXPERT ADVISOR INITIALIZATION                                    |
//+------------------------------------------------------------------+
void OnInit()
  {
   if(NotTest()) { EventSetTimer(1); } // If it's not the tester, set the timer
//---
   Init_arr_vparams(); // Initialization of the array of parameter values
   SetParameters(); // Set the parameters
   GetIndicatorsHandles(); // Get indicator handles
   NewBar(); // New bar initialization
   SetInfoPanel(); // Info panel
  }
//+------------------------------------------------------------------+
//| CURRENT SYMBOL TICKS                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// If the bar is not new, exit
   if(!NewBar()) { return; }
   else
     { TradingBlock(); }
  }
//+------------------------------------------------------------------+
//| TIMER                                                            |
//+------------------------------------------------------------------+
void OnTimer()
  {
   SetParameters(); SetInfoPanel();
  }
//+------------------------------------------------------------------+
//| EXPERT ADVISOR DEINITIALIZATION                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// Get the deinitialization reason code
   if(NotTest()) {
     { Print(getUnitReasonText(reason)); }
//---
// When deleting from the chart
   if(reason==REASON_REMOVE)
     {
      // Delete all objects created by the Expert Advisor
      DeleteAllExpertObjects();
      //---
      if(NotTest()) { EventKillTimer(); } // Stop the timer
      IndicatorRelease(hdlSI); // Delete the indicator handle
     }
  }

J'ai également inclus quelques fonctions supplémentaires dans le fichier principal :

  • GetIndicatorsHandles – obtient le handle de l'indicateur.
  • NewBar – détermine le nouvel événement de barre.
  • SetParameters – définit les paramètres en fonction du mode.
  • iZeroMemory - met à zéro certaines variables et tableaux.
Les codes sources de ces fonctions peuvent être trouvés dans les fichiers joints à l'article. Ici, nous ne passerons en revue que la fonction SetParameters (des commentaires explicatifs sont fournis dans le code) :
//+------------------------------------------------------------------+
//| SETTING PARAMETERS IN TWO MODES                                  |
//+------------------------------------------------------------------+
// If this variable is set to false, the parameters in the file are read from the array
// where they are saved for quick access after they have been read for the first time.
// The variable is zeroed out upon the change in the value on the panel.
bool flgRead=false;
double arrParamIP[]; // Array where the parameters from the file are saved
//---
void SetParameters()
  {
// If currently in the tester or
// in real time but with the "On The Fly" Setting mode disabled
   if(!NotTest() || (NotTest() && !SettingOnTheFly))
     {
      // Zero out the variable and parameter array
      flgRead=false;
      ArrayResize(arrParamIP,0);
      //---
      // Check the Indicator Period for correctness
      if(Period_Ind<=0)
        { lcheck=10; }
      else { lcheck=Period_Ind; }
      gPeriod_Ind=(int)lcheck;
      //---
      gStopLoss=StopLoss;
      gTakeProfit=TakeProfit;
      gReverse=Reverse;
      //---
      // Check the Lot for correctness
      if(Lot<=0)
        { lcheck=0.1; }
      else { lcheck=Lot; }
      gLot=lcheck;
     }
   else // If "On The Fly" Setting mode is enabled
     {
      // Check whether there is a file to write/read parameters to/from the file
      string lpath="";
      //---
      // If the folder exists
      if((lpath=CheckCreateGetPath())!="")
        {
         // Write or read the file
         WriteReadParameters(lpath);
        }
     }
  }

Le code source de la fonction SetParameters est simple et direct. Examinons de plus près la fonction WriteReadParameters. Tout est assez simple ici. Nous vérifions d'abord si le fichier avec les paramètres existe. Si c'est le cas, nous lisons le fichier et écrivons les valeurs des paramètres dans un tableau à l'aide de la fonction GetValuesParamsFromFile. Si le fichier n'existe pas, il sera créé, avec les paramètres externes actuels qui y sont écrits.

Ci-dessous le code avec des commentaires plus détaillés pour la mise en œuvre des actions décrites ci-dessus :

//+------------------------------------------------------------------+
//| WRITE DATA TO FILE                                               |
//+------------------------------------------------------------------+
void WriteReadParameters(string pth)
  {
   string nm_fl=pth+"ParametersOnTheFly.ini"; // File name and path
//---
// Get the file handle to read the file
   int hFl=FileOpen(nm_fl,FILE_READ|FILE_ANSI);
//---
   if(hFl!=INVALID_HANDLE) // If the handle has been obtained, the file exists
     {
      // Get parameters from the file
      if(!flgRead)
        {
         // Set the array size
         ArrayResize(arrParamIP,szArrIP);
         //---
         // Fill the array with values from the file
         flgRead=GetValuesParamsFromFile(hFl,arrParamIP);
        }
      //---
      // If the array size is correct,...
      if(ArraySize(arrParamIP)==szArrIP)
        {
         // ...set the parameters to the variables
         //---
         // Check the Indicator Period for correctness
         if((int)arrParamIP[0]<=0) { lcheck=10; }
         else { lcheck=(int)arrParamIP[0]; }
         gPeriod_Ind=(int)lcheck;
         //---
         gTakeProfit=arrParamIP[1];
         gStopLoss=arrParamIP[2];
         gReverse=arrParamIP[3];
         //---
         // Check the Lot for correctness
         if(arrParamIP[4]<=0)
           { lcheck=0.1; }
         else { lcheck=arrParamIP[4]; }
         gLot=lcheck;
        }
     }
   else // If the file does not exist
     {
      iZeroMemory(); // Zero out variables
      //---
      // When creating the file, write current parameters of the Expert Advisor
      //---
      // Get the file handle to write to the file
      int hFl2=FileOpen(nm_fl,FILE_WRITE|FILE_CSV|FILE_ANSI,"");
      //---
      if(hFl2!=INVALID_HANDLE) // If the handle has been obtained
        {
         string sep="=";
         //---
         // Parameter names and values are obtained from arrays in the ARRAYS.mqh file
         for(int i=0; i<szArrIP; i++)
           { FileWrite(hFl2,arr_nmparams[i],sep,arr_vparams[i]); }
         //---
         FileClose(hFl2); // Close the file
         //---
         Print("File with parameters of the "+NAME_EXPERT+" Expert Advisor created successfully.");
        }
     }
//---
   FileClose(hFl); // Close the file
  }

Les fonctions WriteReadParameters et GetValuesParamsFromFile se trouvent dans le fichier FILE_OPERATIONS.mqh.

Certaines des fonctions ont déjà été décrites dans mon article précédent "Comment préparer des cotations MetaTrader 5 pour d'autres applications", nous ne nous attarderons donc pas sur elles ici. Vous ne devriez pas non plus rencontrer de difficultés avec les fonctions de trading, car elles sont très simples et abondamment commentées. Ce sur quoi nous allons nous concentrer est le sujet principal de l'article.


3. Interaction avec le panneau de l'utilisateur

Le fichier !OnChartEvent.mqh contient des fonctions d'interaction avec le panneau utilisateur. Les variables et les tableaux qui sont utilisés dans de nombreuses fonctions sont déclarés dans la portée globale au tout début :

// Current value on the panel or
// entered in the input box
string currVal="";
bool flgDialogWin=false; // Flag for panel existence
int
szArrList=0,// Size of the option list array
number=-1; // Parameter number in the panel list
string
nmMsgBx="",  // Name of the dialog window
nmValObj=""; // Name of the selected object
//---
// Option list arrays in the dialog window
string lenum[],lenmObj[];
//---
// colors of the dialog window elements
color
clrBrdBtn=clrWhite,
clrBrdFonMsg=clrDimGray,clrFonMsg=C'15,15,15',
clrChoice=clrWhiteSmoke,clrHdrBtn=clrBlack,
clrFonHdrBtn=clrGainsboro,clrFonStr=C'22,39,38';

Ceci est suivi par la fonction principale qui gère les événements. Dans notre exemple, nous devrons gérer deux événements :

  • L'événement CHARTEVENT_OBJECT_CLICK- clic gauche sur l'objet graphique.
  • L'événement CHARTEVENT_OBJECT_EDIT – fin de l'édition de texte dans l'objet graphique Edit.

Vous pouvez en savoir plus sur les autres événements MQL5 dans Référence MQL5.

Définissons d'abord un contrôle de gestion des événements en temps réel uniquement, à condition toujours que le mode de paramétrage "On The Fly" soit activé (SettingOnTheFly). Le traitement des événements sera traité par des fonctions distinctes : ChartEvent_ObjectClick et ChartEvent_ObjectEndEdit.

//+------------------------------------------------------------------+
//| USER EVENTS                                                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int     id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam)
  {
// If the event is real time and the "On The Fly" setting mode is enabled
   if(NotTest() && SettingOnTheFly)
     {
      //+------------------------------------------------------------------+
      //| THE CHARTEVENT_OBJECT_CLICK EVENT                                |
      //+------------------------------------------------------------------+
      if(ChartEvent_ObjectClick(id,lparam,dparam,sparam)) { return; }
      //---
      //+------------------------------------------------------------------+
      //| THE CHARTEVENT_OBJECT_ENDEDIT EVENT                              |
      //+------------------------------------------------------------------+
      if(ChartEvent_ObjectEndEdit(id,lparam,dparam,sparam)) { return; }
     }
//---
   return;
  }

Lorsque vous cliquez sur l'objet qui appartient à la liste, une fenêtre de dialogue apparaît sur le panneau d'informations vous permettant de sélectionner une autre valeur ou d'entrer une nouvelle valeur dans la zone de saisie.

Fig. 3. Fenêtre de dialogue de modification de la valeur du paramètre sélectionné

Fig. 3. Fenêtre de dialogue de modification de la valeur du paramètre sélectionné

Voyons de plus près comment cela fonctionne. Lorsqu'un objet graphique est cliqué, le programme utilise d'abord la fonction ChartEvent_ObjectClick pour vérifier par l'identifiant d'événement s'il y a vraiment eu un clic sur un objet graphique.

Si vous souhaitez que la fenêtre de dialogue s'ouvre au milieu du graphique, vous devez connaître la taille du graphique. Il peut être obtenu en indiquant les propriétés CHART_WIDTH_IN_PIXELS et CHART_HEIGHT_IN_PIXELS dans la fonction ChartGetInteger. Le programme passe ensuite au DialogWindowInfoPanel. Vous pouvez vous familiariser avec toutes les propriétés du graphique dans MQL5 Référence.

Vous trouverez ci-dessous le code pour la mise en œuvre des actions ci-dessus :

//+------------------------------------------------------------------+
//| THE CHARTEVENT_OBJECT_CLICK EVENT                                |
//+------------------------------------------------------------------+
bool ChartEvent_ObjectClick(int id,long lparam,double dparam,string sparam)
  {
   // If there was an event of clicking on a graphical object
   if(id==CHARTEVENT_OBJECT_CLICK) // id==1
     {
      Get_STV(); // Get all data on the symbol
      //---
      string clickedChartObject=sparam; // Name of the clicked object
      //---
      // Get the chart size
      width_chart=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
      height_chart=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
      //---
      DialogWindowInfoPanel(clickedChartObject);
     }
//---
   return(false);
  }

À l'aide de la fonction DialogWindowInfoPanel, nous vérifions d'abord si la fenêtre de dialogue est actuellement ouverte. Si la fenêtre n'est pas trouvée, la fonction GetNumberClickedObjIP vérifie si le clic était en relation avec un objet de la liste du panneau d'informations. Si l'objet cliqué est l'objet de la liste, la fonction renverra le numéro d'élément pertinent du tableau d'objets. À l'aide de ce nombre, la fonction InitArraysAndDefault détermine ensuite la taille du tableau de liste dans la fenêtre de dialogue et les valeurs par défaut. Si toutes les actions sont réussies, la fenêtre de dialogue apparaîtra.

Si la fonction DialogWindowInfoPanel détermine que la fenêtre de dialogue est déjà ouverte, le programme vérifiera s'il y a eu un clic sur un objet dans la fenêtre de dialogue. Par exemple, à l'ouverture de la fenêtre de dialogue, la ligne dont la valeur est actuellement affichée sur le panneau apparaîtra comme sélectionnée. Si vous cliquez sur une autre option dans la liste, le programme utilisera la fonction SelectionOptionInDialogWindow qui sélectionne l'option de liste de la fenêtre de dialogue sur laquelle vous avez cliqué.

Si vous cliquez sur l'option de liste actuellement sélectionnée, cet objet sera identifié comme un objet à éditer et une zone de saisie apparaîtra afin qu'une nouvelle valeur puisse être saisie lorsque vous cliquez sur la case. La fonction SetEditObjInDialogWindow est responsable de la définition de la zone de saisie.

Et enfin, si le bouton Appliquer a été cliqué, le programme vérifiera si la valeur a été modifiée. Si c'est le cas, la nouvelle valeur apparaîtra sur le panneau et sera écrite dans le fichier.

Le code de la fonction principale de la fenêtre de dialogue est fourni ci-dessous :

//+------------------------------------------------------------------+
//| DIALOG WINDOW OF THE INFO PANEL                                  |
//+------------------------------------------------------------------+
void DialogWindowInfoPanel(string clickObj)
  {
// If there is currently no dialog window
   if(!flgDialogWin)
     {
      // Get the object number in the array
      // Exit if none of the parameters displayed on the panel has been clicked
      if((number=GetNumberClickedObjIP(clickObj))==-1) { return; }
      //---
      // Initialization of default values
      //and determination of the list array size
      if(!InitArraysAndDefault()) { return; }
      //---
      // Set the dialog window
      SetDialogWindow();
      //---
      flgDialogWin=true; // Mark the dialog window as open
      ChartRedraw();
     }
   else // If the dialog window is open
     {
      // Set the input box for the modification of the value
      SetEditObjInDialogWindow(clickObj);
      //---
      // If one of the buttons in the dialog box is clicked
      if(clickObj=="btnApply" || clickObj=="btnCancel")
        {
         // If the Apply button is clicked
         if(clickObj=="btnApply")
           {
            // Compare values on the panel with the ones on the list
            // If the value on the list is different from the one that is currently displayed on the panel 
            // (which means it is different from the one in the file),
            // ...change the value on the panel and update the file
            if(currVal!=ObjectGetString(0,nmValObj,OBJPROP_TEXT))
              {
               // Update the value on the panel
               ObjectSetString(0,nmValObj,OBJPROP_TEXT,currVal); ChartRedraw();
               //---
               // Read all data on the panel and write it to the file
               WriteNewData();
              }
           }
         //---
         DelDialogWindow(lenmObj); // Delete the dialog window
         iZeroMemory(); // Zero out the variables
         //---
         // Update the data
         SetParameters();
         GetHandlesIndicators();
         SetInfoPanel();
         //---
         ChartRedraw();
        }
      else // If neither Apply nor Cancel has been clicked
        {
         // Selection of the dialog window list option
         SelectionOptionInDialogWindow(clickObj);
         //---
         ChartRedraw();
        }
     }
  }

Chaque fois qu'une nouvelle valeur est saisie dans la zone de saisie, l'événement CHARTEVENT_OBJECT_EDIT est généré et le programme bascule vers la fonction ChartEvent_ObjectEndEdit. Si la valeur de la fenêtre de dialogue a été modifiée, la valeur saisie sera enregistrée, vérifiée pour l'exactitude et affectée à l'objet dans la liste. Vous pouvez le voir plus en détail dans le code ci-dessous :

//+------------------------------------------------------------------+
//| THE CHARTEVENT_OBJECT_ENDEDIT EVENT                              |
//+------------------------------------------------------------------+
bool ChartEvent_ObjectEndEdit(int id,long lparam,double dparam,string sparam)
  {
   if(id==CHARTEVENT_OBJECT_ENDEDIT) // id==3
     {
      string editObject=sparam; // Name of the edited object
      //---
      // If the value has been entered in the input box in the dialog window
      if(editObject=="editValIP")
        {
         // Get the entered value
         currVal=ObjectGetString(0,"editValIP",OBJPROP_TEXT);
         //---
         // (0) Period Indicator
         if(number==0)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal="1"; }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB0",OBJPROP_TEXT,currVal);
           }
         //---
         // (4) Lot
         if(number==4)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal=DS(SS.vol_min,2); }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB0",OBJPROP_TEXT,DS2(SD(currVal)));
           }
         //---
         // (1) Take Profit (p)
         // (2) Stop Loss (p)
         if(number==1 || number==2)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal="1"; }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB1",OBJPROP_TEXT,currVal);
           }
         //---         
         DelObjbyName("editValIP"); ChartRedraw();
        }
     }
//---
   return(false);
  }

L'Expert Advisor en action est visible dans la vidéo ci-dessous :



Conclusion

Les fichiers zippés joints à la fin de l'article peuvent être téléchargés pour une étude plus approfondie.

J'espère que cet article aidera ceux d'entre vous qui commencent seulement à apprendre MQL5 à trouver des réponses rapides à de nombreuses questions en utilisant les exemples simples donnés. J'ai intentionnellement omis certaines vérifications des extraits de code fournis.

Par exemple, si vous modifiez la hauteur/largeur du graphique lorsque la fenêtre de dialogue est ouverte, la fenêtre de dialogue ne sera pas automatiquement centrée. Et si vous complétez le tout en sélectionnant une autre option dans la liste, l'objet qui sert à sélectionner la ligne concernée sera considérablement déplacé. Que ce soit votre devoir. Il est très important de pratiquer la programmation et plus vous pratiquez, mieux c'est.

Bonne chance!

Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/572

Fichiers joints |
onthefly_en.zip (26.38 KB)
Apprentissage automatique : Comment les machines à vecteurs de support peuvent être utilisées dans le trading Apprentissage automatique : Comment les machines à vecteurs de support peuvent être utilisées dans le trading
Les machines à vecteurs de support sont utilisées depuis longtemps dans des domaines tels que la bio-informatique et les mathématiques appliquées pour évaluer des ensembles de données complexes et extraire des modèles utiles pouvant être utilisés pour classer les données. Cet article examine ce qu'est une machine à vecteurs de support, comment elle fonctionne et pourquoi elle peut être si utile pour extraire des motifs complexes. Nous étudions ensuite comment ils peuvent être appliqués au marché et potentiellement utilisés pour conseiller sur le trading. À l'aide de l'outil d'apprentissage par machine à vecteur de support, l'article fournit des exemples concrets qui permettent aux lecteurs d'expérimenter leur propre trading.
Les bases de la programmation MQL5 : Tableaux Les bases de la programmation MQL5 : Tableaux
Les tableaux font partie intégrante de presque tous les langages de programmation, avec les variables et les fonctions. L'article devrait intéresser principalement les programmeurs novices en MQL5, tandis que les programmeurs expérimentés auront une bonne occasion de résumer et de systématiser leurs connaissances.
Les bases de la programmation MQL5 : Les chaînes Les bases de la programmation MQL5 : Les chaînes
L'article couvre tout ce que vous pouvez faire avec les chaînes en MQL5. Il devrait intéresser principalement les programmeurs novices en MQL5, tandis que les développeurs expérimentés auront une bonne occasion de résumer et de systématiser leurs connaissances.
Signaux de Trading pour MetaTrader 5: Une meilleure alternative aux comptes PAMM ! Signaux de Trading pour MetaTrader 5: Une meilleure alternative aux comptes PAMM !
Nous sommes heureux d'annoncer que MetaTrader 5 propose désormais des signaux de trading, offrant ainsi un outil puissant aux investisseurs et aux gestionnaires. Pendant que vous suivez les trades d'un trader performant, le terminal les reproduira automatiquement dans votre compte !