English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
preview
Tutto quello che c'è da apprendere sulla struttura del programma MQL5

Tutto quello che c'è da apprendere sulla struttura del programma MQL5

MetaTrader 5Trading |
256 3
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introduzione

Ogni software in qualsiasi linguaggio di programmazione ha una struttura, dopo averla compresa possiamo creare o sviluppare il nostro software senza problemi. I programmi del linguaggio MQL5 hanno la stessa struttura di qualsiasi altro linguaggio di programmazione e devono essere compresi dallo sviluppatore per raggiungere gli obiettivi del suo progetto in modo fluido ed efficace. In questo articolo, forniremo informazioni in questo contesto per cercare di distribuire il contenuto nel modo più semplice possibile. Impareremo la struttura di qualsiasi programma MQL5 trattando i seguenti argomenti:

Dopo gli argomenti precedenti, si suppone che abbiate compreso molto bene la struttura di qualsiasi programma MQL5 e che possiate creare o sviluppare qualsiasi software basato su questa struttura in modo fluido ed efficace.

Avvertenza: Tutte le informazioni sono fornite "così come sono" solo a scopo didattico e non sono preparate per scopi commerciali o di consulenza. Le informazioni non garantiscono alcun tipo di risultato. Se scegliete di utilizzare questi materiali su uno qualsiasi dei vostri conti di trading, lo farete a vostro rischio e pericolo e sarete gli unici responsabili.


Preprocessore

In questa parte, impareremo a conoscere in dettaglio il preprocessore come concetto di programmazione. Il preprocessore è un passo fondamentale nel processo di compilazione. Avviene prima dell'effettiva compilazione di un programma. Durante la fase di preelaborazione, vengono eseguite varie azioni, come l'inclusione di file, la determinazione delle proprietà del software, la definizione di costanti e l'importazione di funzioni.

