English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
preview
Tout ce qu'il faut savoir sur la structure d’un programme MQL5

Tout ce qu'il faut savoir sur la structure d’un programme MQL5

MetaTrader 5Trading |
626 3
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

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 :

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.

Avertissement : Toutes les informations données dans cet article sont fournies "en l'état", uniquement à des fins d'information et ne sont aucunement données à des fins de trading ou de conseil. Ces informations ne garantissent aucun type de résultat. Si vous utilisez le contenu de cet article sur l'un de vos comptes de trading, vous le faites à vos propres risques et vous en serez le seul responsable.


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 :

property

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 :

inputs

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 :

inputs1

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.
  • Version avec une valeur de retour : 
int  OnStart(void);
  • Version sans valeur de retour :
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.
  •  Version avec une valeur de retour :
int  OnInit(void);
  • Version sans valeur de retour :
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.
  • Calculs basés sur le tableau de données :
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
   );
  • Calculs basés sur la série temporelle actuelle :
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.
  • Version avec valeur de retour :
int  OnTesterInit(void);
  • Version sans valeur de retour :
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

Derniers commentaires | Aller à la discussion (3)
Valeriy Yastremskiy
Valeriy Yastremskiy | 20 oct. 2023 à 14:05
J'aimerais qu'il y ait moins de réimpressions de documentation sans explications. Pas un mot sur la structure)
Aleksandr Slavskii
Aleksandr Slavskii | 20 oct. 2023 à 15:31
Valeriy Yastremskiy #:
J'aimerais qu'il y ait moins de ces réimpressions de documentation sans explication.

+

Gerard William G J B M Dinh Sy
Gerard William G J B M Dinh Sy | 20 août 2025 à 09:29
Tellement à dire et tellement peu de mots sur les sujets que tout le monde considère comme futil alors que se sont les bases de départ de tout bon code... 

Les règles de nommage,
la gestion d'erreurs, 
la gestion des logs, 
et le plus important les mises en place de tout un tas de process qui vous permettront de debugger rapidement et efficacement 
Démarrer avec MQL5 Algo Forge Démarrer avec MQL5 Algo Forge
Nous présentons MQL5 Algo Forge — un portail dédié aux développeurs de trading algorithmique. Il combine la puissance de Git avec une interface intuitive pour gérer et organiser les projets au sein de l'écosystème MQL5. Vous pouvez y suivre des auteurs intéressants, former des équipes et collaborer à des projets de trading algorithmique.
Comprendre les fonctions dans MQL5 avec des applications Comprendre les fonctions dans MQL5 avec des applications
Les fonctions sont des éléments essentiels dans tout langage de programmation : elles aident les développeurs à appliquer le concept DRY, qui signifie ne vous répétez pas, et présentent bien d'autres avantages. Dans cet article, vous trouverez beaucoup plus d'informations sur les fonctions, et sur comment créer nos propres fonctions en MQL5 avec des applications simples pouvant être utilisées ou appelées dans n'importe quel système de votre choix pour l’enrichir sans compliquer les choses.
Tester différents types de Moyennes Mobiles pour voir leur pertinence Tester différents types de Moyennes Mobiles pour voir leur pertinence
Nous connaissons tous l'importance de l'indicateur des Moyennes Mobiles (Moving Average en anglais) pour de nombreux traders. Il existe d'autres types de Moyennes Mobiles qui peuvent s'avérer utiles pour le trading. Nous allons les identifier dans cet article et faire une comparaison simple entre chacun et une Moyenne Mobile Simple, la version la plus populaire, afin de voir lequel peut donner les meilleurs résultats.
Développer un robot de trading en Python (Partie 3) : Mise en œuvre d'un algorithme de trading basé sur un modèle Développer un robot de trading en Python (Partie 3) : Mise en œuvre d'un algorithme de trading basé sur un modèle
Nous poursuivons la série d'articles sur le développement d'un robot de trading en Python et en MQL5. Dans cet article, nous allons créer un algorithme de trading en Python.