English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Modifica "al volo" i parametri dell'Expert Advisor dal pannello utente

Modifica "al volo" i parametri dell'Expert Advisor dal pannello utente

MetaTrader 5Esempi | 11 gennaio 2022, 16:16
505 0
Anatoli Kazharski
Anatoli Kazharski

Contenuti

Introduzione
1. Problemi in primo piano
2. Struttura dell'Expert Advisor
3. Interazione con il pannello utente
Conclusione


Introduzione

Quando si sviluppano Expert Advisor complessi, il numero di parametri esterni può essere molto elevato. E le impostazioni molto spesso devono essere modificate manualmente, rendendo l'intero processo molto dispendioso in termini di tempo, dato l’enorme elenco di parametri. Ovviamente è possibile preparare i set in anticipo e salvarli, ma in alcuni casi potrebbe non essere esattamente ciò che è richiesto. È qui che MQL5 torna utile, come sempre.

Proviamo a creare un pannello utente che ci permetta di modificare i parametri di un Expert Advisor "al volo" durante il trading. Questo può essere rilevante per coloro che fanno trading manualmente o in modalità semi-automatica. Ad ogni modifica effettuata, i parametri verranno scritti in un file dal quale verranno poi letti dall'Expert Advisor per essere ulteriormente visualizzati sul pannello.


1. Problemi in primo piano

A titolo illustrativo, svilupperemo un semplice EA che apre una posizione nella direzione dell'indicatore JMA. L'EA lavorerà sulle barre completate sul simbolo e sull'intervallo di tempo correnti. I parametri esterni includeranno Indicator Period, Stop Loss, Take Profit, Reverse e Lot. Queste opzioni saranno abbastanza sufficienti nel nostro esempio.

Aggiungiamo due parametri aggiuntivi per poter accendere/spegnere il pannello (pannello Info On/Off) e abilitare/disabilitare la modalità di impostazione dei parametri Expert Advisor (impostazione "On The Fly"). Laddove il numero di parametri è elevato, è sempre più conveniente posizionare opzioni aggiuntive all'inizio o alla fine dell'elenco per un accesso facile e veloce.

Fig. 1. Pannello Info con i parametri dell'Expert Advisor

Fig. 1. Pannello informativo con i parametri dell'Expert Advisor

La modalità di impostazione "Al volo" è disabilitata per impostazione predefinita. Quando abiliti questa modalità per la prima volta, Expert Advisor crea un file per salvare tutti i parametri che ha attualmente. Lo stesso accadrà se il file viene cancellato accidentalmente. L'Expert Advisor rileverà l'eliminazione e ricreerà il file. Con la modalità di impostazione "On The Fly" disabilitata, l'Expert Advisor sarà guidato da parametri esterni.

Se questa modalità è abilitata, l'Expert Advisor leggerà i parametri dal file e, semplicemente facendo clic su qualsiasi parametro nel pannello delle informazioni, sarà possibile selezionare il valore richiesto o inserire un nuovo valore nella finestra di dialogo che si apre . I dati del file verranno aggiornati ogni volta che viene selezionato un nuovo valore.


2. Struttura dell'Expert Advisor

Sebbene il programma sia piccolo e tutte le funzioni possano essere facilmente inserite in un unico file, è comunque molto più comodo navigare in tutte le informazioni del progetto quando sono categorizzate correttamente. Pertanto, è meglio classificare le funzioni per tipo e averle in file diversi fin dall'inizio per includerle successivamente nel file principale. La figura seguente mostra una cartella di progetto condivisa con OnTheFly Expert Advisor e tutti i file di inclusione. I file di inclusione vengono inseriti in una cartella separata (Includi).

Fig. 2. File di progetto nella finestra Navigatore di MetaEditor

Fig. 2. File di progetto nella finestra Navigatore di MetaEditor

Quando i file di inclusione si trovano nella stessa cartella con il file master, il codice è il seguente:

//+------------------------------------------------------------------+
//| 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"

Ulteriori informazioni su come includere i file sono disponibili in Riferimento MQL5.

Avremo bisogno di variabili globali - copie di parametri esterni. I loro valori saranno assegnati dai parametri esterni o dal file, a seconda della modalità dell'Expert Advisor. Queste variabili vengono utilizzate in tutto il codice del programma, ad esempio nella visualizzazione dei valori sul pannello delle informazioni, nelle funzioni di trading, ecc.

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

Come in tutti gli altri Expert Advisor, avremo le principali funzioni: OnInit, OnTick e OnDeinit. E ci sarà anche la funzione OnTimer. Ogni secondo verificherà l'esistenza del file dei parametri e lo ripristinerà nel caso sia stato cancellato accidentalmente. Poiché dobbiamo interagire con il pannello utente, verrà utilizzata anche la funzione OnChartEvent. Questa funzione insieme ad altre funzioni correlate è stata inserita in un file separato (!OnChartEvent.mqh).

