English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Simulink : un guide pour les développeurs d'Expert Advisors

Simulink : un guide pour les développeurs d'Expert Advisors

MetaTrader 5Systèmes de trading | 17 novembre 2021, 16:21
374 0
Denis Kirichenko
Denis Kirichenko

Introduction

Il existe plusieurs articles qui décrivent les nombreuses possibilités de Matlab. Pour être plus précis, la façon dont ce logiciel est capable d’étendre les outils du programmeur, qu’il utilise pour élaborer un Expert Advisor. Dans cet article, je tenterai d’illustrer le travail d’un package matlab aussi puissant que le Simulink.

Je voudrais offrir un moyen alternatif d’élaborer un système de trading automatisé pour les traders. J’ai été inspiré à me tourner vers ce type de méthode en raison de la complexité du problème auquel le trader est confronté - la création, la vérification et le test du système de trading automatisé. Je ne suis pas un programmeur professionnel. Et donc, le principe de « passer du simple au complexe » est d’une importance primordiale pour moi dans le développement d’un système de trading automatisé. Qu’est-ce qui est précisément simple pour moi? Tout d’abord, il s’agit de la visualisation du processus de création du système et de la logique de son fonctionnement. En outre, il s’agit d’un minimum de code manuscrit. Ces attentes sont conformes aux capacités du package Simulink®, un produit MATLAB bien connu, qui est un leader mondial parmi les instruments de visualisation de calculs mathématiques.

Dans cet article, je tenterai de créer et de tester le système de trading automatisé, basé sur un package Matlab, puis écrire un Expert Advisor pour MetaTrader 5. De plus, toutes les données historiques pour le test inversé seront utilisées à partir de MetaTrader 5.

Pour éviter toute confusion terminologique, j’appellerai le système de trading, qui fonctionne dans Simulinik, avec un mot volumineux MTS, et celui qui fonctionne dans MQL5, simplement un Expert Advisor.


1. Les principes de base de Simulink et Stateflow

Avant de procéder à des actions spécifiques, il est nécessaire de présenter une certaine forme de minimum théorique.

Avec l’aide du package Simulink®, qui fait partie de MATLAB, l’utilisateur peut modéliser, simuler et analyser des systèmes dynamiques. De plus, il est possible de soulever la question de la nature du système, de le simuler, puis d’observer ce qui se passe.

Avec Simulink, l’utilisateur peut créer un modèle à partir de zéro ou modifier un modèle déjà existant. Le package prend en charge l’ élaboration de systèmes linéaires et non linéaires, qui sont créés sur la base d’un comportement discret, continu et hybride.

Les principales propriétés du package sont présentées sur le site de titlehttp://www.mathworks.com/products/simulink/description1.htmltitle du développeur :

  • Bibliothèques étendues et extensibles de blocs prédéfinis;
  • Éditeur graphique interactif pour l’assemblage et la gestion de schémas fonctionnels intuitifs;
  • Capacité à gérer des conceptions complexes en segmentant les modèles en hiérarchies de composants de conception;
  • Explorateur de modèles pour naviguer, créer, configurer et rechercher tous les signaux, paramètres, propriétés et code généré associés à votre modèle ;
  • Interfaces de programmation d’applications (API) qui vous permettent de vous connecter à d’autres programmes de simulation et d’incorporer du code manuscrit ;
  • Embedded MATLAB™ Les blocs fonctionnels pour intégrer les algorithmes MATLAB dans Simulink et les implémentations de systèmes embarqués
  • Modes de simulation (Normal, Accélérateur et Accélérateur Rapide) pour exécuter des simulations de manière interprétative ou à des vitesses de code C compilées à l’aide de solveurs à pas fixes ou variables;
  • Débogueur graphique et profileur pour examiner les résultats de la simulation, puis diagnostiquer les performances et le comportement inattendu dans votre conception ;
  • Accès complet à MATLAB pour analyser et visualiser les résultats, personnaliser l’environnement de modélisation et définir les données de signal, de paramètre et de test ;
  • Outils d’analyse et de diagnostic des modèles pour assurer la cohérence des modèles et identifier les erreurs de modélisation.

Commençons donc l’examen immédiat de l’environnement Simulink. Il est initialisé à partir d’une fenêtre Matlab déjà ouverte de deux des manières suivantes :

  1. en utilisant la commande Simulink dans la fenêtre de commande ;
  2. à l’aide de l’icône Simulink dans la barre d’outils.

Figure 1. Initialisation deSimulink

Figure 1. Initialisation de Simulink

Lorsque la commande est exécutée, la fenêtre de navigation des bibliothèques (Simulink Library Browser) s’affiche. 

Figure 2. Navigateurde bibliothèquede bibliothèque

Figure 2. Navigateur de bibliothèque


La fenêtre du navigateur contient une arbre des composants des bibliothèques Simulink. Pour afficher une section particulière de la bibliothèque, il vous suffit de la sélectionner avec la souris, après quoi un ensemble de composants d’icône, de la section active de la bibliothèque, apparaîtra dans la section droite de la fenêtre Simulink Library Browser. La Fig. 2 affiche la section principale de la bibliothèque Simulink.

À l’aide du menu du navigateur ou des boutons de sa barre d’outils, vous pouvez ouvrir une fenêtre pour créer un nouveau modèle ou pour télécharger un modèle existant. Je dois noter que tout le travail avec Simulink se produit avec un système MATLAB ouvert, dans lequel il est possible de surveiller l’exécution des opérations, du moment que leur sortie est assurée par le programme de modélisation.


Figure 3.Fenêtre vide Simulinkvide Simulink

Figure 3. Fenêtre vide Simpulink


