English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
preview
Développer un Expert Advisor de trading à partir de zéro (partie 31) : Vers l'avenir (IV)

Développer un Expert Advisor de trading à partir de zéro (partie 31) : Vers l'avenir (IV)

MetaTrader 5Trading | 26 septembre 2024, 09:32
373 0
Daniel Jose
Daniel Jose

Introduction

Après avoir supprimé Chart Trade de l'EA dans l'article "Développement d'un EA de trading à partir de zéro (partie 29)", nous avons transformé le panneau Chart Trade en un indicateur. La façon de procéder, ainsi que la façon d'ajuster et d'entretenir les fonctions nécessaires au fonctionnement de l'indicateur, sont décrites dans la partie 30. Il s'agit d'une des approches possibles, mais il existe en réalité d'autres moyens, avec leurs avantages et leurs inconvénients. Nous les examinerons une autre fois.

Il nous reste donc encore quelque chose à retirer de l'EA. Nous allons le supprimer maintenant, et cet article sera le dernier de cette série. La chose à enlever est le système de sonorisation. Cela peut être déroutant si vous n'avez pas suivi les articles précédents.

Afin de comprendre comment se déroule l'ensemble du processus (qui comprend de nombreux éléments nécessitant une explication), nous utiliserons presque le même modèle que celui de l'article précédent. Cela rendra l'explication simple et compréhensible, même pour ceux qui ne sont pas des programmeurs professionnels. Nous allons également compliquer un peu le système, juste pour mettre un peu de piment dans l'affaire.

Cette fois-ci, la nouvelle pièce est le système de sonorisation. Il cessera de faire partie de l'EA. Mais cela apportera de nombreux avantages à l'avenir. Mais ne nous précipitons pas. L'important est de comprendre ce qui va se passer ici. L'article sera relativement court, mais intéressant.


Introduction d'un service sonore

Tous ces changements peuvent vous rendre fou. Mais croyez-moi, l'idée n'est pas de vous rendre fou, bon peut-être de vous déconcerter un peu, mais de montrer comment de petits changements peuvent parfois faire une grande différence et rendre l'utilisation de la plateforme MetaTrader 5 beaucoup plus agréable. En même temps, vous verrez comment toutes ces actions permettent de moduler les choses.

Vous pouvez ainsi choisir ce dont vous avez besoin et ce qui ne l'est pas. Si une fonction est vraiment utilisée, vous pourrez l'améliorer ultérieurement pour la rendre encore plus utile et agréable. Cela ne nécessitera pas de grands changements ou une reprogrammation de ce qui a été créé il y a un certain temps. L'idée est de TOUJOURS RÉUTILISER.

L'une de ces caractéristiques est le système de sonorisation. Il peut sembler que laisser ce système à l'intérieur de l'EA soit une bonne idée. Dans un sens, ce système n'interfère pas avec le fonctionnement de l'EA dans son ensemble. Mais si nous le retirons de l'EA et mettons en place une communication entre eux, vous verrez qu'il est possible d'utiliser les alertes sonores de manière très simple, comme s'il s'agissait d'une bibliothèque de sons. Cette solution sera très utile.

Il est inutile de placer un système d'alerte uniquement au sein d'un EA. Il peut être utile de disposer d'un système de sonorisation dans les indicateurs ou même dans les scénarios qui se déroulent à des heures précises. Cela sera très utile pour l'analyse. Ainsi, la plateforme MetaTrader 5 peut devenir un véritable monstre en termes d'analyse, où vous pouvez effectuer d'énormes calculs pour mieux analyser le marché à des moments très spécifiques, qu'il s'agisse de l'entrée ou de la fermeture d'une position. Tout cela peut se faire avec un minimum d'efforts.

On peut dire : "Mais je peux ajouter tous les sons à un fichier MQH (fichier d'en-tête), les intégrer dans des exécutables et obtenir le comportement requis. Oui, c'est possible. Mais réfléchissez au scénario suivant : Au fil du temps, ce fichier MQH s'étoffe et, à mesure qu'il grossit, certains programmes plus anciens peuvent devenir incompatibles avec ce fichier d'en-tête (MQH). Si vous devez recompiler ces anciens fichiers, vous rencontrerez des problèmes. Et si vous créez un système modulaire dans lequel il existe un protocole de communication entre les processus, vous pouvez étendre la fonctionnalité de la plateforme tout en maintenant la compatibilité avec les programmes plus anciens.

