English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Fondamenti di programmazione MQL5: Variabili Globali del Terminale

Fondamenti di programmazione MQL5: Variabili Globali del Terminale

MetaTrader 5Esempi | 12 gennaio 2022, 11:41
227 0
Denis Kirichenko
Denis Kirichenko

Introduzione

Nell'ambiente MQL4/5 c'è uno strumento interessante - variabili globali del terminale client. Consente di creare aree di archiviazione dati condivise per tutti i programmi del terminale. Inoltre, l’attività di quest'area non si arresta alla chiusura del terminal. Questo articolo suggerisce di utilizzare gli strumenti di programmazione orientata agli oggetti per avere un'idea chiara di quali siano le variabili globali del terminale.

Più avanti nell'articolo, le variabili globali del terminale client verranno chiamate "variabili globali" se non diversamente specificato.


1. Variabili globali, funzioni

Dal punto di vista di un programmatore, una variabile globale è un'area di memoria denominata, disponibile per tutti i programmi di lavoro di un terminale di trading. I programmatori alle prime armi dovrebbero notare che se ci sono più terminali che funzionano contemporaneamente, ognuno di essi avrà il proprio spazio di memoria indipendente per le variabili globali. Non si sovrapporranno.

Gli sviluppatori del linguaggio specificano nella Documentazione che ci sono 11 funzioni utilizzate per lavorare con le variabili globali.

La teoria può essere trovata nella sezione "GlobalVariables" del libro di testo MQL4.

Nelle prossime sezioni utilizzerò gli strumenti di programmazione orientata agli oggetti per l'implementazione di task prefissati.


2. Class CGlobalVar

Guidati dalle idee della programmazione orientata agli oggetti, creiamo la classe CGlobalVar, che sarà direttamente responsabile dell'oggetto di una variabile globale.

//+------------------------------------------------------------------+
//| Class CGlobalVar                                                 |
//+------------------------------------------------------------------+
class CGlobalVar : public CObject
  {
   //--- === Data members === --- 
private:
   string            m_name;
   double            m_value;
   //---
   datetime          m_create_time;
   datetime          m_last_time;
   //--- flag for temporary var
   bool              m_is_temp;

   //--- === Methods === --- 
public:
   //--- constructor/destructor
   void              CGlobalVar(void);
   void              CGlobalVar(const string _var_name,const double _var_val,
                                const datetime _create_time);
   void             ~CGlobalVar(void){};
   //--- create/delete
   bool              Create(const string _var_name,const double _var_val=0.0,
                            const bool _is_temp=false);
   bool              Delete(void);
   //--- exist
   bool              IsGlobalVar(const string _var_name,bool _to_print=false);

   //--- set methods
   bool              Value(const double _var_val);
   bool              ValueOnCondition(const double _var_new_val,const double _var_check_val);

   //--- get methods
   string            Name(void) const;
   datetime          CreateTime(void) const;
   datetime          LastTime(void);
   template<typename T>
   T                 GetValue(T _type) const;
   bool              IsTemporary(void) const;
   //---
private:
   string            FormName(const string _base_name,const bool _is_temp=false);
  };

Cosa deve includere una classe? Per un elenco di attributi minimo, sceglierei le seguenti proprietà:

  • nome di una variabile;
  • valore di una variabile;
  • tempo di creazione;
  • ora dell'ultima chiamata;
  • caratteristica di una variabile temporanea.

Per quanto riguarda i metodi, sono i seguenti:

  • Creazione
  • eliminazione;
  • verificare l'esistenza;
  • impostazione di un nuovo valore;
  • impostare un nuovo valore per condizione;
  • ricevere un nome;
  • ricevere un valore;
  • ricevendo un flag di variabile temporanea.

Il metodo CGlobalVar::GetValue dovrebbe essere menzionato separatamente. È un metodo modello. Restituisce il tipo di dati per il valore della variabile che un utente imposta come argomento.