Tout d’abord, modifions quelques paramètres de notre modèle. Ouvrons Simulation --> Paramètres de Configuration. Cette fenêtre comporte un certain nombre d’onglets avec de nombreux paramètres. Nous nous intéressons à l’onglet Solveur par défaut, où vous pouvez définir les paramètres du solveur du système de modélisation Simulink.

Dans l’heure de simulation, l’heure de modélisation est définie par l’heure de début - Heure de début (généralement 0) et l’heure de fin - Heure d’arrêt.

Pour notre tâche, attribuons à l’heure de début une valeur de 1. Nous laisserons l’heure d’arrêt telle qu’elle est.

Dans les options du solveur, j’ai également modifié le type en étape fixe, le solveur lui-même en discret et l’étape (taille de l’étape fixe) en 1.

Figure 4. Fenêtre de Paramètres de Configuration


L’environnement Simulink est réalisé avec succès par le sous-système Stateflow, qui est un package de modélisation piloté par les événements, basé sur la théorie des automates à états finis. Il nous permet de représenter le travail du système, basé sur une chaîne de règles, qui indiquent les événements et les actions en réaction à ces événements.

L’interface utilisateur graphique du package Stateflow comporte les composants suivants :

  • Un Éditeur Graphique de SF-charts;
  • Explorateur Stateflow ;
  • Stateflow Finder pour rechercher les objets nécessaires dans les graphiques SF;
  • Un débogueur de modèles SF;
  • Real Time Workshop, un générateur de code en temps réel.

Le diagramme de blocs le plus couramment utilisé (graphique), qui se trouve dans la section Stateflow. Examinons-le.

Déplaçons le bloc depuis la bibliothèque et double-cliquons dessus pour ouvrir le diagramme. Une fenêtre vide d’un éditeur de graphique SF apparaîtra. Il peut être utilisé pour créer des graphiques SF et leur débogage, afin d’obtenir les fonctions nécessaires.

La barre d’outils est située verticalement sur le côté gauche. Il y a 9 boutons :

  1. État
  2. Jonction de l’historique;
  3. Transition par défaut;
  4. Jonction conjonctive;
  5. Table de vérité;
  6. Fonction
  7. Fonction MATLAB intégrée;
  8. Boîte;
  9. Appel de fonction Simulink.

Malheureusement, il est impossible d’examiner chaque élément en détail dans le contexte de cet article. Par conséquent, je me limiterai à une brève description de ces éléments, dont nous aurons besoin pour notre modèle. Vous trouverez des informations plus détaillées dans la section Aide de Matlab ou sur le site Web du développeur.

Figure 5. Vue du graphique SF dansl’éditeurdans l’éditeur

Figure 5. La vue du graphique SF dans l’éditeur

L’objet principal des graphiques SF est l’État. Il est présenté par un rectangle aux coins arrondis.

Il peut être exclusif ou parallèle. Chaque État peut être le parent et avoir des héritiers. Les états peuvent être actifs ou non actifs, les états peuvent effectuer certaines procédures.

La transition est représentée sous la forme d’une ligne courbe fléchée, elle relie les états et d’autres objets. Une transition peut être effectuée en cliquant avec le bouton gauche de votre souris sur l’objet source et en dirigeant le curseur vers l’objet cible. La transition peut avoir ses propres conditions, qui sont enregistrées entre parenthèses. La procédure de transition est indiquée entre parenthèses, elle sera exécutée si la condition est remplie. La procédure, exécutée lors de la confirmation de l’objet cible, est indiquée par une barre oblique.

Le nœud alternatif (jonction conjonctive) a la forme d’un cercle, et permet la transition pour se diriger vers les différents chemins, dont chacun est défini par une condition spécifique. Dans ce cas, la transition, qui correspond à la condition spécifiée, est sélectionnée.

Fonction représentée sous la forme d’un organigramme avec les instructions du langage procédural Stateflow. Un organigramme reflète la structure logique de l’utilisation des transitions et des nœuds alternatifs.

Un événement est un autre objet important de Stateflow, appartenant au groupe d’objets non graphiques. Cet objet peut lancer les procédures du graphique SF.

La procédure (action) est également un objet non graphique. Il peut appeler la fonction, attribuer un événement spécifique, une transition, etc.

Les données du modèle SF sont représentées par des valeurs numériques. Les données ne sont pas représentées sous forme d’objets graphiques. Ils peuvent être créés à n’importe quel niveau de la hiérarchie du modèle et présentent des propriétés.

2. Description de la stratégie de trading

Maintenant, brièvement sur le trading. Pour nos besoins de formation, l’Expert Advisor sera très simple, pour ne pas dire primitif.

Le système de trading automatisé ouvrira des positions sur la base du signal, essentiellement, après le croisement des mouvements exponentiels, avec une période de 21 et 55 (nombres de Fibonacci), moyennant sur les prix de clôture. Donc, si l’EMA 21 croise l’EMA 55 à partir du bas, une position longue est ouverte, sinon - une position courte.

Pour le filtrage du bruit, la position sera ouverte à la barre K-th par le prix de l’ouverture de la barre après l’apparition de la croix 21/55. Nous effectuerons un trade sur l’EURUSD H1. Un seul position sera ouverte Il ne sera fermé qu’après avoir atteint le niveau Take Profit ou Stop Loss

Je voudrais mentionner que lors du l’élaboration du système de trading automatisé et du test inversé de l’historique, certaines simplifications du tableau du trade globale sont admises.

Par exemple, le système ne vérifiera pas l’exécution d’un signal par le courtier. En outre, nous ajouterons les restrictions de trading au cœur du système dans MQL5.


3. La modélisation d’une Stratégie de Trading dans Simulink