Il codice principale del file master è il seguente:

#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
     }
  }

Ho anche incluso alcune altre funzioni nel file principale:

  • GetIndicatorsHandles: ottiene l'handle dell'indicatore.
  • NewBar – determina il nuovo evento bar.
  • SetParameters: imposta i parametri in base alla modalità.
  • iZeroMemory – azzera alcune variabili e array.
I codici sorgente per queste funzioni possono essere trovati nei file allegati all'articolo. Qui esamineremo solo la funzione SetParameters (i commenti esplicativi sono forniti nel codice):
//+------------------------------------------------------------------+
//| 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);
        }
     }
  }

Il codice sorgente per la funzione SetParameters è semplice e diretto. Diamo un'occhiata più da vicino alla funzione WriteReadParameters. Tutto è abbastanza semplice qui. Per prima cosa controlliamo se il file con i parametri esiste. In tal caso, leggiamo il file e scriviamo i valori dei parametri in un array utilizzando la funzione GetValuesParamsFromFile. Se il file non esiste, verrà creato, con i parametri esterni correnti scritti su di esso.

Di seguito il codice con commenti più dettagliati per l'attuazione delle azioni sopra descritte:

//+------------------------------------------------------------------+
//| 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
  }

Le funzioni WriteReadParameters e GetValuesParamsFromFile si trovano nel file FILE_OPERATIONS.mqh.

Alcune delle funzioni sono già state descritte nel mio precedente articolo "Come preparare le quotazioni di MetaTrader 5 per altre applicazioni", pertanto non ci soffermeremo qui. Non dovresti incontrare alcuna difficoltà nemmeno con le funzioni di trading, poiché sono molto semplici e commentate ampiamente. Quello su cui ci concentreremo è l'argomento principale dell'articolo.


3. Interazione con il pannello utente

Il file !OnChartEvent.mqh contiene funzioni per l'interazione con il pannello utente. Le variabili e gli array utilizzati in molte funzioni sono dichiarati nell'ambito globale all'inizio:

// 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';

Questo è seguito dalla funzione principale che gestisce gli eventi. Nel nostro esempio, dovremo gestire due eventi:

  • L'evento CHARTEVENT_OBJECT_CLICK – click sinistro sull'oggetto grafico.
  • L'evento CHARTEVENT_OBJECT_EDIT – fine della modifica del testo nell'oggetto grafico Modifica.

Puoi leggere di più su altri eventi MQL5 in Riferimento MQL5.

Impostiamo prima un controllo per la gestione degli eventi solo in tempo reale, sempre che sia abilitata la modalità di impostazione "On The Fly" (SettingOnTheFly). La gestione degli eventi sarà curata da funzioni separate: ChartEvent_ObjectClick e 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;
  }

Quando si fa clic sull'oggetto che appartiene all'elenco, sul pannello delle informazioni verrà visualizzata una finestra di dialogo che consente di selezionare un altro valore o di inserire un nuovo valore nella casella di input.

Fig. 3. Finestra di dialogo per la modifica del valore del parametro selezionato

Fig. 3. Finestra di dialogo per la modifica del valore del parametro selezionato

Diamo un'occhiata più da vicino a come funziona. Quando si fa clic su un oggetto grafico, il programma utilizza prima la funzione ChartEvent_ObjectClick per verificare tramite l'identificatore dell'evento se c'è stato davvero un clic su un oggetto grafico.

Se vuoi che la finestra di dialogo si apra al centro del grafico, devi conoscere le dimensioni del grafico. Può essere ottenuto indicando le proprietà CHART_WIDTH_IN_PIXELS e CHART_HEIGHT_IN_PIXELS nella funzione ChartGetInteger. Il programma passa quindi al DialogWindowInfoPanel. Puoi familiarizzare con tutte le proprietà del grafico in MQL5 Riferimento.

Di seguito è riportato il codice per l'attuazione delle azioni di cui sopra:

//+------------------------------------------------------------------+
//| 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);
  }

Utilizzando la funzione DialogWindowInfoPanel, controlliamo prima se la finestra di dialogo è attualmente aperta. Se la finestra non viene trovata, la funzione GetNumberClickedObjIP verifica se il clic era in relazione ad un oggetto della lista nel pannello info. Se l'oggetto cliccato è l'oggetto dell'elenco, la funzione restituirà il numero dell'elemento rilevante dall'array di oggetti. Utilizzando quel numero, la funzione InitArraysAndDefault determina quindi la dimensione dell'array dell'elenco nella finestra di dialogo e i valori predefiniti. Se tutte le azioni hanno successo, apparirà la finestra di dialogo.