Il problema qui è che in MQL una funzione può essere digitata solo tramite parametri. Pertanto è necessario aggiungere un parametro falso.

Creiamo lo script di test Globals_test1.mq5 dove lavoreremo con oggetti del tipo CGlobalVar.

#include "CGlobalVar.mqh"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   CGlobalVar gVar1;
//--- create a temporary global var
   if(gVar1.Create("Gvar1",3.123456789101235,true))
     {
      Print("\n---=== A new global var ===---");
      PrintFormat("Name: \"%s\"",gVar1.Name());
      PrintFormat("Is temporary: %d",gVar1.IsTemporary());

      //--- Get the value 
      //--- double type
      double d=0.0;
      double dRes=gVar1.GetValue(d);
      PrintFormat("Double value: %0.15f",dRes);
      //--- float type
      float f=0.0;
      float fRes=gVar1.GetValue(f);
      PrintFormat("Float value: %0.7f",fRes);
      //--- string type
      string s=NULL;
      string sRes=gVar1.GetValue(s);
      PrintFormat("String value: %s",sRes);

      //--- Set a new value 
      double new_val=3.191;
      if(gVar1.Value(new_val))
         PrintFormat("New value is set: %f",new_val);

      //--- Set a new value on condition
      new_val=3.18;
      if(gVar1.ValueOnCondition(3.18,3.191))
         PrintFormat("New value on conditionis set: %f",new_val);
     }
  }

Una variabile globale viene creata come segue:

gVar1.Create("Gvar1",3.123456789101235,true)

Il primo argomento è il componente di base del nome della variabile futura ("Gvar1"), il secondo argomento è il valore di (3.123456789101235) e il terzo argomento è la caratteristica che mostra che la variabile sarà temporanea (vera).

Il nome della variabile si crea aggiungendo al componente base il nome e il tipo di programma.

Nel mio caso è:

  1. Gvar1 - il componente di base;
  2. prog_Globals_test1 - programma in cui è stata creata la variabile (il suo nome è Globals_test1);
  3. il tipo di programma è - scr (script).

Premendo F3, la seguente voce dovrebbe apparire nell'elenco delle variabili globali nella finestra MetaTrader 5:

Fig. 1. Il valore della variabile Test_temp_var1_prog_Globals_test1_scr è pari a 3.18

Fig.1. Il valore della variabile Test_temp_var1_prog_Globals_test1_scr è pari a 3,18

Al suo lancio e implementazione di successo, le seguenti voci vengono stampate nella rivista "Esperti":

KP      0       10:20:20.736    Globals_test1 (AUDUSD.e,H1)     ---=== A new global var ===---
EH      0       10:20:21.095    Globals_test1 (AUDUSD.e,H1)     Name: "Gvar1_temp_prog_Globals_test1_scr"
LF      0       10:20:21.876    Globals_test1 (AUDUSD.e,H1)     Is temporary: 1
MO      0       10:20:31.470    Globals_test1 (AUDUSD.e,H1)     Double value: 3.123456789101235
KG      0       10:20:31.470    Globals_test1 (AUDUSD.e,H1)     Float value: 3.1234567
OP      0       10:20:31.470    Globals_test1 (AUDUSD.e,H1)     String value: 3.123456789101235
RH      0       10:20:31.470    Globals_test1 (AUDUSD.e,H1)     New value is set: 3.191000
DJ      0       10:20:31.470    Globals_test1 (AUDUSD.e,H1)     New value on conditionis set: 3.180000

Nel giornale vengono stampati diversi tipi di dati del valore della variabile.

Se il terminale MetaTrader 5 viene riavviato, la variabile Gvar1_temp_prog_Globals_test1_scr scompare dall'elenco delle variabili globali. Succede perché la variabile era temporanea e viveva mentre il terminale era aperto.