Pour commencer, nous devons télécharger les données de prix historiques dans l’environnement Matlab. Nous le ferons en utilisant un script MetaTrader 5, qui les enregistrera (testClose.mq5).

Dans Matlab, ces données (Ouvert, Haut, Bas, Clos Spread) seront également chargées à l’aide d’un simple m-script (priceTxt.m).

En utilisant le movavg (fonction Matlab standard), nous allons créer des tableaux de Moyennes Mobiles Exponentielles:

[ema21, ema55] = movavg(clos, 21, 55, 'e');

Ainsi qu’un tableau auxiliaire des index de barres :

num=1:longueur(clos);

Créons les variables suivantes :

K=3; sl=0.0065; tp=0.0295;

Commençons le processus de modélisation.

Créez une fenêtre vide Simulink et appelez-la mts lors de son enregistrement. Toutes les actions suivantes ont été dupliquées dans un format vidéo. Si quelque chose n’est pas tout à fait clair, ou même pas clair du tout, vous pouvez regarder mes actions en visionnant la vidéo.

Lors de l’enregistrement du modèle, le système peut imprimer l’erreur suivante :

??? Le fichier « C:\\Simulink\\mts.mdl » contient des caractères incompatibles avec le codage de caractères actuel, Windows-1251. Pour éviter cette erreur, effectuez l’une des opérations suivantes :
1) Utilisez la fonction slCharacterEncoding pour remplacer le codage de caractères actuel par l’un des : Shift_JIS, Windows-1252, ISO-8859-1.
2) Supprimez les caractères qui ne sont pas pris en charge. Le premier caractère qui n’est pas pris en charge se trouve à la ligne 23, décalage d’octet 15.

Pour éliminer cela, il vous suffit de fermer toutes les fenêtres des modèles et de modifier l’encodage à l’aide des commandes suivantes :

bdclose all
set_param(0, 'CharacterEncoding', 'Windows-1252');

Précisons la source d’information de notre modèle.

Le rôle de cette source d’information sera les données historiques de MetaTrader 5, qui contiennent les prix d’ouverture, maximum, minimum et de clôture. De plus, nous prendrons en compte le Spread, même s’il est récemment devenu relativement flottant. Enfin, nous enregistrons l’heure d’ouverture du bar. À des fins de modélisation, certains tableaux de données initiales seront interprétés comme un signal, c’est-à-dire comme un vecteur de valeurs d’une fonction temporelle à des points discrets dans le temps.

Créons un sous-système « FromWorkspace » pour récupérer les données de l’espace de travail Matlab. Sélectionnez la section Ports et sous-systèmes dans le navigateur des bibliothèques Simulink. Faites glisser le bloc « Sous-système » vers la fenêtre du modèle Simulink à l’aide de la souris. Renommez-le en « FromWorkspace », en cliquant sur le sous-système. Ensuite, connectez-vous en double-cliquant sur le bouton gauche de la souris sur le bloc, afin de créer les variables d’entrée et de sortie, ainsi que les constantes du système.

Pour créer les sources de signal dans l’Explorateur de bibliothèques, choisissez l’ensemble de blocs de traitement du signal et les sources (Sources de Traitement du Signal). À l’aide de votre souris, faites glisser le bloc « Signal depuis l’espace de travail » dans la fenêtre du sous-système du modèle FromWorkspace. Puisque le modèle aura 4 signaux d’entrée, nous dupliquons simplement le bloc et en créons 3 autres copies. Indiquons tout de suite quelles variables seront traitées par bloc. Pour ce faire, cliquez deux fois sur le bloc et entrez le nom de la variable dans les propriétés. Ces variables seront : open, ema21, ema55, num. Nous nommerons les blocs comme suit: signal ouvert, signal ema21, signal ema55, signal num.

Maintenant, à partir de la section Simulink « Blocs couramment utilisés », nous allons ajouter un bloc pour créer un canal (Bus Creator). Ouvrez le bloc et modifiez le nombre d’entrées à 4. Connectez le signal ouvert, le signal ema21, le signal ema55, les blocs de signal num avec les entrées du bloc Bus Creator.

De plus, nous aurons 5 constantes d’entrée supplémentaires. Le bloc « Constant » est ajouté à partir de la section « Blocs couramment utilisés ». Comme valeur (valeur constante), nous indiquons les noms des variables: spread, élevé, bas, tp, sl:

  • spread - il s’agit d’un tableau de valeurs de spread;
  • élevé - il s’agit d’un tableau de valeurs de prix maximales;
  • faible - c’est un tableau de valeurs de prix minimales;
  • tp - La valeur de Take Profit en termes absolus;
  • sl - La valeur Stop Loss en termes absolus.

Nous appellerons les blocs comme suit: spread array, high array, low array, Take Profit, Stop Loss.

Sélectionnez le bloc de port de sortie (Out1) dans la section Simulink « Ports et sous-systèmes » et déplacez-le vers la fenêtre du sous-système. Faites 5 copies du port de sortie. Le premier, nous allons nous connecter avec le bloc Bus Creator, et d’autres - alternativement, avec les blocs spread, high, low, Take Profit et Stop Loss.

Nous allons renommer le premier port au prix, et les autres - par le nom de la variable de sortie.

Pour créer un signal de trading, insérons le bloc d’addition (Ajouter) de la section Simulink « Opérations mathématiques ». Nous l’appellerons emas différentiel. Dans le bloc, nous allons changer la liste des signes, c + + à + -. À l’aide de la combinaison de touches Ctrl + K, tournez le bloc de 90 ° dans le sens des aiguilles d’une montre. Connectez le bloc de signal ema21 à l’entrée "+". et le signal ema55 avec le ."-". 

