Tout ce qu'il faut savoir sur la structure d’un programme MQL5
Introduction
Chaque logiciel, quel que soit le langage de programmation, possède une structure. Après avoir compris cette structure, nous pouvons créer ou développer notre logiciel en douceur. Les programmes en langage MQL5 sont identiques à ceux de tout autre langage de programmation et leur structure est censée être comprise par le développeur afin d'atteindre les objectifs de son projet de manière fluide et efficace. Dans cet article, nous fournirons des informations dans ce contexte afin d'essayer de livrer son contenu aussi facilement que possible. Nous apprendrons la structure de tout programme MQL5 en abordant les sujets suivants :
- Préprocesseur
- Macro de substitution (#define)
- Propriétés du programme (#property)
- Inclure des fichiers (#include)
- Import de fonctions (#import)
- Compilation conditionnelle (#ifdef, #ifndef, #else, #endif)
- Variables d'entrée et variables globales
- Fonctions, classes
- Gestionnaires d'événements
- Exemples de programmes MQL5
- Conclusion
Suite à cela, je considérerai que vous comprenez très bien la structure de tout programme MQL5 et que vous pourrez créer ou développer n'importe quel logiciel basé sur cette structure de manière fluide et efficace.
Préprocesseur
Dans cette partie, nous allons découvrir en détail concept de programmation du préprocesseur. Le préprocesseur est une étape cruciale du processus de compilation. Elle intervient avant la compilation proprement dite d'un programme. Au cours de l'étape de prétraitement, diverses actions sont effectuées, telles que l'inclusion de fichiers, la détermination des propriétés du logiciel, la définition de constantes et l'import de fonctions.
Toutes les directives du préprocesseur commencent par le signe #. Ces directives ne sont pas considérées comme des déclarations linguistiques. Par conséquent, elles ne doivent pas être terminés par un point-virgule. L'ajout d'un point-virgule à la fin d'une directive du préprocesseur peut entraîner des erreurs en fonction du type de directive.
Autrement dit, le préprocesseur est destiné à préparer le code source du programme avant le processus de compilation. Il existe plusieurs types de directives de préprocesseur en fonction des paramètres que l'on doit déterminer dans le programme MQL5 :
- Macro de substitution (#define)
- Propriétés du programme (#property)
- Inclure des fichiers (#include)
- Import de fonctions (#import)
- Compilation conditionnelle (#ifdef, #ifndef, #else, #endif)
Macro de substitution (#define)
La directive #define du préprocesseur peut être utilisée pour créer des constantes symboliques ou pour définir des constantes à utiliser dans le programme. Si vous ne savez pas ce qu'est une constante, il s'agit d'un identifiant dont la valeur ne change pas. Nous pouvons également dire que la directive #define peut être utilisée pour attribuer des noms mnémoniques aux constantes, car nous utiliserons une valeur de remplacement pour un identifiant spécifique. Voici le premier format de cette directive du préprocesseur :
#define identifier replacement-value Cette ligne de code dans le programme signifie que l'identifiant sera remplacé par une certaine valeur avant la compilation du programme. Ce format est la directive #define avec ou sans paramètres. Il existe un autre format dans MQL5 qui est le format paramétrique avec un maximum autorisé de 8 paramètres, pouvant être utilisés avec la directive #define comme suit :
#define identifier (param1, param2,... param5) Les mêmes règles que pour les variables régissent l'identifiant des constantes :
- La valeur peut être de n'importe quel type : entier, double ou chaîne de caractères.
- L'expression peut être composée de plusieurs éléments et se termine à la fin de la ligne ; elle ne peut pas être déplacée vers la ligne de code suivante.
Voici un exemple :
//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 }
Il existe également la directive #undef du préprocesseur qui annule ce qui a été déclaré ou défini auparavant.
Propriétés du programme (#property)
Lorsque nous créons notre logiciel, il se peut que nous ayons besoin de spécifier des paramètres supplémentaires. Nous pouvons le faire en utilisant #property. Ces propriétés doivent être spécifiées dans le fichier mql5 principal et non dans un fichier inclus. Celles qui sont spécifiées dans les fichiers inclus seront ignorées. Nous pouvons donc dire que la directive #property spécifie des propriétés supplémentaires pour le programme. Si vous demandez ce que nous devons spécifier dans ce contexte, nous pouvons répondre à cette question en disant que nous avons beaucoup de choses comme, par exemple, des indicateurs, des scripts, des informations descriptives et des propriétés de bibliothèque. Comme les autres directives du préprocesseur, les #property sont spécifiées dans la partie supérieure du code source et sont affichées dans l'onglet commun de la fenêtre du programme lors de son exécution.
Voici un exemple de ce type de directive du préprocesseur :
#property copyright "Copyright 2023, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property description "Property preprocessor"
Nous pouvons voir ces valeurs dans la fenêtre du programme, comme dans l'image suivante :

Comme nous pouvons le voir dans l'image précédente, les propriétés définies sont affichées dans l'onglet commun lors de l'exécution de l'EA. Le texte du copyright « 2023, MetaQuotes Ltd. » est en plus un lien hypertexte.
Inclure des fichiers (#include)
Comme d'habitude, toutes les directives #include seront placées au début du programme. Il spécifie qu'un fichier doit être inclus dans un logiciel spécifique, ce qui signifie que le fichier inclus devient une partie du logiciel et que nous pouvons utiliser son contenu comme les variables, les fonctions et les classes.
Il existe 2 formats pour inclure des fichiers à l'aide de la directive #include :
#include <File_Name.mqh> #include "File_Name.mqh"
La différence entre ces deux formats est l'endroit où le compilateur doit chercher le fichier à inclure. Le premier format permet au compilateur de chercher le fichier dans le dossier Include de l'installation de MetaTrader 5 ou dans le fichier d'en-tête de la bibliothèque standard. Et le second format permet au compilateur de chercher le fichier dans le même répertoire que le fichier du programme.
Import de fonctions (#import)
La directive #import est utilisée pour importer des fonctions dans le logiciel à partir de modules MQL5 compilés (fichiers *.ex5) et de modules du système d'exploitation (fichiers *.dll). la fonction doit être entièrement décrite et son format doit être le même que le suivant :
#import "File_Name" func1 define; func2 define; ... funcN define; #import
Compilation conditionnelle (#ifdef, #ifndef, #else, #endif)
La compilation conditionnelle permet de contrôler les exécutions des directives de prétraitement en plus de la compilation du programme. Elle nous permet de contrôler la compilation ou l'omission d'une partie du code du programme sur la base d'une condition spécifique qui peut être l'un des formats suivants :
#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
Comme nous l'avons mentionné précédemment, si nous passons à une nouvelle ligne, les directives du préprocesseur ne continueront pas. Mais ici ce type de directive peut être suivi par un nombre quelconque de lignes en utilisant #else et #endif. Si la condition est vraie, les lignes entre ces deux #else et #endif seront ignorées, mais si la condition n'est pas remplie, les lignes entre le #ifdef/#ifndef et le #else (ou le #endif si le premier est absent) sont ignorées.
Pour en savoir plus sur le préprocesseur dans MQL5, consultez la référence MQL.
Variables d'entrée et variables globales
Dans cette partie, nous allons identifier d'autres composants de la structure du programme MQL5 : les variables d'entrée et les variables globales. Nous commencerons par les variables d'entrée, qui définissent une variable externe avec un type de données. Nous avons donc le modificateur d'entrée et les valeurs de la variable d'entrée. Le modificateur d'entrée ne peut pas être modifié à l'intérieur du programme mql5, les valeurs ne peuvent être modifiées que par l'utilisateur du programme à partir de la fenêtre ou de l'onglet Entrées des propriétés du programme. Lorsque nous définissons ces variables externes par le modificateur d'entrée, elles sont toujours réinitialisées avant que la fonction OnInIt() ne soit appelée.
Le format des variables d'entrée est le suivant :
input int MA_Period=20; input int MA_Shift=0; input ENUM_MA_METHOD MA_Method=MODE_SMA;
Ensuite, ces variables sont affichées dans la fenêtre d'entrée à déterminer par l'utilisateur, comme dans l'image suivante :

Comme nous pouvons le voir, nous pouvons définir la période de la MA, son décalage et son type. Nous pouvons également déterminer l'aspect des paramètres d'entrée dans l'onglet Entrées en plaçant un commentaire avec ce que nous devons voir dans la fenêtre, comme dans l'exemple précédent :
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
Dans l'onglet Entrées, nous verrons les paramètres suivants :

Comme nous pouvons le voir, les paramètres sont différents de ceux de l'image précédente. Pour en savoir plus sur les variables d'entrée, consultez la référence MQL5.
Les variables globales doivent être créées en dehors des gestionnaires d'événements ou des fonctions créées au même niveau que les fonctions. Voici un exemple de variables globales :
int Globalvar; // Global variable before or outside the event handler and functions int OnInit() { ... }
Nous pouvons donc dire que la portée des variables globales est l'ensemble du programme et qu'elles sont accessibles depuis toutes les fonctions du programme, initialisées une fois lorsque le programme est chargé et avant le traitement de l'événement OnInit ou OnStart(). Nous parlerons des gestionnaires d'événements plus tard, mais je les mentionne ici pour présenter la position des variables globales dans la structure du programme MQL5.
Pour en savoir plus sur les variables globales, consultez la référence MQL5.
Fonctions, classes
Dans cette partie, nous parlerons des autres composants de la structure du programme MQL5 : les fonctions et les classes. Vous pouvez lire l’article précédent Comprendre les fonctions dans MQL5 avec des applications sur les fonctions pour en savoir plus. Si vous voulez en savoir plus également sur les classes dans le contexte de la Programmation Orientée Objet (POO) dans MQL5, vous pouvez également lire mon article précédent à ce sujet dans l'article Comprendre la Programmation Orientée Objet (POO) de MQL5. J'espère que vous les trouverez utiles.
Mentionnons ici la place importante de ce composant dans n'importe quel logiciel, comme les classes personnalisées, car nous pouvons les définir n'importe où, voire dans des fichiers inclus avec la directive #include comme nous l'avons vu avec le préprocesseur. Elles peuvent être placées avant ou après les gestionnaires d'événements et en dessous des variables d'entrée et globales.
Le format des fonctions est le suivant :
returnedDataType functionName(param1, param2)
{
bodyOfFunction
} Le format des classes est le suivant :
class Cobject { int var1; // variable1 double var2; // variable1 void method1(); // Method or function1 };
Pour en savoir plus sur les fonctions et les classes, consultez la référence MQL5.
Gestionnaires d'événements
Dans cette partie, nous allons partager des informations sur les gestionnaires d'événements qui sont des composants très importants dans un programme mql5. Le gestionnaire d'événement est une fonction exécutable lorsqu'un événement spécifique se produit, par exemple lors de la réception d'une nouvelle cotation de prix ou d'un nouveau tick par l’expert advisor. Le gestionnaire d'événement OnTick() est alors exécutable, car il contient le corps du code qui peut être exécuté lors de la réception d'un nouveau prix ou d'un nouveau tick.
En fonction du type de programme MQL5, il existe différents gestionnaires d'événements, qui sont décrits ci-dessous :
| Gestionnaire d'événements | Description | Format |
|---|---|---|
| OnStart | Ce gestionnaire peut être utilisé dans des programmes de type script pour appeler une fonction lorsque l'événement de démarrage se produit. |
int OnStart(void);
void OnStart(void); |
| OnInit | Il peut être utilisé dans les EA et dans les indicateurs pour appeler une fonction lors de l'initialisation du programme. |
int OnInit(void);
void OnInit(void); |
| OnDeinit | Il peut être utilisé dans les EA et dans les indicateurs pour appeler une fonction lors de la dé-initialisation du programme. | void OnDeinit( const int reason // deinitialization reason code ); |
| OnTick | Il peut être utilisé dans les EA et dans les indicateurs pour appeler la fonction lors de la réception de nouvelles cotations. | void OnTick(void); |
| OnCalculate | Il peut être utilisé dans les indicateurs pour appeler une fonction lorsque l'événement Init est envoyé et à chaque changement de données de prix. |
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 | Il peut être utilisé dans les EA et dans les indicateurs pour appeler une fonction lorsque l'événement périodique de la minuterie se produit sur le terminal de trading. | void OnTimer(void); |
| OnTrade | Il peut être utilisé dans les EA pour appeler une fonction lorsqu'une opération de transaction est terminée sur un serveur de transaction. | void OnTrade(void); |
| OnTradeTransaction | Il peut être utilisé dans les EA pour appeler une fonction lors de l'exécution de certaines actions sur un compte de transaction. | void OnTradeTransaction() const MqlTradeTransaction& trans, // trade transaction structure const MqlTradeRequest& request, // request structure const MqlTradeResult& result // response structure ); |
| OnBookEvent | Il peut être utilisé dans les EA pour appeler une fonction lorsque la profondeur du marché est modifiée. | void OnBookEvent( const string& symbol // symbol ); |
| OnChartEvent | Il peut être utilisé dans les indicateurs pour appeler une fonction lorsque l'utilisateur travaille sur un graphique. | 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 | Il peut être utilisé dans les EA pour appeler une fonction lorsque le test d'un Expert Advisor sur des données historiques est terminé. | double OnTester(void); |
| OnTesterInit | Il peut être utilisé dans les EA pour appeler une fonction avec le début de l'optimisation dans le testeur de stratégie avant la première passe d'optimisation. |
int OnTesterInit(void);
void OnTesterInit(void); |
| OnTesterDeinit | Il peut être utilisé dans les EA pour appeler une fonction après la fin de l'optimisation d'un Expert Advisor dans le testeur de stratégie. | void OnTesterDeinit(void); |
| OnTesterPass | Il peut être utilisé dans les EA pour appeler une fonction lorsqu'une nouvelle trame de données est reçue. | void OnTesterPass(void); |
Pour en savoir plus sur la gestion des événements, consultez la référence MQL5.
Exemple de programme MQL5
Dans cette partie, nous allons appliquer ce que nous avons appris pour créer une application simple en utilisant la bonne structure MQL5. Nous avons mentionné que nous pouvons utiliser les composants de la structure MQL5 en fonction du type de programme et de la tâche nécessaire. Il n'y a pas d'obligation d'utiliser tous ces composants, comme par exemple l'utilisation du préprocesseur #include, car il peut ne pas être nécessaire d'inclure un fichier externe, d’ajouter des propriétés avec #property, ou de créer des classes ou des fonctions personnalisées dans votre programme. Quoi qu'il en soit, vous utiliserez ce qui est nécessaire pour votre programme. Vous trouverez ci-dessous quelques applications simples pour présenter tous les composants de structure nécessaires en fonction des différents types de programmes.
Type de script
Voici un exemple simple de script MQL5 capable de calculer et d'additionner deux nombres saisis par l'utilisateur en utilisant des entrées et d'imprimer le résultat dans l'onglet Expert en utilisant la fonction Print. Il est important de mentionner ici que, dans ce programme de script, nous allons ajouter une propriété avec #property permettant d'afficher les entrées du script de l'utilisateur.
//+------------------------------------------------------------------+ //| 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); } //+------------------------------------------------------------------+
Si nous voulons créer un autre EA ou un autre indicateur, nous devons utiliser des gestionnaires d'événements différents en fonction du type de programme. Par exemple, un EA peut exécuter une action lorsqu'il reçoit un nouveau tick en utilisant le gestionnaire d'événement OnTick().
Maintenant que nous avons identifié la structure du programme MQL5, nous constatons que certaines composantes varient en fonction du type de programme et de ses objectifs ou tâches. Cette compréhension nous aide à identifier la position de chaque composant dans le logiciel.
Pour appliquer ces connaissances, nous pouvons commencer par un simple programme de script, comme indiqué précédemment.
Conclusion
Vous avez maintenant compris la structure de tout programme MQL5 et vous êtes en mesure d'identifier ce dont vous avez besoin comme composants pour créer votre logiciel MQL5 en fonction de son type :
- Le préprocesseur
- Macro de substitution (#define)
- Propriétés du programme (#property)
- Inclure des fichiers (#include)
- Import de fonctions (#import)
- Compilation conditionnelle (#ifdef, #ifndef, #else, #endif)
- Les variables d'entrée et variables globales
- Les fonctions et classes
- Les gestionnaires d'événements
- OnStart
- OnInit
- OnDeinit
- OnTick
- OnCalculate
- OnTimer
- OnTrade
- OnTradeTransaction
- OnBookEvent
- OnChartEvent
- OnTester
- OnTesterInit
- OnTesterDeinit
- OnTesterPass
J'espère que cet article vous a aidé à construire votre programme MQL5. Il est essentiel de comprendre son contexte pour que le processus se déroule sans heurts et de manière efficace. Si vous souhaitez en savoir plus sur la création d'un système de trading à l'aide d'indicateurs techniques populaires, vous pouvez vous référer à mes précédents articles publiés sur ce sujet.
J'ai également écrit des articles sur la création et l'utilisation d'indicateurs personnalisés dans n'importe quel EA et sur d'autres sujets essentiels de la programmation MQL5, tels que la Programmation Orientée Objet (POO) et les fonctions. Je pense que ces articles vous seront utiles dans votre parcours d'apprentissage et de trading.
Traduit de l’anglais par MetaQuotes Ltd.
Article original : https://www.mql5.com/en/articles/13021
Avertissement: Tous les droits sur ces documents sont réservés par MetaQuotes Ltd. La copie ou la réimpression de ces documents, en tout ou en partie, est interdite.
Cet article a été rédigé par un utilisateur du site et reflète ses opinions personnelles. MetaQuotes Ltd n'est pas responsable de l'exactitude des informations présentées, ni des conséquences découlant de l'utilisation des solutions, stratégies ou recommandations décrites.
Démarrer avec MQL5 Algo Forge
Développer un robot de trading en Python (Partie 3) : Mise en œuvre d'un algorithme de trading basé sur un modèle
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation
L'article Tout ce qu'il faut savoir sur la structure du programme MQL5 a été publié :
Auteur : Mohamed Abdelmaaboud
J'aimerais qu'il y ait moins de ces réimpressions de documentation sans explication.
+