In MQL4/5, alla ricezione dei dati sulla variabile globale, non c'è modo di scoprire se la variabile è temporanea o meno. Forse il modo più semplice per identificare una variabile temporanea è aggiungere una chiave al nome della variabile. Ad esempio, può essere il suffisso "temp" nel nome della variabile. Tuttavia, la necessità di controllare la creazione del nome della variabile globale è un netto svantaggio di questo approccio, specialmente se tali variabili vengono create da altri programmi che non utilizzano la classe CGlobalVar.

Ad un certo punto volevo sapere quante variabili globali potevano essere create e quanto velocemente.

Ho leggermente modificato lo script precedente e l'ho chiamato Globals_test2.mq5. È stato lanciato con un numero diverso di corse. Ho riavviato il terminale dopo ogni esecuzione per eliminare le variabili.

#property script_show_inputs
//---
#include "CGlobalVar.mqh"

input uint InpCnt=10000; // Number of variables
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- start value
   uint start=GetTickCount();
//---
   for(uint idx=0;idx<InpCnt;idx++)
     {
      CGlobalVar gVar;
      //--- Create a temporary global var
      if(!gVar.Create("Test_var"+IntegerToString(idx+1),idx+0.15,true))
         Alert("Error creating a global variable!");
     }
//--- finish value
   uint time=GetTickCount()-start;
//--- to print
   PrintFormat("Creation of %d global variables took %d ms",InpCnt,time);
  }

Ecco il risultato (Fig.2)

Fig.2. Tempo speso per creare variabili globali temporanee

Fig.2. Tempo speso per creare variabili globali temporanee

Il risultato di un test simile per le variabili globali complete è presentato in Fig.3. La loro creazione non richiede molto più tempo.

Il motivo è che queste variabili vengono salvate sul disco nel file gvariables.dat situato nella cartella Profili.

Fig.3. Tempo speso per creare variabili globali complete

Fig.3. Tempo speso per creare variabili globali complete

Non credo che sia necessario creare così tante variabili globali. Ho condotto questa valutazione semplicemente per curiosità.

Nel prossimo passaggio lavoreremo con un insieme di variabili globali.


3. CGlobalVarList Class

Per regolare il lavoro con le variabili globali, creeremo una classe lista di variabili globali del tipo CGlobalVarList. Questo tipo di elenco è un discendente della classe di elenco standard CList.

La dichiarazione di classe può essere presentata come:

//+------------------------------------------------------------------+
//| Class CGlobalVarList                                             |
//+------------------------------------------------------------------+
class CGlobalVarList : public CList
  {
   //--- === Data members === --- 
private:
   ENUM_GVARS_TYPE   m_gvars_type;

   //--- === Methods === --- 
public:
   //--- constructor/destructor
   void              CGlobalVarList(void);
   void             ~CGlobalVarList(void){};
   //--- load/unload
   bool              LoadCurrentGlobals(void);
   bool              KillCurrentGlobals(void);
   //--- working with files
   virtual bool      Save(const int _file_ha);
   virtual bool      Load(const int _file_ha);
   //--- service
   void              Print(const int _digs);
   void              SetGvarType(const ENUM_GVARS_TYPE _gvar_type);
   //---
private:
   bool              CheckGlobalVar(const string _var_name);
  };

Se gli oggetti collegati alle variabili globali correnti devono essere inclusi in un elenco di tipo CGlobalVarList, viene utilizzato il metodo CGlobalVarList::LoadCurrentGlobals.

