Tutto quello che c'è da apprendere sulla struttura del programma MQL5
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:
- 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, Classi
- Gestori Evento
- Esempi di Programmi MQL5
- Conclusioni
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.
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:

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:

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:

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. |
int OnStart(void);
void OnStart(void); |
| OnInit | Può essere utilizzato nei programmi EA e negli indicatori per richiamare una funzione al momento dell'inizializzazione del programma. |
int OnInit(void);
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. |
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 );
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. |
int OnTesterInit(void);
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
Avvertimento: Tutti i diritti su questi materiali sono riservati a MetaQuotes Ltd. La copia o la ristampa di questi materiali in tutto o in parte sono proibite.
Questo articolo è stato scritto da un utente del sito e riflette le sue opinioni personali. MetaQuotes Ltd non è responsabile dell'accuratezza delle informazioni presentate, né di eventuali conseguenze derivanti dall'utilizzo delle soluzioni, strategie o raccomandazioni descritte.
Introduzione a MQL5 Algo Forge
Sviluppo di un robot di trading in Python (parte 3): Implementazione di un algoritmo di trading basato su un modello
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Accetti la politica del sito e le condizioni d’uso
È stato pubblicato l'articolo Tutto quello che c'è da sapere sulla struttura del programma MQL5:
Autore: Mohamed Abdelmaaboud
Vorrei che ci fossero meno ristampe di documentazione senza spiegazioni.
+