Insérez ensuite le bloc Delay, de la section Signal Processing Blockset, de Signal Operations Nous l’appellerons K Delay. Dans le champ Délai (échantillons) de ce bloc, nous entrons le nom de la variable K. Connectez-le avec le bloc précédent.

Les blocs différentiels emas et K Delay formatent l’avant (différence de niveau) du signal de commande pour les calculs uniquement pour l’étape de modélisation, où il y a eu changement. Le sous-système, que nous créerons un peu plus tard, sera activé si au moins un élément affiche un changement dans son niveau de signal.

Ensuite, à partir de la section « Blocs couramment utilisés » de Simulink, nous ajouterons un multiplexeur avec bloc et (Mux). De même, faites pivoter le bloc de 90 ° dans le sens des aiguilles d’une montre. Nous allons diviser la ligne de signal du bloc de retard en deux et la connecter aux multiplexes.

Dans la section Stateflow, insérez un bloc Graphique. Entrez dans le graphique. Ajoutez 2 événements entrants (Buy and Sell) et 2 événements sortants (OpenBuy et OpenSell). La valeur de déclenchement (Trigger) pour l’événement Buy, nous la définirons sur Falling (activation du sous-système par un front négatif), et pour les événements Sell, nous définirons sur Rising (activation du sous-système par un front positif). La valeur de déclenchement (Trigger) pour les événements OpenBuy et OpenSell, nous la définirons sur la position de l’appel de fonction (Calling), (l’activation du sous-système sera déterminée par la logique du travail de la fonction S donnée).

Nous allons créer une transition par défaut avec 3 nœuds alternatifs. Le premier nœud, nous allons nous connecter par une transition au deuxième nœud, en leur définissant les conditions et la procédure pour qu’ils achètent {OpenBuy;}, et pour le troisième, en définissant la procédure de Vente {OpenSell;}. Connectez l’entrée graphique avec le multiplex et les deux sorties - avec un autre multiplex, qui peut être copié à partir du premier. Le dernier bloc sera connecté au port de sortie, que nous copierons à partir d’un port analogue, et l’appellerons Acheter / Vendre.

Et j’ai presque oublié! Pour que le modèle fonctionne correctement, nous devons créer un objet de canal virtuel, qui sera situé dans l’espace de travail Matlab. Pour ce faire, nous entrons dans l’éditeur de bus via le menu Outils. Dans l’éditeur, sélectionnez l’élément Ajouter un Bus. Appelez-le InputBus.

Insérez les éléments en fonction des noms des variables d’entrée : open, ema21, ema55 et num. Ouvrez le Créateur de Bus et vérifiez la case prés des propriétés Specify via l’objet bus (Définir les propriétés via l’objet bus). En d’autres termes, nous avons connecté notre bloc à l’objet de canal virtuel que nous avons créé. Le canal virtuel signifie que les signaux sont seulement combinés à titre graphique , sans affecter la distribution de la mémoire.

Enregistrez les modifications dans la fenêtre du sous-système. Ceci conclut notre travail avec le sous-système FromWorkspace.


Vient maintenant le temps de créer la « Black Box ». Ce sera un bloc, basé sur les signaux entrants, il traitera les informations et prendra des décisions de trading. Bien sûr, c’est nous qui devons la créer, plutôt qu’un programme informatique. Après tout, nous sommes les seuls à pouvoir décider des conditions dans lesquelles le système devrait effectuer un trade En outre, le bloc devra afficher les informations sur les deals terminés sous forme de signaux.

Le bloc nécessaire s’appelle le Graphique et se trouve dans la section Stateflow. Nous en avons déjà pris connaissance, n’est-ce pas? En utilisant le "drag and drop" , nous le déplaçons vers notre fenêtre de modèle.

Figure 6. Les blocs du sous-systèmed’entrée et le graphique StateFlowd’entrée et le graphique StateFlow

Figure 6. Les blocs du sous-système d’entrée et le graphique StateFlow


Ouvrez le graphique et entrez-y nos données. Tout d’abord, créons un objet canal, comme nous l’avons fait dans le sous-système FromWorkspace. Mais contrairement au précédent, qui nous a fourni les signaux de l’espace de travail, celui-ci renverra le résultat obtenu. Et donc, nous appellerons l’objet OutputBus. Ses éléments deviendront : barOpen, OpenPrice, TakeProfit, StopLoss, ClosePrice, barClose, Comment, PositionDir, posN, AccountBalance.