C'est la raison de ces changements : vous montrer comment vous pouvez créer et utiliser n'importe lequel des chemins possibles. Et je le montre en retirant des éléments de l'EA, tout en gardant les choses aussi proches que possible du comportement d'origine.

Dans l'article précédent, j'ai montré comment recréer Chart Trade de façon à ce qu'il se comporte de la même façon que lorsqu'il a été intégré à l'EA. Mais après l'avoir retiré de l'EA, il était nécessaire de créer un moyen pour qu'il continue à fonctionner dans le même mode. La méthode que je vous ai montrée est l'une des nombreuses possibilités, et bien qu'elle ne soit pas la meilleure, elle fonctionne. Toute solution nécessite une bonne compréhension du fonctionnement général des choses. Parfois, le fait de se limiter à un seul modèle d'idée n'aide pas à résoudre des situations spécifiques, bien au contraire. C'est précisément par manque de connaissances que beaucoup pensent qu'il n'est pas possible de faire quelque chose ou que le système est limité. Alors qu'en fait, la limitation réside dans le manque de connaissances de la personne responsable de la planification et de la mise en œuvre de la solution.

Nous l'avons constaté lors de la mise en œuvre du système d’ordres sans utiliser de structure pour stocker les données. Beaucoup pensaient que c'était quelque chose d'impossible à faire, qu'il n'y avait pas moyen de faire de telles choses. Mais j'ai montré que c'était possible. L'important est de savoir et de comprendre ce que l'on fait. La première étape consiste à connaître les limites de chaque type de solution.

Nous allons donc apprendre à rendre le système sonore aussi modulaire que possible, en gardant à l'esprit que nous étendrons ses fonctionnalités au fur et à mesure que le système se développera.

Tout d'abord, nous ne toucherons pas à la classe C_Sound, sauf dans les cas où nous aurons besoin d'étendre ses fonctionnalités. Il n'y aura donc pas de grands changements dans cette classe. En fait, à ce stade, cette classe restera inchangée, mais nous devons apporter de petits ajouts au système. Le premier d'entre eux est le fichier d'en-tête illustré ci-dessous :

#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#define def_GlobalVariableAlert "Sound Alert"
//+------------------------------------------------------------------+


Vous pourriez penser que nous allons utiliser ce fichier dans l'EA, mais non... l'EA n'utilisera pas ce fichier, du moins pas encore. Il utilisera un autre fichier que nous verrons plus tard.

Ensuite, nous pouvons créer un fichier qui sera le service sonore. Il est illustré dans le code ci-dessous :

#property service
#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#include <NanoEA-SIMD\Auxiliar\C_Sounds.mqh>
#include <NanoEA-SIMD\Interprocess\Sound.mqh>
//+------------------------------------------------------------------+
void OnStart()
{
        union u00
        {
                double value;
                struct s00
                {
                        uint    i0,
                                i1;
                }info;
        }u_local;
        C_Sounds Sound;
        
        while (!IsStopped())
        {
                Sleep(500);
                if (GlobalVariableGet(def_GlobalVariableAlert, u_local.value))
                {
                        GlobalVariableDel(def_GlobalVariableAlert);
                        if (u_local.info.i1 == 0) Sound.PlayAlert((C_Sounds::eTypeSound)u_local.info.i0);
                        else Sound.PlayAlert(u_local.info.i1);
                }
        }
}
//+------------------------------------------------------------------+


Ce service surveille les variables globales de MetaTrader 5. Il jouera le son spécifié dès que la variable dont le nom est déclaré dans le fichier d'en-tête est lancée par un script, un EA ou un indicateur, quels que soient son nom et le moment où il se produit.

Il suffit de spécifier l'index du fichier à lire. Sur la base de la structure ci-dessus, vous serez en mesure de jouer un total de 4 294 967 295 de sons différents, ce qui correspond seulement au nombre de fichiers externes. Vous pouvez avoir le même nombre de sons internes, ce qui vous permet de faire beaucoup de choses.

Pour que le système sache quel type de son jouer, il vérifie la valeur de la variable u_local.info.i1. Si la valeur est 0, le son à reproduire sera incorporé dans le fichier de service, et l'index du son sera indiqué par la variable u_local.info.i0. Cette valeur représente l'indice à l'intérieur de la classe C_Sound.