Se la funzione DialogWindowInfoPanel determina che la finestra di dialogo è già aperta, il programma verificherà se c'è stato un clic su un oggetto nella finestra di dialogo. Ad esempio, aprendo la finestra di dialogo, la riga il cui valore è attualmente visualizzato sul pannello apparirà come selezionata. Se si fa clic su un'altra opzione nell'elenco, il programma utilizzerà la funzione SelectionOptionInDialogWindow che seleziona l'opzione dell'elenco della finestra di dialogo selezionata.

Se si fa clic sull'opzione dell'elenco attualmente selezionata, questo oggetto verrà identificato come un oggetto da modificare e apparirà una casella di input in modo che sia possibile inserire un nuovo valore quando si fa clic sulla casella. La funzione SetEditObjInDialogWindow è responsabile dell'impostazione della casella di input.

E infine, se è stato cliccato il pulsante Applica, il programma verificherà se il valore è stato modificato. In caso affermativo, il nuovo valore apparirà sul pannello e verrà scritto nel file.

Di seguito è riportato il codice della funzione principale della finestra di dialogo:

//+------------------------------------------------------------------+
//| 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();
        }
     }
  }

Ogni volta che viene inserito un nuovo valore nella casella di input, viene generato l'evento CHARTEVENT_OBJECT_EDIT e il programma passa alla funzione ChartEvent_ObjectEndEdit. Se il valore della finestra di dialogo è stato modificato, il valore inserito verrà memorizzato, verificato la correttezza e assegnato all'oggetto nella lista. Puoi vederlo più in dettaglio nel codice qui sotto:

//+------------------------------------------------------------------+
//| 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 in azione può essere visto nel video qui sotto:



Conclusione

I file compressi allegati alla fine dell'articolo possono essere scaricati per uno studio più approfondito.

Spero che questo articolo aiuterà quelli di voi che iniziano a imparare MQL5 solo a trovare risposte rapide a molte domande usando i semplici esempi forniti. Ho intenzionalmente omesso alcuni controlli dagli snippet di codice forniti.

Ad esempio, se si modifica l'altezza/larghezza del grafico quando la finestra di dialogo è aperta, la finestra di dialogo non verrà centrata automaticamente. E se lo rabbocchi selezionando un'altra opzione dall'elenco, l'oggetto che serve a selezionare la relativa riga verrà notevolmente spostato. Lascia che questo sia il tuo compito. È molto importante esercitarsi nella programmazione e più ti eserciti, meglio è.

Buona fortuna!

Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/572

File allegati |
onthefly_en.zip (26.38 KB)
Apprendimento automatico: Come le macchine a vettori di supporto possono essere utilizzate nel trading Apprendimento automatico: Come le macchine a vettori di supporto possono essere utilizzate nel trading
Le macchine a vettori di supporto sono state a lungo utilizzate in campi come la bioinformatica e la matematica applicata per valutare set di dati complessi ed estrarre modelli utili che possono essere utilizzati per classificare i dati. Questo articolo esamina cos'è una macchina a vettori di supporto, come funzionano e perché possono essere così utili nell'estrazione di modelli complessi. Indaghiamo quindi su come possono essere applicate al mercato e potenzialmente utilizzate per dare consigli sulle negoziazioni. Utilizzando il Support Vector Machine Learning Tool, questo articolo fornisce esempi funzionanti che consentono ai lettori di sperimentare con il proprio trading.
Fondamenti di programmazione MQL5: Arrays Fondamenti di programmazione MQL5: Arrays
Gli array sono parte integrante di quasi tutti i linguaggi di programmazione insieme a variabili e funzioni. L'articolo dovrebbe interessare principalmente i programmatori MQL5 alle prime armi, mentre i programmatori esperti avranno una buona opportunità per riassumere e sistematizzare le loro conoscenze.
Le basi sulla programmazione in MQL5: Stringhe Le basi sulla programmazione in MQL5: Stringhe
L'articolo copre tutto ciò che puoi fare con le stringhe in MQL5. Dovrebbe interessare principalmente i programmatori MQL5 alle prime armi, mentre per gli sviluppatori esperti questo articolo rappresenta una buona opportunità per riassumere e sistematizzare le loro conoscenze.
Segnali di trading per MetaTrader 5 Una migliore alternativa agli account PAMM! Segnali di trading per MetaTrader 5 Una migliore alternativa agli account PAMM!
Siamo lieti di annunciare che MetaTrader 5 ora dispone di segnali di trading, offrendo così un potente strumento a investitori e manager. Mentre segui le operazioni di un trader di successo, il terminale le riprodurrà automaticamente nel tuo account!