//+------------------------------------------------------------------+
//| Load current global vars                                         |
//+------------------------------------------------------------------+
bool CGlobalVarList::LoadCurrentGlobals(void)
  {
   ENUM_GVARS_TYPE curr_gvar_type=this.m_gvars_type;
   int gvars_cnt=GlobalVariablesTotal();
//---
   for(int idx=0;idx<gvars_cnt;idx++)
     {
      string gvar_name=GlobalVariableName(idx);
      if(this.CheckGlobalVar(gvar_name))
         continue;

      //--- gvar properties
      double gvar_val=GlobalVariableGet(gvar_name);
      datetime gvar_time=GlobalVariableTime(gvar_name);
      CGlobalVar *ptr_gvar=new CGlobalVar(gvar_name,gvar_val,gvar_time);
      //--- control gvar type 
      if(CheckPointer(ptr_gvar)==POINTER_DYNAMIC)
        {
         if(curr_gvar_type>GVARS_TYPE_ALL)
           {
            bool is_temp=ptr_gvar.IsTemporary();
            //--- only full-fledged
            if(curr_gvar_type==GVARS_TYPE_FULL)
              {if(is_temp)continue;}
            //--- only temporary
            else if(curr_gvar_type==GVARS_TYPE_TEMP)
              {if(!is_temp)continue;}
           }
         //--- try to add
         if(this.Add(ptr_gvar)>-1)
            continue;
        }
      //---
      return false;
     }
//---
   return true;
  }

Questo metodo legge tutte le variabili globali presenti e le include nell'elenco.

L'attributo m_gvars_type controlla il tipo della variabile globale inclusa. È un'enumerazione del tipo ENUM_GVARS_TYPE:

//+------------------------------------------------------------------+
//| Enumeration for gvars type                                       |
//+------------------------------------------------------------------+
enum ENUM_GVARS_TYPE
  {
   GVARS_TYPE_ALL=-1,  // all global
   GVARS_TYPE_FULL=0,  // only full
   GVARS_TYPE_TEMP=1,  // only temporary
  };

Supponiamo che prima dell'inizializzazione della lista CGlobalVarList, ci fosse un insieme di variabili globali come presentato in Fig.4.

Fig.4. Insieme approssimativo di variabili globali

Fig.4. Insieme approssimativo di variabili globali

Verificheremo se questo set verrà elaborato correttamente dall'elenco. Per effettuare tale verifica verrà creato lo script di test Globals_test3.mq5.

#include "CGlobalVarList.mqh"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   CGlobalVarList gvarList;
   gvarList.LoadCurrentGlobals();   
   PrintFormat("Number of variables in the set: %d",gvarList.Total());
  }

Nuove variabili globali (evidenziate in giallo) sono apparse dopo il lancio dello script, cosa che non doveva avvenire (Fig.5).

Fig.5. Nuovo set di variabili globali

Fig.5. Numero di variabili globali.

Una stringa è stata stampata come:

2014.10.21 11:35:00.839       Globals_test3 (AUDUSD.e,H1)              Number of variables in the list: 10

È successo perché nella dichiarazione del metodo CGlobalVarList::LoadCurrentGlobals c'è un riferimento al metodo CGlobalVar::Create.

Ciò significa che nella stringa viene creata una nuova variabile globale:

if(ptr_gvar.Create(gvar_name,gvar_val))

Inoltre, gli indici delle variabili globali cambiano man mano che vengono visualizzate nuove variabili. Questo è ciò che causa la confusione.

Consiglierei di sostituire il metodo CGlobalVar::Create con uno meno attivo. Un costruttore con parametri deve essere aggiunto alla classe CGlobalVar in modo che la variabile possa essere presa in considerazione nell'elenco.

Dopo la modifica, il metodo CGlobalVarList::LoadCurrentGlobals ha il seguente aspetto:

//+------------------------------------------------------------------+
//| Load current global vars                                         |
//+------------------------------------------------------------------+
bool CGlobalVarList::LoadCurrentGlobals(void)
  {
   int gvars_cnt=GlobalVariablesTotal();
//---
   for(int idx=0;idx<gvars_cnt;idx++)
     {
      string gvar_name=GlobalVariableName(idx);
      double gvar_val=GlobalVariableGet(gvar_name);
      datetime gvar_time=GlobalVariableTime(gvar_name);
      CGlobalVar *ptr_gvar=new CGlobalVar(gvar_name,gvar_val,gvar_time);
      if(CheckPointer(ptr_gvar)==POINTER_DYNAMIC)
         if(this.Add(ptr_gvar)>-1)
            continue;
      //---
      return false;
     }
//---
   return true;
  }