Nous pouvons maintenant compiler le service et l'exécuter. Dès que les conditions ci-dessus sont remplies, le service effectue son travail, en se rappelant que lorsque la variable globale est capturée par le service, elle est supprimée afin de pouvoir être utilisée à un autre moment.

Avant d'aller plus loin, réfléchissons un peu. Contrairement à l'indicateur Chart Trade, qui ne communique qu'avec l'EA, le système sonore peut communiquer avec n'importe quel type de programme de la plateforme MetaTrader 5. Pour jouer le son désiré, vous devez définir la valeur de la variable, qui sera toujours double.

Vous pensez peut-être que c'est facile, mais essayez et vous verrez que ce n'est pas le cas. Vous devrez également créer la variable globale avec le nom correct à chaque fois. Vous devrez donc faire beaucoup de travail chaque fois que vous voudrez jouer un son précédemment sauvegardé.

Mais il existe une solution pratique qui permet d'éviter tous ces tracas. Parce qu'elle est assez agréable, nous utiliserons cette solution à son niveau le plus basique à ce stade précoce. Pour savoir comment faire, passons au sujet suivant.


Création d'une bibliothèque pour accéder au service sonore

La raison de la création d'une bibliothèque est qu'elle nous facilitera la vie d'une manière ou d'une autre. Peu importe comment, mais cela nous facilitera la vie. Dans la rubrique précédente, j'ai mentionné que lorsqu'un programme accède au service sonore, nous n'avons pas besoin de connaître le nom de la variable globale qui donne accès au service. Aussi étrange que cela puisse paraître, la meilleure façon de transmettre des informations entre les processus est d'ajouter une couche au système. Cette couche est la bibliothèque.

Ces bibliothèques "cachent" la complexité de la modélisation des données entre les processus, de sorte que vous n'avez plus à vous préoccuper de la forme que doit prendre la modélisation. Vous ne vous occupez que des appels eux-mêmes et des résultats attendus.

La création d'une bibliothèque ne pose que 2 problèmes :

  1. Déclarer clairement les fonctions qui seront exportées.
  2. Masquer autant que possible la complexité de la modélisation interne, de sorte que l'utilisateur de la bibliothèque n'ait pas besoin de savoir ce qui se passe. L'utilisateur ne doit voir que les données qui entrent et le résultat qui sort.

Ainsi, toute procédure ou fonction au sein d'une bibliothèque est conçue pour avoir un comportement très simple du point de vue de l'utilisateur. Mais en interne, il peut y avoir un niveau extrêmement complexe d'opérations conduisant aux résultats finaux. Mais le programmeur qui utilisera la bibliothèque n'a pas besoin de savoir ce qui se passe à l'intérieur. Il est important de savoir que les résultats sont fournis correctement.

Jetons donc un coup d'œil à notre bibliothèque qui cachera la modélisation des données utilisée dans le service sonore. Chaque programme doit signaler 2 choses : la première est de savoir si le son est interne ou externe ; la seconde est l'indice du son. Cela semble compliqué ? Voyons le code de ces appels à l'intérieur de la bibliothèque :

void Sound_WAV(uint index) export { Sound(0, index); }
void Sound_Alert(uint index) export { Sound(index, 0); }


Ces deux fonctions masquent toute complexité dans la modélisation des données. Notez que nous utilisons le mot-clé export qui demande au compilateur de créer un lien symbolique vers ces fonctions. Il s'agit en fait de procédures car elles ne renvoient aucune valeur. Elles seront ainsi visibles en dehors du fichier, comme s'il s'agissait d'une DLL.

Mais si vous examinez le code, vous ne trouverez pas de fonction appelée Sound. Où se trouve-t-elle ? Elle se trouve dans la bibliothèque elle-même, mais elle ne sera pas visible à l'extérieur de celle-ci. Vous trouverez le code complet de la bibliothèque ci-dessous :

//+------------------------------------------------------------------+
#property library
#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#include <NanoEA-SIMD\Interprocess\Sound.mqh>
//+------------------------------------------------------------------+
void Sound_WAV(uint index) export { Sound(0, index); }
//+------------------------------------------------------------------+
void Sound_Alert(uint index) export { Sound(index, 0); }
//+------------------------------------------------------------------+
void Sound(uint value00, uint value01)
{
        union u00
        {
                double value;
                struct s00
                {
                        uint    i0,
                                i1;
                }info;
        }u_local;
        
        u_local.info.i0 = value00;
        u_local.info.i1 = value01;
        GlobalVariableTemp(def_GlobalVariableAlert);
        GlobalVariableSet(def_GlobalVariableAlert, u_local.value);
}
//+------------------------------------------------------------------+