Maintenant, nous entamerons la construction Dans la fenêtre du graphique, nous afficherons la transition par défaut (# 1).

Pour les conditions et procédures, nous indiquerons:

[Input.num>=56 && Input.num>Output.barFermé] {Output.barOpen=Input.num;i = Input.num-1;Output.posN++;}

Cette condition indique que les données seront traitées si le nombre de barres d’entrée sera d’au moins 56, ainsi que si la barre d’entrée sera supérieure à la barre de fermeture de la position précédente. Ensuite, la barre d’ouverture (Output.barOpen) se voit attribuer le numéro de la barre entrante, par une variable d’index de i - l’index (à partir de 0), et le nombre de positions ouvertes augmente de 1.

La 2ème transition n’est exécutée que si la position ouverte ne sera pas la première. Sinon, la troisième transition est exécutée, ce qui attribuera à la variable de solde du compte (Output.AccountBalance) la valeur 100000.

La 4ème transition est exécutée si le graphique a été initié par l’événement OpenBuy. Dans ce cas, la position sera orientée vers l’achat (Output.PositionDir = 1), le prix d’ouverture deviendra égal au prix de la barre d’ouverture, en tenant compte du spread (Output.OpenPrice = Input.open + spread [i] * 1e-5). Les valeurs des signaux de sortie StopLoss et TakeProfit seront également indiquées.

Si un événement OpenSell se produit, le flux suivra la 5ème transition et définira ses valeurs pour les signaux de sortie.

La 6ème transition est réalisée si la position est longue, sinon le flux suit la 7ème transition.

La 8ème transition vérifie si le prix maximum de la barre a atteint ou non le niveau Take Profit, ou si le prix minimum de la barre a atteint le niveau de Stop Loss. Sinon, la valeur de la variable d’indice i est augmentée d’un (9ème transition).

La 10ème transition vérifie les conditions survenant au Stop Loss : le prix minimum de la barre a franchi le niveau Stop Loss. S’il est confirmé, le flux suivra jusqu’à la 11ème transition, puis jusqu’à la 12ème, où les valeurs des différences de prix des positions de clôture et d’ouverture, le solde du compte courant et l’indice de la barre de clôture sont définis.

Si la 10ème transition n’est pas confirmée, la position sera fermée au Take Profit (13ème transition). Et puis, à partir du 14ème, le flux suivra jusqu’à la 12ème transition.

Les procédures et les conditions des transitions pour une position courte sont inversées

Enfin, nous avons créé de nouvelles variables dans le graphique. Afin de les intégrer automatiquement dans notre modèle, nous devons exécuter le modèle directement dans la fenêtre du graphique, en cliquant sur le bouton "Start Simulation" Il ressemble au bouton"Play" sur les lecteurs de musique. À ce stade, l’Assistant Symbole Stateflow (objets maîtres SF) se lancera et suggèrera d’enregistrer les objets créés. Appuyez sur le bouton SelectAll, puis cliquez sur le bouton Create. Des objets ont été créés. Ouvrons maintenant le Navigateur de Modèles. Sur la gauche, cliquez sur notre Graphique dans la Hiérarchie des Modèles. Trions les objets par type de données (DataType).

Ajoutez plus de données à l’aide des commandes de menu "Add" et "Data" Nous appellerons la première variable Entrée. Remplacez la valeur des étendues par Entrée et type par « Bus :<bus object name> . Et puis entrez le nom, du canal créé précédemment, InputBus, directement dans ce champ. Ainsi, notre variable Entrée aura le type d’InputBus. Définissons la valeur du port sur un.

Effectuez la même opération avec la variable Sortie Lui seul doit avoir l’Étendue de Sortie et le type de Bus de Sortie.

Modifions l’étendue des variables high, low, sl, tp et spread à la valeur "Input". Respectivement, nous définirons les numéros de port dans l’ordre suivant: 3, 4, 6, 5, 2.

Modifions également la portée de la variable Lots en Constante. Dans l’onglet « Attributs de valeur », saisissons 1, événements OpenBuy et OpenSell - pour Entrée dans le champ « Initial » (à droite).  Dans les événements, modifiez la valeur de déclenchement de l’appel de fonction.

Créez une variable interne len, avec une étendue Constante. Dans l’onglet « Attributs de valeur », dans le champ « Valeur initiale », nous allons entrer une longueur de fonction m (clôturer). Ainsi, il sera égal à la longueur du tableau proche, qui se trouve dans l’espace de travail Matlab.

Pour les variables hautes et basses, nous entrerons une valeur de [len 1] dans le champ Taille. Ainsi, dans la mémoire, nous avons réservé les tailles de tableau de haut et bas comme la valeur de [len 1].

Aussi, indiquons pour la variable K dans l’onglet « Attributs de Valeur », dans le champ « Valeur initiale » (à droite) la variable réelle de K, tirée de l’espace de travail.

En conséquence, nous avons un sous-système Chart, avec 7 ports d’entrée et un port de sortie. Positionnons le bloc de manière à ce que le port des événements d’entrée () soit en bas. Nous allons renommer le bloc « Gestion de la position ». Dans le graphique lui-même, nous afficherons également le nom du bloc. Combinez les blocs du sous-système FromWorkspace et la « Gestion de la position » via les ports appropriés. Et changez la couleur des blocs.

Il convient de noter que le sous-système « Gestion de la position » ne fonctionnera que s’il est « réveillé » par les événements OpenBuy ou OpenSell entrants. De cette façon, nous optimisons le fonctionnement du sous-système pour éviter les calculs inutiles.

Figure 7. Sous-systèmes de gestion de l’espace de travail et de la position


Nous devons maintenant créer un sous-système pour imprimer les résultats du traitement dans l’espace de travail Matlab et le combiner avec le sous-système « Gestion de position ». Ce sera la tâche la plus facile.

Créons un sous-système « ToWorkspace » pour obtenir les résultats dans l’espace de travail. Répétez les étapes que nous avons franchies lorsque nous avons créé le sous-système « FromWorkspace ». Dans le navigateur de la bibliothèque, sélectionnez la section Ports et sous-systèmes Simulink. À l’aide de la souris, faites glisser le bloc « Sous-système » dans la fenêtre du modèle Simulink. Renommez-le en « ToWorkspace » en cliquant sur le « Sous-système ». Combinez le bloc avec le sous-système « Gestion de position ».

Pour créer les variables, connectez-vous en double-cliquant sur le bloc avec le bouton gauche de la souris,

Étant donné que le sous-système recevra des données de l’objet OutputBus, qui est un bus non virtuel, nous devons donc sélectionner les signaux depuis ce canal. Pour ce faire, nous sélectionnons la section Simulink « Blocs couramment utilisés » dans le navigateur de la bibliothèque et ajoutons un "Bus Selector". Le bloc aura 1 signal d’entrée et 2 signaux de sortie, alors que nous devons avoir 10 de ces signaux.

Connectons le bloc au port d’entrée. Appuyez sur le bouton "Start simulation" (il s’agit de notre bouton « Play »). Le compilateur entamera la construction du modèle. Il ne sera pas construit avec succès, mais il créera des signaux d’entrée pour le bloc de sélection de bus. Si nous entrons dans le bloc, nous constaterons l’apparition des les signaux nécessaires sur le côté gauche de la fenêtre, qui sont transmis via OutputBus. Ils doivent tous être sélectionnés, à l’aide du bouton « Select», et les déplacer vers le côté droit - « Selected signals ».

Figure 8. paramètres du Bus Selector block

Figure 8. Paramètres du Bus Selector Block


Référons-nous à nouveau à la section « Blocs couramment utilisés » du navigateur des bibliothèques Simulink et ajoutons le bloc multiplex Mux. Il indique le nombre d’entrées, qui est égal à 10.

Connectez-vous ensuite à la section « Sinks » du navigateur de la bibliothèque Simulink et déplacez le bloc ToWorkspace vers la fenêtre du sous-système. Nous y indiquerons le nouveau nom de la variable « AccountBalance » et modifierons le format de sortie (Format de sauvegarde) de « Structure » à « Array ». Combinez le bloc avec le multiplex. Supprimez le port de sortie, car il ne sera plus nécessaire. Personnalisez la couleur des blocs. Sauvegardez la fenêtre. Le sous-système est prêt.

Avant de construire le modèle, nous devons s’assurer de la présence des variables dans l’espace de travail. Les variables suivantes doivent être présentes : InputBus, K, OutputBus, close, ema21, ema55, high, low, num, open, sl, spread, tp.

Définissons la valeur Stop Time comme paramètre pour définir num (end). Cela signifie que le vecteur traité aura la longueur, qui a été définie par le dernier élément du tableau num.

Avant de commencer la construction d’un modèle, nous devons choisir un compilateur, à l’aide de la commande suivante:

mex-setup

Veuillez choisir votre compilateur pour la création d’une interface externe Fichiers (MEX) :
Souhaitez-vous que mex localise les compilateurs installés [y] / n ? y

Sélectionnez un compilateur :

[1] Lcc-win32 C 2.4.1 pouces C:\PROGRA~2\MATLAB\R2010a\sys\lcc
[2] Microsoft Visual C++ 2008 SP1 in C:\Program Files (x86)\Microsoft Visual Studio 9.0
Aucun

Compilateur: 2

Comme vous pouvez le voir, j’ai sélectionné le compilateur Microsoft Visual C ++ 2008 SP1.

Commençons à construire. Appuyez sur le bouton « Démarrer la simulation ». Une erreur s’affiche : Erreur d’interface Stateflow : Incompatibilité de largeur de port. L’entrée « spread » (#139) prévoit à un scalaire. Le signal est le vecteur unidimensionnel avec 59739 éléments.

La variable « spread » ne doit pas avoir le type double, mais plutôt hériter de son type du signal de Simulink.

Dans l’Explorateur de modèles, pour cette variable, nous indiquons « Hériter : Identique à Simulink », et dans le champ Taille, et indiquez « -1 ». Enregistrer les changements ?

Mettons en marche le modèle à nouveau. Maintenant, le compilateur fonctionne. Il affichera quelques avertissements mineurs. Et en moins de 40 secondes, le modèle traitera les données de près de 60 000 barres. Le trade est effectué de '2001 .01.01 00:00 'à '2010 .08.16 11:00'. Le nombre total de positions ouvertes est de 461. Vous pouvez suivre le fonctionnement du modèle dans l’élément suivant.



4. Implémentation de la Stratégie dans MQL5

Ainsi, notre système de trading automatisé est compilé dans Simulink. Maintenant, nous devons transférer cette idée de trading dans l’environnement MQL5. Nous avons dû traiter des blocs et des objets Simulink, à travers lesquels nous avons exprimé la logique de notre Expert Advisor de trading. La tâche actuelle consiste à transférer le système de trading logique dans le MQL5 Expert Advisor.

Cependant, il convient de noter que certains blocs ne doivent pas nécessairement être définis d’une certaine façon dans le code MQL5, car leurs fonctions pourraient être masquées. Je tenterai de commenter avec un maximum de détails sur quelle ligne se rapporte à quel bloc, dans le code réel. Parfois, cette relation peut être indirecte. Et parfois, il peut refléter une connexion d’interface de blocs ou d’objets.

Avant de commencer cette section, permettez-moi d’attirer votre attention sur un article « Guide étape par étape pour la rédaction d’Expert Advisors dans MQL5 pour les débutants ». Cet article fournit une description facile à saisir d’idées principales et règles de base de rédaction d’un Expert Advisor dans MQL5. Mais je m’y attarderai maintenant. Je vais utiliser quelques lignes de code MQL5 à partir de là.

4.1 Sous-système « FromWorkspace »

Par exemple, nous avons un bloc « signal ouvert » dans le sous-système « FromWorkspace ». Dans Simulink, il est nécessaire pour obtenir le prix de la barre d’ouverture lors du test inversé, et pour ouvrir une position à ce prix, au cas où un signal de trading serait reçu. Ce bloc n’est évidemment pas présent dans le code MQL5, car l’Expert Advisor demande les informations de prix immédiatement après avoir reçu le signal de trading.

Dans l’Expert Advisor, nous devrons traiter les données reçues des moyennes mobiles. Par conséquent, nous allons créer pour eux des tableaux dynamiques et des variables auxiliaires correspondantes, telles que des poignées.

int ma1Handle;  // Moving Average 1 indicator handle: block "ema21 signal"
int ma2Handle;  // indicator handle Moving Average 2: block "ema55 signal"

ma1Handle=iMA(_Symbol,_Period,MA1_Period,0,MODE_EMA,PRICE_CLOSE); // get handle of Moving Average 1 indicator 
ma2Handle=iMA(_Symbol,_Period,MA2_Period,0,MODE_EMA,PRICE_CLOSE); // get handle of Moving Average 2 indicator

double ma1Val[]; // dynamic array for storing the values of Moving Average 1 for every bar: block "ema21 signal"
double ma2Val[]; // dynamic array for storing the values of Moving Average 2 for every bar: block "ema55 signal"

ArraySetAsSeries(ma1Val,true);// array of indicator values MA 1: block "ema21 signal"
ArraySetAsSeries(ma2Val,true);// array of indicator values MA 2: block "ema55 signal"

Toutes les autres lignes, qui affectent quelque peu les ema21 et ema55 en mouvement, peuvent être considérées comme auxiliaires.

« Take Profit » et « Stop Loss » sont définis comme des variables d’entrée :

input int TakeProfit=135;   // Take Profit: Take Profit in the FromWorkspace subsystem
input int StopLoss=60;      // Stop Loss:  Stop Loss in the FromWorkspace subsystem
Compte tenu du fait qu’il y a 5 chiffres significatifs pour EURUSD, la valeur de TakeProfit et StopLoss devra être mise à jour de la manière suivante:
int sl,tp;
sl = StopLoss;
tp = TakeProfit;
if(_Digits==5)
 {
  sl = sl*10;
  tp = tp*10;
 }

Les tableaux « spread », « high » et «low » sont utilisés pour servir les valeurs, car ils sont chargés de fournir des données historiques, sous la forme d’une matrice des données de prix pertinentes, afin d’identifier les conditions de trade.

Ils ne sont pas explicitement représentés dans le code. Cependant, on peut soutenir que le tableau des « spreads », par exemple, est nécessaire pour former un flux de prix «ask». Et les deux autres sont nécessaires pour déterminer les conditions de clôture d’une position, qui ne sont pas indiqués dans le code, car elles sont automatiquement exécutées dans MetaTrader 5, lorsqu’elles atteignent un certain niveau de prix.

Le bloc « num signal » est auxiliaire et n’est pas affiché dans le code de l’Expert Advisor.

Le bloc « emas differential » vérifie les conditions d’ouverture d’une position courte ou longue en trouvant les différences. Le « K Delay » crée un décalage pour les tableaux, qui sont moyens à la valeur de K.

L’événement Buy ou Sell est créé, il s’agit d’un événement d’entrée pour le sous-système d’ouverture de position.

Dans le code, tout est exprimé comme suit :

// event Buy (activation by the negative front)
bool Buy=((ma2Val[1+K]-ma1Val[1+K])>=0 && (ma2Val[K]-ma1Val[K])<0) ||
         ((ma2Val[1+K]-ma1Val[1+K])>0 && (ma2Val[K]-ma1Val[K])==0);

// event Sell (activation by the positive front)
bool Sell=((ma2Val[1+K]-ma1Val[1+K])<=0 && (ma2Val[K]-ma1Val[K])>0)||
         ((ma2Val[1+K]-ma1Val[1+K])<0 && (ma2Val[K]-ma1Val[K])==0);
Le sous-système d’ouverture de position crée lui-même les événements « OpenBuy » et « OpenSell », qui sont traités dans le sous-système « Gestion de position », à l’aide de conditions et procédures.

 

4.2 Sous-système « Gestion de position »

Le sous-système commence à fonctionner en traitant les événements OpenBuy OpenSell.

Pour la première transition du sous-système, l’une des conditions est la présence d’au moins 56 barres, qui est indiquée dans le code à travers la vérification de ces conditions:

if(Bars(_Symbol,_Period)<56) // 1st transition of the «Position handling»subsystem : condition [Input.num>=56]
      {
        Alert("Not enough bars!");
        return(-1);
      }

Deuxième condition de la transition : le nombre de la barre d’ouverture doit être supérieur à la barre de fermeture (Input.num ; Output.barFermanse), c’est-à-dire  le poste a été close.

Dans le code, elle est indiquée comme suit:

//--- 1st transition of the «Position handling» subsystem: condition [Input.num>Output.barClose]

bool IsBought = false;  // bought
bool IsSold = false;    // sold
if(PositionSelect(_Symbol)==true) // there is an opened position
 {
   if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
     {
      IsBought=true;  // long
     }
   else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
     {
      IsSold=true;    // short
     }
  }
// check for opened position
if(IsTraded(IsBought,IsSold))
 {
   return;
 }

//+------------------------------------------------------------------+
//| Function of the check for opened position                        |
//+------------------------------------------------------------------+
bool IsTraded(bool IsBought,bool IsSold)
  {
   if(IsSold || IsBought)
     {
      Alert("Transaction is complete");
      return(true);
     }
   else
      return(false);
  }

La 4ème transition est responsable de l’ouverture d’une position longue.

elle est représentée comme suit :

// 4th transition procedures of the «Position handling» subsystem: open long position
 mrequest.action = TRADE_ACTION_DEAL;                                  // market buy
 mrequest.price = NormalizeDouble(latest_price.ask,_Digits);           // latest ask price
 mrequest.sl = NormalizeDouble(latest_price.bid - STP*_Point,_Digits);  // place Stop Loss
 mrequest.tp = NormalizeDouble(latest_price.bid + TKP*_Point,_Digits);  // place Take Profit
 mrequest.symbol = _Symbol;                                           // symbol
 mrequest.volume = Lot;                                              // total lots
 mrequest.magic = EA_Magic;                                          // Magic Number
 mrequest.type = ORDER_TYPE_BUY;                                       // order to buy
 mrequest.type_filling = ORDER_FILLING_FOK;                            // the specified volume and for a price, 
                                                                               // equal or better, than specified
 mrequest.deviation=100;                                             // slippage
 OrderSend(mrequest,mresult);
 if(mresult.retcode==10009 || mresult.retcode==10008) // request completed or order placed
    {
     Alert("A buy order has been placed, ticket #:",mresult.order);
    }
 else
    {
     Alert("A buy order has not been placed; error:",GetLastError());
     return;
    }

La 5ème transition est responsable de l’ouverture d’une position courte.

elle est représentée comme suit :

// 5th transition procedures of the «Position handling» subsystem: open a short position
 mrequest.action = TRADE_ACTION_DEAL;                                  // market sell
 mrequest.price = NormalizeDouble(latest_price.bid,_Digits);           // latest bid price
 mrequest.sl = NormalizeDouble(latest_price.ask + STP*_Point,_Digits);  // place a Stop Loss
 mrequest.tp = NormalizeDouble(latest_price.ask - TKP*_Point,_Digits);  // place a Take Profit
 mrequest.symbol = _Symbol;                                          // symbol
 mrequest.volume = Lot;                                             // lots
 mrequest.magic = EA_Magic;                                         // Magic Number
 mrequest.type= ORDER_TYPE_SELL;                                      // sell order
 mrequest.type_filling = ORDER_FILLING_FOK;                           // in the specified volume and for a price, 
                                                                              // equal or better, than specified in the order
 mrequest.deviation=100;                                             // slippage
 OrderSend(mrequest,mresult);
 if(mresult.retcode==10009 || mresult.retcode==10008) // request is complete or the order is placed
    {
     Alert("A sell order placed, ticket #:",mresult.order);
    }
 else
    {
     Alert("A sell order is not placed; error:",GetLastError());
     return;
    }

Les autres transitions dans les sous-catégories ne sont clairement pas présentées dans l’Expert Advisor, puisque les procédures appropriées (activation des arrêts ou atteinte d’un niveau Take Profit), sont effectuées automatiquement dans MQL5.

Le sous-système « ToWorkspace » n’est pas représenté dans le code MQL5 car sa tâche consiste à présenter la sortie dans les espaces de travail Matlab.


Conclusions

En utilisant une idée de trading simple comme exemple, j’ai créé le système de trading automatisé dans Simulink, dans lequel j’ai effectué un test inversé sur des données historiques. Au début, j’ai été dérangé par la question: « Y a-t-il un intérêt à s’impliquer dans toute cette agitation lorsque vous pouvez rapidement implémenter un système de trading via le code MQL5? »

Bien sûr, vous pouvez le faire sans la visualisation du processus de création du système et la logique de son travail. Mais le plus souvent, ce n’est que pour les programmeurs expérimentés ou simplement pour les personnes talentueuses. Lorsque le système de trading s’étend avec de nouvelles conditions et fonctions, la présence du schéma fonctionnel et son travail seront clairement la tâche du trader.

Je voudrais également mentionner que je n’ai pas essayé d’opposer les capacités du langage Simulink au langage MQL5. J’ai simplement illustré comment vous pouvez créer un système de trading automatisé en utilisant une conception de bloc. Peut-être qu’à l’avenir, les développeurs de MQL5 créeront un constructeur visuel de stratégies, qui facilitera le processus d’écriture d’Expert Advisors.

Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/155

Fichiers joints |
matlab.zip (28.68 KB)
mts.mq5 (9.93 KB)
testclose.mq5 (3.49 KB)
Le gestionnaire d'événements "New Bar" Le gestionnaire d'événements "New Bar"
Le langage de programmation MQL5 est en mesure de résoudre des problèmes à un tout nouveau niveau. Même ces tâches, qui offrent déjà de telles solutions, grâce à la programmation orientée objet peuvent atteindre un niveau supérieur. Dans cet article, nous prenons un exemple particulièrement simple de vérification d'une nouvelle barre sur un graphique, qui a été transformé en un outil plutôt puissant et polyvalent. Quel outil ? Découvrez-le dans cet article.
Recherche d'erreurs et journalisation Recherche d'erreurs et journalisation
MetaEditor 5 dispose de la fonctionnalité de débogage. Mais lorsque vous écrivez vos programmes MQL5, vous souhaitez souvent afficher non pas les valeurs individuelles, mais tous les messages qui apparaissent lors des tests et du travail en ligne. Lorsque le contenu du fichier journal est de grande taille, il est évident d'automatiser la récupération rapide et facile du message requis. Dans cet article, nous examinerons les moyens de trouver des erreurs dans les programmes MQL5 et les méthodes de collecte de données. Nous simplifierons également la connexion aux fichiers et apprendrons à connaître un programme simple LogMon pour une visualisation confortable des fichiers journaux
Gaz neuronal en croissance : Implémentation en MQL5 Gaz neuronal en croissance : Implémentation en MQL5
L'article étale un exemple de comment élaborer un programme MQL5 mettant en implémentant l'algorithme adaptatif de groupement appelé Growing neural gas (GNG). L'article est destiné aux utilisateurs qui ont étudié la documentation du langage et qui ont certaines compétences en programmation et des connaissances de base dans le domaine de la neuro-informatique.
Comment créer rapidement un Expert Advisor  pour le championnat de trading automatisé 2010 Comment créer rapidement un Expert Advisor pour le championnat de trading automatisé 2010
Afin d’élaborer un expert pour participer au Championnat de Trading Automatisé 2010, utilisons un modèle de conseiller expert prêt. Même le programmeur novice MQL5 sera en mesure d’assurer cette tâche, car pour vos stratégies les classes de base, les fonctions, les modèles sont déjà élaborés. Il suffit d'écrire un minimum de code pour implémenter votre idée de trading.