Lo script funziona correttamente dopo che il metodo è stato modificato. Viene stampato il seguente record:

2014.10.21 11:38:04.424      Globals_test3 (AUDUSD.e,H1)              Number of variables in the list: 6

Quindi aggiungeremo funzionalità che consentono di eliminare e stampare un elenco.

Ora lo script Globals_test3.mq5 ha il seguente aspetto:

//---
#include "CGlobalVarList.mqh"
//---
input ENUM_GVARS_TYPE InpGvarType=GVARS_TYPE_FULL; // Set gvar type
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   CGlobalVarList gvarList;
//--- delete gvars
   gvarList.SetGvarType(InpGvarType);
//--- load current gvars  
   gvarList.LoadCurrentGlobals();
   Print("Print the list before deletion.");
   gvarList.Print(10);
//--- delete gvars
   if(gvarList.KillCurrentGlobals())
     {
      Print("Print the screen after deletion.");
      gvarList.Print(10);
     }
  }

Complicheremo il compito creando 10 variabili globali differenziate (Fig.6).

Fig.6. Variabili globali differenziate

Fig.6. Variabili globali differenziate

Solo le variabili complete saranno incluse nella nostra lista gvarList. Quindi verranno eliminati.

La rivista "Esperto" conterrà quanto segue:

MG      0       11:05:01.113    Globals_test3 (AUDUSD.e,H1)     Print the list before deletion.
KL      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     
OI      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     ---===Local list===---
QS      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     Global variable type: GVARS_TYPE_FULL
RI      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     Total number of global variables: 10
EG      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     Number of global variables in current list: 5
RN      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     Gvar #1, name - gVar10_prog_test1_scr, value - 16.6400000000
KP      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     Gvar #2, name - gVar2_prog_test1_scr, value - 4.6400000000
GR      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     Gvar #3, name - gVar4_prog_test1_scr, value - 7.6400000000
RD      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     Gvar #4, name - gVar6_prog_test1_scr, value - 10.6400000000
LJ      0       11:05:01.613    Globals_test3 (AUDUSD.e,H1)     Gvar #5, name - gVar8_prog_test1_scr, value - 13.6400000000
EH      0       11:06:18.675    Globals_test3 (AUDUSD.e,H1)     Print the list after deletion.
FS      0       11:06:19.003    Globals_test3 (AUDUSD.e,H1)     
JJ      0       11:06:19.003    Globals_test3 (AUDUSD.e,H1)     ---===Local list===---
HN      0       11:06:19.003    Globals_test3 (AUDUSD.e,H1)     Global variable type: GVARS_TYPE_FULL
KH      0       11:06:19.003    Globals_test3 (AUDUSD.e,H1)     Total number of global variables: 5
QP      0       11:06:19.003    Globals_test3 (AUDUSD.e,H1)     Number of global variables in the current list: 0

L'elenco che include solo le variabili globali complete è stato creato correttamente.

Quindi è stato cancellato e nel terminale sono rimaste solo 5 variabili temporanee (Fig.7).

Fig.7. Variabili globali temporanee

Fig.7. Variabili globali temporanee

Il compito previsto è stato compiuto.

Nella classe CGlobalVarList sono stati implementati anche i metodi per salvare i dati nel file e scaricare i dati dal file.


4. Applicazione pratica

Come è noto, MQL4/5 è un linguaggio di programmazione specializzato. È stato creato per programmare strategie di trading. Ecco perché qualsiasi strumento del linguaggio è da considerarsi come mezzo per formalizzare una certa idea di trading.

Ci sono abbastanza esempi di collegamento di Expert Advisor con variabili globali sulla piattaforma MQL5. Oggi suggerisco di esaminare da vicino la situazione in cui è richiesto il controllo sull'attuazione del programma.