Tutte le direttive del preprocessore iniziano con (#).  Queste direttive non sono considerate dichiarazioni linguistiche. Di conseguenza, non devono terminare con un punto e virgola (;). L'inclusione di un punto e virgola alla fine di una direttiva del preprocessore può causare errori in base al tipo di direttiva.

In altre parole, possiamo dire che il preprocessore ha lo scopo di preparare il codice sorgente del programma prima del processo di compilazione. Esistono molti tipi di direttive del preprocessore basate sui parametri che dobbiamo determinare nel programma MQL5, come i seguenti:

  • Sostituzione Macro (#define)
  • Proprietà del Programma (#property)
  • Includere i File (#include)
  • Importazione di Funzioni (#import)
  • Compilazione Condizionale (#ifdef, #ifndef, #else, #endif)

Sostituzione Macro (#define):

La direttiva del preprocessore #define può essere utilizzata per creare costanti simboliche o per definire costanti da utilizzare nel programma. Se non sapete cos'è una costante, si tratta di un identificatore che ha un valore che non cambia. Possiamo anche dire che la direttiva #define può essere usata per assegnare nomi mnemonici alle costanti, dato che useremo un valore sostitutivo per un identificatore specifico. Il primo formato di questa direttiva del preprocessore è il seguente:

#define identifier replacement-value

Quindi, abbiamo questa riga di codice nel nostro programma che significa che l'identificatore sarà sostituito da un valore sostitutivo prima della compilazione del programma. Questo formato è la direttiva #define senza parametri o formato parameter-free e c'è un altro formato in MQL5 che è il formato parametrico con un massimo di otto parametri consentiti che possono essere usati con la direttiva #define come il seguente:

#define identifier (param1, param2,... param5)

Le stesse regole delle variabili regolano l'identificatore delle costanti:

  • Il valore può essere di qualsiasi tipo, come integer, double o string.
  • L'espressione può essere composta da più token e termina quando la riga viene terminata e non può essere spostata alla riga di codice successiva.

Il seguente è un esempio di ciò:

//Parameter-free format
#define INTEGER               10                                     //int
#define DOUBLE                10.50                                  //double
#define STRING_VALUE      "MetaQuotes Software Corp."                //str
#define INCOMPLETE_VALUE INTEGER+DOUBLE                              //Incomlete
#define COMPLETE_VALUE (INTEGER+DOUBLE)                              //complete
//Parametic format
#define A 2+3
#define B 5-1
#define MUL(a, b) ((a)*(b))
double c=MUL(A,B);
//function to print values
void defValues()
  {

   Print("INTEGER Value, ",INTEGER);         //result: INTEGER Value, 10
   Print("DOUBLE Value, ",DOUBLE);           //result: DOUBLE Value, 10.50
   Print("STRING Value, ",STRING_VALUE);     //result: STRING Value, MetaQuotes Software Corp.
   Print("INCOMPLETE Value, ",INCOMPLETE_VALUE*2);     //result: INCOMPLETE Value, 31
   Print("COMPLETE Value, ",COMPLETE_VALUE*2);     //result: STRING Value, 41
   Print("c= ",c);                                  //result: c= 41
  }

Esiste anche la direttiva del preprocessore (#undef) che annulla ciò che è stato dichiarato o definito in precedenza.

Proprietà del Programma (#property):

Quando creiamo il nostro software, potremmo trovarci nella necessità di specificare parametri aggiuntivi; possiamo farlo usando #property. Queste proprietà devono essere specificate nel file main mql5 e non nel file include; quelle specificate nei file include saranno ignorate. Quindi, possiamo dire che la direttiva #property specifica proprietà aggiuntive per il programma. Se ci chiediamo cosa dobbiamo specificare in questo contesto, possiamo rispondere che abbiamo molte cose, come ad esempio indicatori, script, informazioni descrittive e proprietà delle librerie. Come le altre direttive del preprocessore, le #property saranno specificate nella parte superiore del codice sorgente e saranno visualizzate nella scheda comune della finestra del programma durante l'esecuzione.

Il seguente è un esempio di questo tipo di direttiva del preprocessore:

#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Property preprocessor"

Questi valori possono essere visualizzati nella finestra del programma come nella figura seguente:

property

Come si può vedere nell'immagine precedente, nella scheda comune sono state definite le proprietà di cui abbiamo bisogno durante l'esecuzione dell'EA e il testo di copyright 2023, MetaQuotes Ltd. è un collegamento ipertestuale che si può vedere al passaggio del mouse e che, se premuto, porta al link della proprietà.

Includere i File (#include):

Come di consueto, tutte le direttive #include saranno posizionate all'inizio del programma. Specifica che un file deve essere incluso in un software specifico, il che significa che il file incluso diventa parte del software e si può usare il suo contenuto, come variabili, funzioni e classi.

Esistono due formati per includere i file tramite la direttiva #include:

#include <File_Name.mqh>
#include "File_Name.mqh"

La differenza tra questi due formati è la posizione in cui il compilatore deve cercare il file da includere: il primo permette al compilatore di cercare il file nella cartella Include dell'installazione di MetaTrader 5 o nel file di intestazione della libreria standard, mentre il secondo permette al compilatore di cercare il file nella stessa directory del file del programma.

Importazione di Funzioni (#import):

La direttiva #import viene utilizzata per importare nel software funzioni da moduli MQL5 compilati (file *.ex5) e da moduli del sistema operativo (file *.dll). la funzione deve essere descritta in modo completo e il suo formato deve essere uguale al seguente:

#import "File_Name"
    func1 define;
    func2 define;
    ...
    funcN define;
#import

Compilazione condizionale (#ifdef, #ifndef, #else, #endif):

La compilazione condizionale permette di controllare l'esecuzione delle direttive di preprocessamento oltre alla compilazione del programma. Permette di controllare la compilazione o il salto di una parte del codice del programma in base a una condizione specifica e può essere uno dei seguenti formati:

#ifdef identifier
   //If the identifier has been defined, the code here will be compiled.
#endif
#ifndef identifier
   // If the identifier is not defined, the code here will be compiled.
#endif

Come abbiamo detto in precedenza, se si passa a una nuova riga le direttive del preprocessore non proseguono, ma in questo caso questo tipo di direttive può essere seguito da un numero qualsiasi di righe, utilizzando gli #else e gli #endif. Se la condizione è vera, le righe tra questi due #else e #endif saranno ignorate, ma se la condizione non è soddisfatta, le righe tra il controllo e #else (o #endif se il primo è assente) saranno ignorate.

Per ulteriori informazioni sul Preprocessore in MQL5, consultare il riferimento MQL.


Variabili di Input e Globali

In questa parte, identificheremo altri componenti della struttura del programma MQL5 dopo le direttive del preprocessore, ovvero le variabili di input e globali. Inizieremo con le variabili di input, che definiscono la variabile esterna dopo aver scritto il modificatore di input per specificare il tipo di dati. Quindi, abbiamo il modificatore di input e i valori della variabile di input; il modificatore di input non può essere modificato all'interno del programma mql5, ma i valori possono essere modificati solo dall'utente del programma dalla finestra Inputs o dalla scheda delle proprietà del programma. Quando si definiscono queste variabili esterne con il modificatore di input, vengono sempre reinizializzate prima che venga richiamato OnInIt().

Di seguito è riportato il formato delle variabili di input:

input int            MA_Period=20;
input int            MA_Shift=0;
input ENUM_MA_METHOD MA_Method=MODE_SMA;

In seguito, la finestra di input che l'utente deve determinare è la stessa dell'immagine seguente:

input

Come si può notare, è possibile definire il periodo della MA, lo spostamento della MA e il tipo di MA. Si può anche determinare l'aspetto dei parametri di input nella scheda Inputs, inserendo un commento con ciò che si desidera vedere nella finestra, come nel seguente caso per lo stesso esempio precedente:

input int            MA_Period=20;        //Moving Average Period 
input int            MA_Shift=0;          //Moving Average Shift
input ENUM_MA_METHOD MA_Method=MODE_SMA;  //Moving Average Type

Possiamo trovare i parametri nella scheda Input uguali ai seguenti:

input1

Come si può notare, i parametri sono diversi da quelli visti nell'immagine precedente. Per saperne di più sulle Variabili di Input, consultare il riferimento MQL5.

Le variabili globali devono essere create al di fuori dei gestori di eventi o delle funzioni create allo stesso livello delle funzioni e se vogliamo vedere un esempio di queste variabili globali possiamo vedere che è uguale al seguente:

int Globalvar;   // Global variable before or outside the event handler and functions
int OnInit()
  {
   ...
  }

Quindi, possiamo dire che l'ambito delle variabili globali è l'intero programma e sono accessibili da tutte le funzioni del programma, inizializzate una volta quando il programma viene caricato e prima della gestione dell'evento OnInit o OnStart(); parleremo dei gestori degli eventi più avanti, ma qui li menziono per presentare la posizione delle variabili globali nella struttura del programma MQL5.

Per saperne di più sulle Variabili Globali, consultare il riferimento MQL5.


Funzioni, Classi

In questa parte, parleremo di altri componenti della struttura del programma MQL5 dopo i preprocessori, gli input e le variabili globali ci sono le funzioni e le classi. C'è un precedente articolo dettagliato sulle funzioni che potete leggere per approfondire questi interessanti argomenti Comprendere le funzioni in MQL5 con le applicazioni. Se avete bisogno di leggere qualcosa sulle classi nel contesto della comprensione della Programmazione Orientata agli Oggetti (OOP) in MQL5, potete leggere anche l’articolo a riguardo Comprendere la Programmazione Orientata agli Oggetti (OOP) in MQL5 Spero lo troviate utile.

In questa sede, citeremo la posizione di questo importante componente in qualsiasi software, proprio come le classi personalizzate, poiché possiamo definirle in qualsiasi punto del software e possono essere definite nei file include che possono essere inclusi utilizzando la direttiva #include, proprio come abbiamo menzionato nell'argomento del preprocessore. Possono essere posizionati prima o dopo i gestori degli eventi e sotto le variabili di input e globali.

Il formato delle funzioni è il seguente:

returnedDataType functionName(param1, param2)
{
        bodyOfFunction
}

Il formato delle classi è il seguente:

class Cobject
{
   int var1;       // variable1
   double var2;    // variable1
   void method1(); // Method or function1
};

Per saperne di più sulle Funzioni e sulle Classi, consultare il manuale di riferimento MQL5.


Gestori Evento

In questa parte, condivideremo informazioni sui gestori di evento, che sono componenti molto importanti nel programma mql5. Il gestore di evento è una funzione eseguibile quando si verifica un evento specifico, ad esempio quando l’expert advisor riceve una nuova quotazione, ovvero un nuovo evento tick, il gestore dell’evento OnTick() sarà eseguibile in quanto questo gestore di evento contiene il corpo del codice che può essere eseguito quando si verifica la ricezione di un nuovo prezzo o tick.

In base al tipo di programma MQL5, esistono diversi gestori di evento, che vengono descritti di seguito:

Gestore dell'evento Descrizione Formato 
OnStart Questo gestore può essere utilizzato nei programmi di tipo script per chiamare una funzione quando si verifica l'evento start.
  • Versione con valore di ritorno: 
int  OnStart(void);
  • Versione senza valore di ritorno:
void  OnStart(void);
OnInit Può essere utilizzato nei programmi EA e negli indicatori per richiamare una funzione al momento dell'inizializzazione del programma.
  •  Versione con valore di ritorno:
int  OnInit(void);
  • Versione senza valore di ritorno:
void  OnInit(void);

OnDeinit Può essere utilizzato nei programmi EA e negli indicatori per richiamare una funzione quando viene de-inizializzato il programma.
void  OnDeinit(
   const int  reason         // deinitialization reason code
   );
OnTick Può essere utilizzato negli EA e negli indicatori per richiamare una funzione quando si ricevono nuove quotazioni.
void  OnTick(void);
OnCalculate Può essere utilizzato negli indicatori per chiamare una funzione quando viene inviato l'evento Init e ad ogni variazione dei dati di prezzo.
  • Calcoli basati su array di dati
int  OnCalculate(
   const int        rates_total,       // price[] array size
   const int        prev_calculated,   // number of handled bars at the previous call
   const int        begin,             // index number in the price[] array meaningful data starts from
   const double&    price[]            // array of values for calculation
   );
  • Calcoli basati sulla serie temporale del timeframe corrente
int  OnCalculate(
   const int        rates_total,       // size of input time series
   const int        prev_calculated,   // number of handled bars at the previous call
   const datetime&  time{},            // Time array
   const double&    open[],            // Open array
   const double&    high[],            // High array
   const double&    low[],             // Low array
   const double&    close[],           // Close array
   const long&      tick_volume[],     // Tick Volume array
   const long&      volume[],          // Real Volume array
   const int&       spread[]           // Spread array
   );
OnTimer Può essere utilizzato negli EA e negli indicatori per chiamare una funzione quando si verifica l'evento periodico Timer da parte del terminale di trading.
void  OnTimer(void);
OnTrade Può essere utilizzato negli EA per chiamare una funzione quando un'operazione di trade viene completata su un server di trade.
void  OnTrade(void);
OnTradeTransaction Può essere utilizzato negli EA per richiamare una funzione quando si eseguono alcune azioni definite su un conto di trade
void  OnTradeTransaction()
   const MqlTradeTransaction&    trans,     // trade transaction structure
   const MqlTradeRequest&        request,   // request structure
   const MqlTradeResult&         result     // response structure
   );
OnBookEvent Può essere utilizzato negli EA per richiamare una funzione quando viene modificata la profondità del mercato.
void  OnBookEvent(
   const string&  symbol         // symbol
   );
OnChartEvent Può essere utilizzato negli indicatori per richiamare una funzione quando l'utente lavora con un grafico.
void  OnChartEvent()
   const int       id,       // event ID 
   const long&     lparam,   // long type event parameter
   const double&   dparam,   // double type event parameter
   const string&   sparam    // string type event parameter
   );
OnTester Può essere utilizzato negli EA per richiamare una funzione quando il test di un Expert Advisor sui dati storici è terminato.
double  OnTester(void);
OnTesterInit Può essere utilizzato negli EA per chiamare una funzione con l'inizio dell'ottimizzazione nel tester di strategia prima del primo passaggio di ottimizzazione.
  • Versione con valore di ritorno
int  OnTesterInit(void);
  • Versione senza valore di ritorno
void  OnTesterInit(void);
OnTesterDeinit Può essere utilizzato negli EA per richiamare una funzione al termine dell'ottimizzazione di un Expert Advisor nel tester di strategia.
void  OnTesterDeinit(void);
OnTesterPass Può essere utilizzato negli EA per richiamare una funzione quando viene ricevuto un nuovo frame di dati.
void  OnTesterPass(void);

Per saperne di più sulla Gestione degli Eventi, consultare il riferimento MQL5.


Esempio di programma MQL5

In questa parte, applicheremo quanto appreso per creare una semplice applicazione utilizzando la giusta struttura MQL5. Abbiamo detto che possiamo usare i componenti della struttura MQL5 in base al tipo di programma e al compito necessario, perché non ci sono obblighi nell'uso di alcuni di questi componenti, come ad esempio l'uso del preprocessore #include, perché potrebbe non essere necessario includere alcun file esterno, così come la #property, perché è un'opzione da usare o meno, oltre al fatto che potrebbe essere necessario o meno creare classi o funzioni personalizzate nel vostro programma. In ogni caso, si utilizzerà ciò che è necessario per il proprio programma e le seguenti sono alcune semplici applicazioni per presentare tutti i componenti della struttura necessari in base ai diversi tipi di programma.

Tipo Script:

Quello che segue è un semplice esempio di script MQL5 in grado di calcolare e sommare due numeri immessi dall'utente tramite gli input e di stampare il risultato nella scheda Expert utilizzando la funzione Print. È necessario ricordare che in questo programma script aggiungeremo una #property che consente di mostrare gli input dello script per l'inserimento di numeri da parte dell'utente.

//+------------------------------------------------------------------+
//|                                       Script program example.mq5 |
//|                                   Copyright 2023, MetaQuotes Ltd.|
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
//property preprocessor
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property script_show_inputs
//inputs
input int userEntryNum1;
input int userEntryNum2;
//global variable
int result;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
//event handler
void OnStart()
  {
   result=userEntryNum1+userEntryNum2;
   Print("Result: ", result);
  }
//+------------------------------------------------------------------+

Se vogliamo creare un altro programma EA o indicatore, dobbiamo utilizzare gestori di eventi differenti in base al tipo di programma. Ad esempio, un programma EA può eseguire un'azione quando riceve un nuovo tick utilizzando il gestore di evento OnTick().

Ora che abbiamo identificato la struttura del programma MQL5, vediamo che alcuni componenti variano a seconda del tipo di programma e dei suoi obiettivi o compiti. Questa comprensione ci aiuta a identificare la posizione di ciascun componente nel software.

Per applicare queste conoscenze, possiamo iniziare con un semplice programma script, come già detto.


Conclusioni

Dopo quanto detto negli argomenti di questo articolo, si suppone che abbiate compreso la struttura di qualsiasi programma MQL5 e che siate in grado di identificare ciò che vi serve come componenti per creare il vostro software MQL5 in base al suo tipo, poiché abbiamo imparato ciò che serve sapere per costruire la struttura MQL5 che è la stessa della seguente sequenza:

  • Il Preprocessore
    • Sostituzione Macro (#define)
    • Proprietà del Programma (#property)
    • Includere i File (#include)
    • Importazione di Funzioni (#import)
    • Compilazione Condizionale (#ifdef, #ifndef, #else, #endif)
  • Variabili di Input e Globali
  • Funzioni e classi
  • Gestori Evento
    • OnStart
    • OnInit
    • OnDeinit
    • OnTick
    • OnCalculate
    • OnTimer
    • OnTrade
    • OnTradeTransaction
    • OnBookEvent
    • OnChartEvent
    • OnTester
    • OnTesterInit
    • OnTesterDeinit
    • OnTesterPass

Spero che questo articolo vi sia stato utile per costruire il vostro programma MQL5. Per un processo fluido ed efficace, è essenziale comprenderne il contesto. Se volete saperne di più sulla creazione di un sistema di trading utilizzando i più diffusi indicatori tecnici, potete consultare i miei articoli pubblicati in precedenza su questo argomento.

Inoltre, ho scritto sulla creazione e utilizzo di indicatori personalizzati in qualsiasi EA e di altri argomenti essenziali della programmazione MQL5, come la Programmazione Orientata agli Oggetti (OOP) e le funzioni. Credo che questi articoli saranno preziosi per il vostro percorso di apprendimento e di trading.

Tradotto dall’inglese da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/en/articles/13021

File allegati |
Ultimi commenti | Vai alla discussione (3)
Valeriy Yastremskiy
Valeriy Yastremskiy | 20 ott 2023 a 14:05
Vorrei vedere meno ristampe di documentazione senza spiegazioni. Non una parola sulla struttura)
Aleksandr Slavskii
Aleksandr Slavskii | 20 ott 2023 a 15:31
Valeriy Yastremskiy #:
Vorrei che ci fossero meno ristampe di documentazione senza spiegazioni.

+

Gerard William G J B M Dinh Sy
Gerard William G J B M Dinh Sy | 20 ago 2025 a 09:29
Tante cose da dire e poche parole su argomenti che tutti considerano banali, anche se sono il punto di partenza di ogni buon codice...

Regole di denominazione,
gestione degli errori,
gestione dei log,
e, soprattutto, l'implementazione di tutta una serie di processi che vi permetteranno di eseguire il debug in modo rapido ed efficiente.
Introduzione a MQL5 Algo Forge Introduzione a MQL5 Algo Forge
Stiamo introducendo MQL5 Algo Forge - un portale dedicato agli sviluppatori di trading algoritmico. Combina la potenza di Git con un'interfaccia intuitiva per gestire e organizzare i progetti all'interno dell'ecosistema MQL5. Qui è possibile seguire autori interessanti, formare team e collaborare a progetti di trading algoritmico.
Comprendere le funzioni in MQL5 con le applicazioni Comprendere le funzioni in MQL5 con le applicazioni
Le funzioni sono elementi critici in qualsiasi linguaggio di programmazione, aiutano gli sviluppatori ad applicare il concetto di (DRY), che significa non ripetersi, e molti altri vantaggi. In questo articolo troverete molte altre informazioni sulle funzioni e su come creare le nostre funzioni in MQL5 con semplici applicazioni che possono essere utilizzate o richiamate in qualsiasi sistema per arricchire il vostro sistema di trading senza complicare le cose.
Testare i diversi tipi di media mobile per vedere quanto sono efficaci Testare i diversi tipi di media mobile per vedere quanto sono efficaci
Conosciamo tutti l'importanza per molti trader dell'indicatore Media Mobile. Esistono altri tipi di Media Mobile che possono essere utili nel trading; in questo articolo le identificheremo e faremo un semplice confronto tra ognuno di loro e il tipo di media mobile semplice più popolare per vedere quale può mostrare i risultati migliori.
Sviluppo di un robot di trading in Python (parte 3): Implementazione di un algoritmo di trading basato su un modello Sviluppo di un robot di trading in Python (parte 3): Implementazione di un algoritmo di trading basato su un modello
Continuiamo la serie di articoli sullo sviluppo di un robot di trading in Python e MQL5. In questo articolo creeremo un algoritmo di trading in Python.