Notez que la procédure Sound contient toute la complexité nécessaire pour assembler la valeur adéquate, de sorte que le service puisse exécuter la tâche demandée par un script, un indicateur ou un EA. Mais au lieu de placer ce code à l'intérieur du programme qui accède au service, nous n'utiliserons que des appels simplifiés, ce qui rend le débogage du programme plus confortable et moins fatigant.

Pour comprendre comment cela fonctionne, examinons un exemple de script :

#property copyright "Daniel Jose"
#property script_show_inputs
#import "Service_Sound.ex5"
        void Sound_WAV(uint);
        void Sound_Alert(uint);
#import
//+------------------------------------------------------------------+
input uint value00 = 1;         //Internal sound service...
input uint value01 = 10016;     //Sound in WAV file...
//+------------------------------------------------------------------+
void OnStart()
{
        Sound_WAV(value01);
        Sound_Alert(value00);
}
//+------------------------------------------------------------------+


Regardez le code ci-dessus. Il n'est pas nécessaire de savoir quel type de communication est mis en œuvre, où et quand l'événement sonore se produira - il peut se produire n'importe où, au sein de la plateforme, dans le système d'exploitation, ou même à distance, cela n'a pas d'importance. La seule chose que nous devons savoir est si le son est interne ou externe au système et son index.

Avant de poursuivre, j'aimerais que vous fassiez une expérience. Échangez les fonctions. Dans ce cas, nous exécutons Sound_WAV puis Sound_Alert. Exécutez-le et voyez le résultat. Ensuite, changez l'ordre : lancez Sound_Alert, puis Sound_WAV et voyez le résultat. Pour ceux qui ne comprennent pas, le code à l'intérieur de l'événement OnStart ressemblerait à ceci dans la première situation :

void OnStart()
{
        Sound_WAV(value01);
        Sound_Alert(value00);
}


Et à ceci dans le deuxième cas :

void OnStart()
{
        Sound_Alert(value00);
        Sound_WAV(value01);
}


Bien qu'elle puisse paraître stupide, cette expérience est nécessaire pour comprendre certaines choses. Ne l'ignorez pas, il sera intéressant de voir les résultats.

Maintenant que nous avons vu ce qu'il faut ajouter à nos programmes pour pouvoir jouer des sons, il suffit d'ajouter le code suivant :

#import "Service_Sound.ex5"
        void Sound_WAV(uint);
        void Sound_Alert(uint);
#import


Chaque fois que vous avez besoin de jouer un son, il vous suffit d'utiliser la bonne fonction avec la bonne valeur, sans vous soucier de la manière dont cela sera fait. Le système veillera lui-même à ce que tout fonctionne parfaitement. Dans notre EA, le code se présentera comme suit :

// ...

#import "Service_Sound.ex5"
        void Sound_WAV(uint);
        void Sound_Alert(uint);
#import
//+------------------------------------------------------------------+
#include <NanoEA-SIMD\Trade\Control\C_IndicatorTradeView.mqh>
#include <NanoEA-SIMD\Interprocess\Sound.mqh>

// ...

La question se pose : Que fait le code mis en évidence à cet endroit ? Ne pouvons-nous pas simplement utiliser la bibliothèque ? Oui. Mais nous pouvons utiliser une énumération pour identifier les codes numériques des sons, comme c'était le cas auparavant, et à moins que vous n'utilisiez un très petit nombre de sons ou d'alertes, il peut être très difficile de comprendre ce que chacun représente en regardant simplement le code. Pour cette raison, le fichier d'en-tête Sound.mqh a reçu un ajout qui est mis en évidence dans le code ci-dessous :

#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#define def_GlobalVariableAlert "Sound Alert"
//+------------------------------------------------------------------+
enum eTypeSound {TRADE_ALLOWED, OPERATION_BEGIN, OPERATION_END};
//+------------------------------------------------------------------+


Nous obtenons donc ce code :