Supponiamo che ci sia un codice del robot di trading "Globals_test_EA" basato su un approccio a moduli:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return INIT_SUCCEEDED;
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   Main();
  }

dove appare il modulo principale:

//+------------------------------------------------------------------+
//| Main module                                                      |
//+------------------------------------------------------------------+
void Main(void)
  {
//--- set flags for all modules
   for(int idx=0;idx<GVARS_LIST_SIZE;idx++)
      SetFlag(idx,false);

//--- Check the trade possibility and connectivity
//--- permission to trade
   if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
      //--- connection to the trading server
      if(TerminalInfoInteger(TERMINAL_CONNECTED))
         //--- permission to trade for the launched EA
         if(MQLInfoInteger(MQL_TRADE_ALLOWED))
           {
            //--- 1) opening module
            Open();
            //--- 2) closing module
            Close();
            //--- 3) Trailing Stop module
            Trail();
           }
  }

Questo è il modulo principale comprende 3 componenti:

  1. modulo di apertura;
  2. modulo di chiusura;
  3. Modulo Trailing Stop.

Ora abbiamo bisogno di creare variabili globali che controllano le fasi di esecuzione del programma.

Ci sono tre fasi sotto forma di moduli. Per ogni fase vengono utilizzati due punti di controllo. Il primo punto di controllo controlla l'inizio del lavoro del modulo e il secondo controlla la fine del lavoro del modulo.

I punti di controllo sono implementati sotto forma di variabili globali.

Quindi, abbiamo bisogno di sei variabili globali con i seguenti nomi:

//--- global variables: names
string gVar_names[6]=
  {
   "gvarOpen_start","gvarOpen_finish",
   "gvarClose_start","gvarClose_finish",
   "gvarTrail_start","gvarTrail_finish"
  };

I flag per tutti i moduli sono impostati all'inizio della funzione Main() e cancellati in ogni modulo separato. Inutile dire che stiamo parlando solo di bandiere "proprie". Ad esempio, facciamo riferimento al modulo Open():

//+------------------------------------------------------------------+
//| Open module                                                      |
//+------------------------------------------------------------------+
void Open(void)
  {
   Comment(curr_module+__FUNCTION__);
//---
   if(!IsStopped())
     {
      //--- clear the module start flag
      SetFlag(0,true);

      //--- assume that the module operates for approximately 1.25 s
        {
         Sleep(1250);
        }
      //--- clear the module finish flag
      SetFlag(1,true);
     }
  }

All'esecuzione del modulo, nella finestra del grafico viene visualizzato un commento che il programma sta lavorando nel blocco Open().

Quindi, se il programma non è stato forzato alla chiusura, il controllo passa alla funzione di impostare/cancellare un flag corrispondente. Nel caso in cui un flag non sia stato cancellato in uno qualsiasi dei punti di controllo, il modulo è considerato non aver terminato il lavoro.

Un modello di fasi di monitoraggio del lavoro del modulo con variabili globali è presentato in Fig. 8.

Fig.8. Modello per la sequenza di elaborazione dei flag

Fig. 8. Modello per la sequenza di elaborazione dei flag

Ad esempio, l'Expert Advisor "Globals_test_EA" è allegato al grafico e funziona normalmente.

Quando ho cancellato l'Expert Advisor dal grafico, nel journal è apparsa la seguente voce:

2014.10.22 20:14:29.575 Globals_test_EA (EURUSD.e,H1)   Program forced to terminate before execution: <<Open_finish>>

Pertanto, la chiusura dell'Expert Advisor è avvenuta in Open(). modulo.

Aprire l'elenco delle variabili globali premendo F3 (Fig.9).

Fig. 9. Variabili globali per Expert Advisor "Globals_test_EA"

Fig. 9. Variabili globali per Expert Advisor "Globals_test_EA"

Dall'aspetto dell'elenco, solo il flag responsabile dell'inizio del lavoro del modulo Open() è stato azzerato.

Sembra che potenziali guasti possano essere rilevati alla mancata esecuzione dei comandi legati alle posizioni di apertura, chiusura e manutenzione.

Dopo un rilancio del robot sullo stesso grafico, nel journal verranno visualizzate le seguenti informazioni:

RQ      0       20:28:25.135    Globals_test_EA (EURUSD.e,H1)   Non-zero value for: <<Open_finish>>
CL      0       20:28:25.135    Globals_test_EA (EURUSD.e,H1)   Non-zero value for: <<Close_start>>
DH      0       20:28:25.135    Globals_test_EA (EURUSD.e,H1)   Non-zero value for: <<Close_finish>>
ES      0       20:28:25.135    Globals_test_EA (EURUSD.e,H1)   Non-zero value for: <<Trail_start>>
RS      0       20:28:25.135    Globals_test_EA (EURUSD.e,H1)   Non-zero value for: <<Trail_finish>>

In questo modo riceviamo un avviso su un fallimento delle fasi del programma. Porta a un'altra domanda. Cosa si può fare se quelle fasi falliscono? Questa è una storia diversa.


Conclusione

In questo articolo ho dimostrato le capacità orientate agli oggetti del linguaggio MQL5 per la creazione di oggetti che facilitano il lavoro con le variabili globali del terminale.

Un caso in cui le variabili globali sono state utilizzate come punti di controllo per l'implementazione delle fasi del programma è servito come esempio.

Come sempre sono ben accetti commenti, suggerimenti e critiche costruttive.


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

File allegati |
globals_test1.mq5 (3.67 KB)
globals_test2.mq5 (2.92 KB)
globals_test3.mq5 (2.59 KB)
cglobalvar.mqh (20.52 KB)
cglobalvarlist.mqh (18.74 KB)
globals_test_ea.mq5 (13.01 KB)
Manuale statistico del trader ipotesi Manuale statistico del trader ipotesi
Questo articolo considera l'ipotesi, una delle idee di base della statistica matematica. Varie ipotesi vengono esaminate e verificate attraverso esempi utilizzando metodi di statistica matematica. I dati effettivi vengono generalizzati utilizzando metodi non parametrici. Per l'elaborazione dei dati vengono utilizzati il pacchetto Statistica e la libreria di analisi numerica ALGLIB MQL5 pilotata.
Grafico liquido Grafico liquido
Ti piacerebbe vedere un grafico orario con le barre che si aprono dal secondo e dal quinto minuto dell'ora? Che aspetto ha un grafico ridisegnato quando l'orario di apertura delle barre cambia ogni minuto? Quali vantaggi ha il trading su tali grafici? Troverai le risposte a queste domande in questo articolo.
Programmazione delle modalità di EA utilizzando l'approccio orientato agli oggetti Programmazione delle modalità di EA utilizzando l'approccio orientato agli oggetti
Questo articolo parla della programmazione di robot di trading multimodale in MQL5. Ogni modalità è implementata con l'approccio orientato agli oggetti. Vengono fornite istanze sia della gerarchia delle classi di modalità che delle classi per il test. Si suppone che la programmazione multimodale dei robot di trading tenga conto di tutte le peculiarità di ogni modalità operativa di un EA scritto in MQL5. Le funzioni e l'enumerazione vengono create per identificare la modalità.
Tracciare linee di tendenza basate su frattali utilizzando MQL4 e MQL5 Tracciare linee di tendenza basate su frattali utilizzando MQL4 e MQL5
L'articolo descrive l'automazione del tracciamento delle linee di tendenza in base all'indicatore Fractals utilizzando MQL4 e MQL5. La struttura dell'articolo fornisce una vista comparativa della soluzione per due lingue. Le linee di tendenza vengono tracciate utilizzando gli ultimi due frattali conosciuti.