int OnInit()
{
        if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
        {
                Sound_Alert(TRADE_ALLOWED);
                return INIT_FAILED;
        }

// ... The rest of the function

Il est beaucoup plus représentatif que le même code qui utilise des index au lieu d'énumérations :

int OnInit()
{
        if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
        {
                Sound_Alert(0);
                return INIT_FAILED;
        }

// ... Rest of the code


Quelles version est la plus facile à comprendre ?

Après tout ce travail, vous obtiendrez ce flux d'informations dans la plateforme :

Comme vous pouvez le constater, quel que soit le fournisseur du signal, nous aurons toujours la même destination.


Conclusion

Bien que cela puisse paraître anodin, ce qui a été montré dans cet article contribue grandement à améliorer la convivialité de votre code, de vos programmes et de vos informations. Alors que vous commencez à programmer de moins en moins et que vous devenez de plus en plus productif, votre code devient en même temps plus sûr et plus stable, car la réutilisation et les tests sont répétés dans de nombreux scénarios différents.

Nous avons vu ici un autre chemin, qui est différent de celui vu dans l'article précédent. Mais même ainsi, ce chemin peut être amélioré considérablement, ce qui nous donne une pléthore de nouvelles possibilités. Mais nous verrons cela dans une autre série, où vous apprendrez comment rendre vos programmes et projets dans MetaTrader 5 beaucoup plus modulaires, avec un niveau de sécurité, de convivialité et de stabilité bien plus élevé que n'importe laquelle des méthodes présentées ici.

La chose la plus importante est de savoir comment concevoir et utiliser différentes solutions, car dans certains cas, une solution sera meilleure qu'une autre, pour une raison ou une autre.

Tous les codes sont disponibles dans le fichier joint. Pour ceux qui ne sont pas très habitués à cette façon de programmer, en utilisant des bibliothèques, je conseille de bien étudier cette phase du développement de l'EA. Ne remettez pas à demain ce que vous pouvez faire aujourd'hui, car demain ne se présentera peut-être pas comme vous le souhaitez.

Cet article termine les étapes de développement d'un EA. Je présenterai bientôt un autre type d’articles, axés sur un autre type de situation, où le niveau de complexité est beaucoup plus élevé, mais néanmoins considérablement plus intéressant. Je vous embrasse tous et je vous dis à bientôt.


Traduit du portugais par MetaQuotes Ltd.
Article original : https://www.mql5.com/pt/articles/10678

Fichiers joints |
EA_-_j_Parte_31_f.zip (14533.52 KB)
Multi-bot dans MetaTrader : Lancement de plusieurs robots à partir d'un seul graphique Multi-bot dans MetaTrader : Lancement de plusieurs robots à partir d'un seul graphique
Dans cet article, je vais étudier un modèle simple pour créer un robot MetaTrader universel pouvant être utilisé sur plusieurs graphiques tout en étant attaché à un seul graphique, sans qu'il soit nécessaire de configurer chaque instance du robot sur chaque graphique individuel.
Développer un Expert Advisor à partir de zéro (partie 30) : CHART TRADE en tant qu'indicateur ? Développer un Expert Advisor à partir de zéro (partie 30) : CHART TRADE en tant qu'indicateur ?
Aujourd'hui, nous allons à nouveau utiliser Chart Trade. Mais cette fois-ci, il s'agira d'un indicateur sur le graphique pouvant être présent ou non sur le graphique.
Swaps (Partie 1) : Verrouillage et Positions Synthétiques Swaps (Partie 1) : Verrouillage et Positions Synthétiques
Dans cet article, j'essaierai d'élargir le concept classique des méthodes de trading par swap. J'expliquerai pourquoi je suis arrivé à la conclusion que ce concept mérite une attention particulière et qu'il est absolument recommandé de l'étudier.
Développer un Expert Advisor de trading à partir de zéro (partie 29) : La plateforme parlante Développer un Expert Advisor de trading à partir de zéro (partie 29) : La plateforme parlante
Dans cet article, nous allons apprendre à faire parler la plateforme MetaTrader 5. Et si nous rendions l'EA plus amusant ? Le trading sur les marchés financiers est souvent ennuyeux et monotone, mais nous pouvons rendre ce travail moins fatigant. Veuillez noter que ce projet peut être dangereux pour les personnes qui ont des problèmes de dépendance. Mais d'une manière générale, cela rend les choses moins ennuyeuses.