English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Graphiques et diagrammes en HTML

Graphiques et diagrammes en HTML

MetaTrader 5Exemples | 12 janvier 2022, 14:29
348 0
Victor
Victor


Introduction

Très probablement, https://www.metatrader5.com/MetaTrader 5 est un produit entièrement autonome et n’a pas besoin d’extensions supplémentaires. MetaTrader 5 fournit une connexion avec le courtier, affiche des cotations, nous permet d’utiliser une variété d’indicateurs pour l’analyse du marché et, bien sûr, donne au trader la possibilité de faire des opérations de trading. Il est tout à fait clair que puisque MetaTrader 5 se concentre principalement sur le confort du trading, il ne peut pas, et ne devrait techniquement pas, être un outil absolument universel, conçu pour la recherche, l’analyse de méthodes mathématiques, la création de contenu multimédia, etc.

De plus, l’universalité excessive d’un produit logiciel conduit finalement à une diminution de son efficacité, de sa fiabilité et de sa sécurité. D’autre part, dans certains cas, l’utilisateur peut avoir besoin de fonctionnalités supplémentaires, en particulier les traders sont des personnes ayant divers domaines d’expertise et formations. Par conséquent, toute fonctionnalité supplémentaire peut augmenter l’attractivité de la plate-forme de trading, si, bien sûr, elles sont réalisées de manière assez simple, et non au détriment de sa fiabilité et de sa sécurité.

Dans cet article, nous examinerons l’un de ces suppléments, qui offrent la possibilité de créer et de montrer les graphiques et les diagrammes axés sur les données obtenues à partir du terminal.

Chaque programme doit faire ce qu’il fait de mieux. Si nous adhérons à ce principe, alors rendons MetaTrader 5 responsable du trading avec le courtier, de la collecte et du traitement des informations entrantes, et utilisons un programme différent, destiné à ces fins, pour l’affichage graphique de ces informations.


NAVIGATEUR WEB

Aujourd’hui, il est difficile de trouver un ordinateur qui n’a pas de navigateur WEB installé. Depuis longtemps, les navigateurs évoluent et s’améliorent. Les navigateurs modernes sont assez fiables, stables dans leur travail et, surtout, gratuits. Compte tenu du fait qu’un navigateur Web est pratiquement l’outil de base pour accéder à Internet, la plupart des utilisateurs le connaissent et rencontrent peu de difficultés lors de son utilisation.

Les capacités des navigateurs modernes sont si larges que nous nous sommes habitués à regarder des vidéos, à écouter de la musique, à jouer à des jeux et à faire un certain nombre d’autres activités via un navigateur Web. Ainsi, aujourd’hui, un navigateur Web est un outil bien élaboré pour afficher différents types d’informations qui peuvent être présentées dans différents formats.

Il ne peut pas être laissé sous silence, qu’il existe actuellement plusieurs navigateurs Web populaires: InternetExplorer, Mozilla Firefox, Google Chrome, etOpera. Ces navigateurs peuvent différer considérablement les uns des autres dans l’aspect de l’implémentation logicielle et des interfaces utilisateur. Cependant, théoriquement, ils devraient pleinement soutenir les normes de base adoptées dans le réseau pour l’échange d’informations, qui concernent principalement les normes du langage HTML.

En pratique, malgré les efforts des développeurs, les navigateurs présentent encore certaines caractéristiques individuelles en termes d’implémentation de certains protocoles ou technologies. Si nous décidons qu’un navigateur particulier, en raison de ses fonctionnalités individuelles, ne nous convient pas, ce problème est facilement résolu en installant un ou plusieurs autres navigateurs Web sur notre ordinateur. Même les fervents partisans de navigateurs tels que Firefox ont au moins Internet Explorer installé dans leurs systèmes.

Malgré le fait que les navigateurs WEB ont été élaborés en tant que partie client, offrant une interaction avec un serveur distant, ils peuvent également être utilisés pour afficher des informations locales stockées sur votre ordinateur. Un exemple de ceci peut être l’affichage de pages WEB, précédemment enregistrées sur votre ordinateur. Le navigateur n’a pas besoin d’accéder à Internet pour travailler avec les pages locales.

Ainsi, un navigateur WEB, fonctionnant en mode hors ligne, est un candidat très attrayant pour le rôle d’un programme utilisé pour étendre les capacités graphiques du terminal client https://www.metatrader5.com/MetaTrader 5. Pour l’utiliser, vous n’avez pas besoin de faire des achats coûteux, des installations lourdes et longues, ni d’apprendre à utiliser un nouveau produit logiciel.

Par conséquent, plus loin dans cet article, nous examinerons les possibilités d’utiliser des navigateurs Web pour construire des graphiques et des diagrammes, axés sur les données obtenues dans MetaTrader 5.


HTML et JavaScript

En choisissant d’utiliser un navigateur WEB comme extension, définissons-nous la règle de base, à laquelle désormais nous adhérerons strictement - l’affichage des pages HTML créées doit être effectué sans le serveur WEB local ou distant. C’est-à-dire que nous n’installerons sur notre ordinateur aucun logiciel serveur et que l’affichage de nos pages ne nécessitera pas d’accès au réseau. Les pages HTML que nous créons ne doivent être affichées qu’au moyen du navigateur Web et doivent être situées sur notre ordinateur. Cette règle minimisera le risque associé à la réduction possible de la sécurité due à l’accès au réseau extérieur.

En utilisant uniquement les fonctionnalités de HTML 4 pour l’affichage des informations, nous pouvons créer des pages WEB avec des tableaux, du texte formaté et des images, mais ces opportunités ne peuvent pas nous satisfaire pleinement, car notre objectif est de construire des graphiques et des diagrammes à part entière, axés sur les données reçues de MetaTrader 5.

Dans la plupart des cas, ce que nous constatons dans le navigateur lorsque nous naviguons vers différents sites, est créé en utilisant les extensions de HTML. En général, ces extensions sont exécutées côté serveur et, pour cette raison, n’est pas adapté à nos besoins. Les technologies en mesure de fonctionner du côté du navigateur et ne nécessitant pas de logiciel serveur, par exemple Macromedia Flash, JavaScript et Java, peuvent nous intéresser.

Si pour l’exécution, côté navigateur, des applications Macromedia Flash et Java, nous aurons, au minimum, besoin de l’installation de plug-ins supplémentaires, alors les programmes utilisateur, écrits en JavaScript, sont directement exécutés par le navigateur. Tous les navigateurs WEB courants ont leurs propres interpréteurs JavaScript intégrés. Afin d’éviter de devoir à installer des logiciels ou des plug-ins supplémentaires, choisissons JavaScript.

Ainsi, dans ce qui suit, nous n’utiliserons MetaTrader 5 qu’avec MQL5 et un navigateur WEB avec HTML et JavaScript. Aucun logiciel supplémentaire ne sera nécessaire. Il convient de rappeler qu’une page HTML n’est rien de plus qu’un fichier texte. Par conséquent, pour créer un document HTML, nous pouvons utiliser n’importe quel éditeur de texte. Par exemple, nous pouvons créer et modifier du code HTML dans MetaEditor 5. Lors de la rédaction de cet article, l’édition du code HTML a été effectuée dans le navigateur http://www.opera-usb.com/Opera @ USB v10.63, qui vous permet de modifier le contenu de la page, d’enregistrer la page modifiée et de prévisualiser la façon dont elle sera affichée.

Une personne, qui n’est pas familière avec les langages HTML et JavaScript, peut être raisonnablement inquiète des difficultés possibles associées à leur maîtrise. Afin de faciliter notre tâche et d’éviter une étude approfondie du HTML et du JavaScript, nous tenterons d’utiliser des solutions prêtes à l’emploi axées sur cette technologie. Étant donné que dans le cadre de cet article, notre objectif se limite uniquement à la construction de graphiques et de diagrammes, nous utiliserons des bibliothèques JavaScript prêtes à l’emploi, écrites spécialement à cet effet.

Le Emprise JavaScript Charts est une bibliothèque graphique élaborée silencieuse. Peut-être que le lecteur sera intéressé à mieux la connaître grâce au lien fourni, cependant, cette bibliothèque n’est pas tout à fait gratuite. Par conséquent, tournons-nous vers les bibliothèques gratuites, par exemple, Dygraphs JavaScript Visualization Library et Highcharts charting library. Dygraphs est attrayant en raison de sa compacité et de sa simplicité, et la bibliothèque Highcharts, à son tour, comprend une plus grande quantité de fonctionnalités et semble plus universelle. Malgré le fait que la bibliothèque Highcharts fait environ 75 Ko et nécessite une bibliothèque jQuery supplémentaire, soit environ 70 Ko supplémentaires, nous la choisirons toujours comme bibliothèque de notre choix.

Vous pouvez vous familiariser avec la bibliothèque Highcharts sur notre site Web http://www.highcharts.com/http://www.highcharts.com/ dans la section « Galerie de démonstration ». Pour chacun des exemples, en cliquant sur « Options d’affichage », vous pouvez constater son code JavaScript source. La documentation détaillée sur la bibliothèque se trouve dans la section « Documentation / Référence des options », dans cette section, vous pouvez également trouver de nombreux exemples de l’utilisation de différentes options. À première vue, en raison de l’abondance du code JavaScript et de la syntaxe inhabituelle pour un programmeur MQL, l’utilisation de cette bibliothèque peut sembler assez compliquée. Mais ce n’est pas tout à fait le cas. Examinons le premier exemple d’un simple fichier HTML qui, par le biais de la bibliothèque, affichera le graphique.

Par exemple, créons un fichier texte nommé Test_01.htm dans l’éditeur du Bloc-notes et copiez l’exemple simple suivant d’utilisation de la bibliothèque.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Example</title>
<!-- - -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"
             type="text/javascript"></script>
<script src="/js/highcharts.js" type="text/javascript"></script>
<!-- - -->
<script type="text/javascript">
var chart1;
$(document).ready(function(){
  chart1 = new Highcharts.Chart({
    chart: {renderTo: 'container1'},
    series: [{data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]}]
  });
});
</script>
<!-- - -->
</head>
<body>
<div id="container1" style="width: 700px; height: 400px "></div>
</body>
</html>

L’échantillon code est séparé en quatre sections par les commentaires.

La première partie supérieure du code comporte les balises de page HTML habituelles. Cette partie du code ne nous intéresse pas particulièrement pour le moment.

Il est suivi d’une autre partie, qui comporte deux balises <script>. Dans le premier cas, nous donnons au navigateur une commande pour télécharger à partir du site Web ajax.googleapis.com le code de bibliothèque jquery.min.js. Le deuxième cas admet que côté serveur, le catalogue /js/ comporte les highcharts de la bibliothèque.js, que le navigateur doit télécharger. Ayant précédemment décidé que dans le processus d’affichage de nos pages, il ne devrait pas y avoir d’accès à des sources externes, cette partie du code devra être modifiée.

Après avoir apporté les modifications, cette partie du code ressemblera à ceci

<script src="jquery.min.js" type="text/javascript"></script>
<script src="highcharts.js" type="text/javascript"></script>

Dans ce cas, nous donnons la commande de télécharger les deux bibliothèques à partir du catalogue qui comporte notre fichier HTML, c’est-à-dire à partir du catalogue actuel. Pour que les bibliothèques puissent être téléchargées par le navigateur, elles doivent d’abord être téléchargées à partir de ajax.googleapis.com et http://www.highcharts.com/http://www.highcharts.com respectivement, et copiées dans le même catalogue où se trouve notre fichier HTML. Ces deux bibliothèques se trouvent également à la fin de cet article, dans les pièces jointes.

Dans la section suivante du code, un objet de classe Highcharts.Chart est créé. Le paramètre « renderTo: 'container1' » indique que le graphique sera affiché dans l’élément HTML appelé « container1 », et le paramètre « data » définit les données qui seront affichées sur le graphique. Comme nous pouvons le constater dans cet exemple, les données sont définies de la même manière que les paramètres, - lors de la création d’un objet de la classe Highcharts.Chart. En apportant de simples modifications, nous localisons la définition des données affichées dans une partie distincte du code, ce qui nous permettra, dans le cas où nous devons afficher plusieurs graphiques, de regrouper leurs données.

Dans la dernière partie de notre exemple, la balise <div>déclare un élément HTML appelé « container1 », et les dimensions de cet élément sont indiquées. Comme mentionné précédemment, il s’agit de l’élément HTML qui sera utilisé pour construire le graphique, dont la taille sera déterminée par la taille, indiquée dans la balise <div>, de l’élément « container1 ».

Compte tenu des modifications apportées, le code de notre exemple se présentera comme suit :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Example</title>
<!-- - -->
<script src="jquery.min.js" type="text/javascript"></script>
<script src="highcharts.js" type="text/javascript"></script>
<!-- - -->
<script type="text/javascript">
var dat1 = [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4];
</script>
<!-- - -->
<script type="text/javascript">
var chart1;
$(document).ready(function(){
  chart1 = new Highcharts.Chart({
    chart: {renderTo: 'container1'},
    series: [{data: dat1}]
  });
});
</script>
<!-- - -->
</head>
<body>
<div id="container1" style="width: 700px; height: 400px "></div>
</body>
</html>

Ce cas de test et toutes les bibliothèques peuvent être copiés à partir des pièces jointes à la fin de cet article. Le fichier d’exemple Test_01.htm et les fichiers des bibliothèques se trouvent dans le même dossier \Test, par conséquent, nous double-cliquons simplement sur le fichier HTML Test_01.htm pour constater les résultats de notre travail.

Il faut garder à l’esprit que pour un affichage normal de cette page de test, l’exécution de JavaScript doit être autorisée dans le navigateur WEB. Étant donné que les navigateurs, pour des raisons de sécurité, vous permettent de désactiver cette option, il peut arriver qu’elle soit désactivée. En conséquence, nous devrions constater ce qui suit:

Test_01.htm

Figure 1. Test_01.htm 

Il s’agit de notre premier tableau de test, et malgré la complexité apparente de cette technologie, sa création n’a pas pris longtemps.

Nous devons noter certaines caractéristiques des graphiques affichés, créés de cette manière. Dans le catalogue copié, ouvrez le fichier Test_01.htm, et si le navigateur Web vous permet de zoomer sur les pages consultées, vous remarquerez que même avec un agrandissement substantiel, la qualité du graphique ne sedégrade pas.

Cela est dû au fait que ce graphique n’est pas une image statique, telle que des fichiers PNG ou JPEG, et est ré-esquissé après un zoom avant ou arrière de la zone allouée à son dessin. Par conséquent, une telle image ne peut pas être enregistrée sur un disque, de la même manière que nous enregistrons généralement une image que nous aimons. Puisque le graphique a été construit au moyen de JavaScript, nous ne devons pas manquer de mentionner le fait que différents navigateurs, ayant leurs propres interprètes intégrés de ce langage, peuvent ne pas toujours l’exécuter de la même manière.

Les graphiques créés à l’aide de JavaScript peuvent parfois différer lors de l’utilisation de différents navigateurs. Le plus souvent, ces différences, par rapport à d’autres navigateurs, se produisent le plus souvent dans Internet Explorer.

Mais nous espérons que les créateurs de bibliothèques JavaScript s’occuperont de la compatibilité maximale possible de leur code avec les navigateurs WEB les plus populaires.


MetaTrader 5 et MQL5

Dans l’exemple ci-dessus, les données, destinées à être affichées sur le graphique, ont été manuellement définies lors de la création de la page HTML. Pour organiser le transfert des données de https://www.metatrader5.com/enMetaTrader 5 dans le graphique créé, nous utiliserons la méthode la plus simple. Laissez données d’enregistrement MetaTrader 5 dans un fichier séparé à partir duquel elles seront chargées dans le navigateur, lors de l’affichage du graphique. Écrivons un exemple qui inclut une page HTML, qui affichera le graphique, en téléchargeant des données à partir d’un fichier et d’un script sur MQL5, qui créera ce fichier.

En tant que fichier HTML, nous utiliserons le fichier précédemment créé Test_01.htm, après y avoir apporté quelques légères modifications. Nous avons appelé le fichier modifié comme exemple1.htm. Toutes les modifications apportées seront réduites au fait que les lignes :

<script type="text/javascript">
var dat1 = [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4];
</script>
sera remplacé par
<script type="text/javascript">
var dat1=[0];
</script>
<script src="exdat.txt" type="text/javascript"></script>

Maintenant, le navigateur, lors du téléchargement de la page HTML, devra également charger le fichier texte exdat.txt, dans lequel les valeurs destinées à être affichées sur le graphique seront affectées au tableau dat1. Ce fichier doit comporter un fragment de code JavaScript. Ce fichier peut être facilement créé dans MetaTrader 5, en utilisant le script correspondant.

Un exemple d’un tel script est fourni ci-dessous.

//+------------------------------------------------------------------+
//|                                                     Example1.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
  int i,n,fhandle;
  double gr[25];
  string str;
  
  n=ArraySize(gr);
  for(i=0;i<n;i++)
    {
    gr[i]=NormalizeDouble(MathSin(i*3*2*M_PI/n),4);
    }

  str=DoubleToString(gr[0],4);
  for(i=1;i<n;i++)
    {
    str+=","+DoubleToString(gr[i],4);
    }
  
  ResetLastError();
  fhandle=FileOpen("exdat.txt",FILE_WRITE|FILE_TXT|FILE_ANSI);
  if(fhandle<0){Print("File open failed, error ",GetLastError());return;}
  
  FileWriteString(fhandle,"dat1=["+str+"];\n");
  
  FileClose(fhandle);
  }
//+------------------------------------------------------------------+

Pour stocker les données affichées, ce script utilise le tableau gr[], qui comporte 25 éléments. Ce tableau, à titre d’exemple, est rempli de valeurs de fonction sinusale, l’arrondi étant effectué jusqu’à quatre décimales. Ce tableau, bien sûr, peut être rempli avec d’autres données plus utiles.

De plus, ces données disposent d’un format et sont combinées en une seule chaîne de texte. Afin de réduire le volume du fichier texte généré, les valeurs des éléments de tableau gr[] avec seulement quatre décimales sont placées dans la chaîne. À cette fin, nous avons utilisé la fonction DoubleToString().

Une fois la chaîne de texte str formée, elle est stockée dans le fichier exdat.txt. En cas d’exécution réussie du script, le fichier texte texdat.txt sera créé dans le sous-dossier \MQL5\Files du terminal client ; si le fichier existe déjà, il sera écrasé.

Les fichiers jquery.min.js, highcharts.js, Example1.mq5, Example1.htm et exdat.txt sont présentés à la fin de cet article dans la section pièces jointes. Ces cinq fichiers se trouvent dans le catalogue \Exemple1. Pour simplement afficher les résultats, copiez simplement cet exemple et dans le catalogue \Example1 ouvrez le fichier Example1.htm. Le graphique sera construit en fonction des données du fichier exdat.txt.

Exemple1.htm 

Figure 2. Exemple1.htm

Bien sûr, pour exécuter le script Example1.mq5, il doit se trouver dans le dossier \MQL5\Scripts du terminal client et être compilé.

Comme mentionné précédemment, après le lancement du script, le fichier exdat.txt sera créé dans le dossier \MQL5\Files, mais dans notre exemple, le fichier HTML, les fichiers des bibliothèques et le fichier de données doivent tous se trouver dans le même dossier. Par conséquent, nous devons copier les fichiers jquery.min.js, highcharts.js et Example1.htm dans le dossier \MQL5\Files ou copier le fichier exdat.txt dans le dossier où se trouvent ces fichiers.

Dans cet exemple, la page HTML et les bibliothèques sont stockées dans des fichiers différents. Au stade la conception, il peut être utile que différentes parties du projet se trouvent dans des fichiers distincts. Cela permet d’éviter, par exemple, des modifications aléatoires du code des bibliothèques lors de la modification du fichier HTML. Mais une fois que la page HTML est entièrement modifiée et qu’aucune autre modification ne devrait être apportée, les bibliothèques peuvent être directement intégrées dans le fichier de code HTML.

Cela est possible parce que les bibliothèques JavaScript ne sont que de simples fichiers texte. Si nous ouvrons le jquery.min.js ou les highcharts.js avec un éditeur de texte, nous ne verrons rien d’intelligible, car le code source des bibliothèques a été compressé à la capacité maximale.

La compression est effectuée en supprimant les symboles de service, par exemple une interligne ou une série d’espaces. Après une telle compression, toute mise en forme est perdue, mais le texte reste sous forme de texte, car le type de fichier ne change pas. Par conséquent, peu importe que le navigateur se connecte au code de la bibliothèque à partir d’un fichier externe avec l’extension .js, ou qu’il le lise à partir du fichier HTML actuel, qui à son tour est également dans un format texte.

Pour combiner les fichiers, remplacez dans Exemple1.htm les lignes

<script src="jquery.min.js" type="text/javascript"></script>
<script src="highcharts.js" type="text/javascript"></script>

avec

<script type="text/javascript">

</script>

Ensuite, à l’aide d’un éditeur de texte tel que le Bloc-notes, nous ouvrons le fichier de la bibliothèque jquery.min.js, et en choisissant la commande « Sélectionner tout », copiez le contenu du fichier. Ensuite, ouvrez le fichier Example1.htm, collez le texte copié de la bibliothèque entre les balises <script type=\"text/javascript\"> et </script>. Enregistrez le fichier obtenu sous le nom d’Exemple2.htm. De la même manière, copiez le contenu de la bibliothèque highcharts.js dans ce fichier, en le plaçant entre le texte de la bibliothèque précédemment copiée et la balise </script>.

À la suite de la copie, la taille du fichier HTML augmente, cependant, nous n’avons plus besoin de fichiers séparés des bibliothèques pour son affichage correct. Il suffit d’avoir le fichier de données exdat.txt dans le dossier\Exemple2, qui inclut les fichiers Exemple2.htm et exdat.txt se trouve à la fin de cet article dans la section pièces jointes.


Un rapport sur l’historique du trading sous forme graphique

Pour une démonstration plus complète de la méthode proposée d’affichage des informations graphiques, nous allons créer un rapport qui montre l’historique du compte de trading à un intervalle de temps indiqué. Le rapport HTML créé dans MetaTrader 5 lorsque vous sélectionnez la commande « Rapport » dans le menu contextuel de l’onglet « Historique », servira de prototype. Ce rapport comprend un grand nombre de caractéristiques différentes, résumées dans un seul tableau. En admettant que ces caractéristiques seront plus visuelles lorsqu’elles seront présentées sous forme de graphiques et de diagrammes, affichons-les à l’aide de la bibliothèque graphique highcharts.js.

Dans les exemples ci-dessus, pour la construction du graphique, nous avons utilisé les paramètres d’affichage par défaut, définis dans cette version de la bibliothèque highcharts.js.

Pour des raisons pratiques, cette option n’aboutira pas, car dans chaque cas, nous devrons ajuster la vue du graphique pour répondre aux exigences spécifiques individuelles. À cette fin, la bibliothèque highcharts.js offre un large éventail d’opportunités, avec un grand nombre d’options qui peuvent être appliquées au graphique ou au diagramme. Comme déjà mentionné, la liste des options, ainsi que leurs descriptions détaillées et leurs exemples, peuvent être trouvées sur http://www.highcharts.com.

Nous ne nous attarderons pas sur la description des options de la bibliothèque graphique et sur les spécificités de son utilisation, car cet article vise uniquement à suggérer et à démontrer la possibilité d’utiliser un NAVIGATEUR WEB pour afficher les informations reçues de MetaTrader 5. D’autant plus qu’en fonction des exigences spécifiques pour la création d’une page WEB, une autre bibliothèque JavaScript peut être utilisée. Le lecteur peut sélectionner indépendamment la bibliothèque la plus appropriée et l’étudier aussi en profondeur comme l’exige sa pratique..

Pour afficher l’historique du compte de trading, nous avons créé le fichier ProfitReport.htm. Il se trouve dans les pièces jointes.  Le dossier \Report comporte les données.txt avec les données à afficher. Le fichier data.txt est placé dans le dossier à titre d’exemple.

Lorsque nous copions le dossier \Report et ouvrons le .htm ProfitReport, nous constatons les caractéristiques de trading du compte test, créé pour cet exemple, sous forme graphique.

ProfitReport.htm

Figure 3. ProfitReport.htm

Lors de la création du ProfitReport.htm, nous avons d’abord créé une mise en page approximative et déterminé à peu près où et quel type d’informations seront localisées.

Ensuite, nous avons placé les graphiques, avec leurs options par défaut, sur la page.

Après avoir créé ce modèle, nous avons choisi les options les plus appropriées pour chaque graphique individuel. Après avoir terminé l’édition, nous avons simplement copié les textes des bibliothèques dans la page. Comme déjà mentionné, pour un affichage correct de la page, il doit être situé dans le même catalogue que les données du fichier.txt, qui comporte les données, destinées à son affichage.

Le fichier data.txt a été créé dans MetaTrader 5, en utilisant le script ProfitReport.mq5. Dans le cas d’une exécution réussie de ce script, le fichier data.txt est créé dans le dossier \MQL5\Files, comportant les caractéristiques du trade du compte couramment actif.

Nous ne devons pas oublier que le script doit être placé dans le dossier \MQL5\Scripts et compilé.

//-----------------------------------------------------------------------------------
//                                                                   ProfitReport.mq5
//                                          Copyright 2011, MetaQuotes Software Corp.
//                                                                https://www.mql5.com
//-----------------------------------------------------------------------------------
#property copyright   "Copyright 2011, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version     "1.00"
#property script_show_inputs

#include <Arrays\ArrayLong.mqh>
#include <Arrays\ArrayDouble.mqh>
#include <Arrays\ArrayString.mqh>
#include <Arrays\ArrayInt.mqh>

//--- input parameters
input int nD=30;               // Number of days
//--- global
double   balabce_cur=0;        // balance
double   initbalance_cur=0;    // Initial balance (not including deposits to the account)
int      days_num;             // number of days in the report (including the current day)
datetime tfrom_tim;            // Date from
datetime tend_tim;             // Date to
double   netprofit_cur=0;      // Total Net Profit
double   grossprofit_cur=0;    // Gross Profit
double   grossloss_cur=0;      // Gross Loss
int      totaltrades_num=0;    // Total Trades
int      longtrades_num=0;     // Number of Long Trades
double   longtrades_perc=0;    // % of Long Trades
int      shorttrades_num=0;    // Number of Short Trades
double   shorttrades_perc=0;   // % of Short Trades
int      proftrad_num=0;       // Number of All Profit Trades
double   proftrad_perc=0;      // % of All Profit Trades
int      losstrad_num=0;       // Number of All Loss Trades
double   losstrad_perc=0;      // % of All Loss Trades
int      shortprof_num=0;      // Number of Short Profit Trades
double   shortprof_perc=0;     // % of Short Profit Trades
double   shortloss_perc=0;     // % of Short Loss Trades
int      longprof_num=0;       // Number of Long Profit Trades
double   longprof_perc=0;      // % of Long Profit Trades
double   longloss_perc=0;      // % of Long Loss Trades
int      maxconswins_num=0;    // Number of Maximum consecutive wins
double   maxconswins_cur=0;    // Maximum consecutive wins ($)
int      maxconsloss_num=0;    // Number of Maximum consecutive losses
double   maxconsloss_cur=0;    // Maximum consecutive losses ($)
int      aveconswins_num=0;    // Number of Average consecutive wins
double   aveconswins_cur=0;    // Average consecutive wins ($)
int      aveconsloss_num=0;    // Number of Average consecutive losses
double   aveconsloss_cur=0;    // Average consecutive losses ($)
double   largproftrad_cur=0;   // Largest profit trade
double   averproftrad_cur=0;   // Average profit trade
double   larglosstrad_cur=0;   // Largest loss trade
double   averlosstrad_cur=0;   // Average loss trade
double   profitfactor=0;       // Profit Factor
double   expectpayoff=0;       // Expected Payoff
double   recovfactor=0;        // Recovery Factor
double   sharperatio=0;        // Sharpe Ratio
double   ddownabs_cur=0;       // Balance Drawdown Absolute
double   ddownmax_cur=0;       // Balance Drawdown Maximal
double   ddownmax_perc=0;      // % of Balance Drawdown Maximal
int      symbols_num=0;        // Numbre of Symbols
  
string       Band="";
double       Probab[33],Normal[33];
CArrayLong   TimTrad;
CArrayDouble ValTrad;
CArrayString SymNam;
CArrayInt    nSymb;

//-----------------------------------------------------------------------------------
// Script program start function
//-----------------------------------------------------------------------------------
void OnStart()
  {
  int         i,n,m,k,nwins=0,nloss=0,naverw=0,naverl=0,nw=0,nl=0;
  double      bal,sum,val,p,stdev,vwins=0,vloss=0,averwin=0,averlos=0,pmax=0;
  MqlDateTime dt;
  datetime    ttmp,it;
  string      symb,br;
  ulong       ticket;
  long        dtype,entry;
  
  if(!TerminalInfoInteger(TERMINAL_CONNECTED)){printf("Terminal not connected.");return;}
  days_num=nD;
  if(days_num<1)days_num=1;             // number of days in the report (including the current day)
  tend_tim=TimeCurrent();                                                // date to
  tfrom_tim=tend_tim-(days_num-1)*86400;
  TimeToStruct(tfrom_tim,dt);
  dt.sec=0; dt.min=0; dt.hour=0;
  tfrom_tim=StructToTime(dt);                                            // date from
//---------------------------------------- Bands
  ttmp=tfrom_tim;
  br="";
  if(dt.day_of_week==6||dt.day_of_week==0)
    {
    Band+=(string)(ulong)(ttmp*1000)+",";
    br=",";ttmp+=86400;
    }
  for(it=ttmp;it<tend_tim;it+=86400)
    {
    TimeToStruct(it,dt);
    if(dt.day_of_week==6){Band+=br+(string)(ulong)(it*1000)+","; br=",";}
    if(dt.day_of_week==1&&br==",") Band+=(string)(ulong)(it*1000);
    }
  if(dt.day_of_week==6||dt.day_of_week==0) Band+=(string)(ulong)(tend_tim*1000);

//----------------------------------------
  balabce_cur=AccountInfoDouble(ACCOUNT_BALANCE);                          // Balance

  if(!HistorySelect(tfrom_tim,tend_tim)){Print("HistorySelect failed");return;}
  n=HistoryDealsTotal();                                           // Number of Deals
  for(i=0;i<n;i++)
    {
    ticket=HistoryDealGetTicket(i);
    entry=HistoryDealGetInteger(ticket,DEAL_ENTRY);
    if(ticket>=0&&(entry==DEAL_ENTRY_OUT||entry==DEAL_ENTRY_INOUT))
      {
      dtype=HistoryDealGetInteger(ticket,DEAL_TYPE);
      if(dtype==DEAL_TYPE_BUY||dtype==DEAL_TYPE_SELL)
        {
        totaltrades_num++;                                          // Total Trades
        val=HistoryDealGetDouble(ticket,DEAL_PROFIT);
        val+=HistoryDealGetDouble(ticket,DEAL_COMMISSION);
        val+=HistoryDealGetDouble(ticket,DEAL_SWAP);
        netprofit_cur+=val;                                         // Total Net Profit
        if(-netprofit_cur>ddownabs_cur)ddownabs_cur=-netprofit_cur; // Balance Drawdown Absolute
        if(netprofit_cur>pmax)pmax=netprofit_cur;
        p=pmax-netprofit_cur;
        if(p>ddownmax_cur)
          {
          ddownmax_cur=p;                                 // Balance Drawdown Maximal
          ddownmax_perc=pmax;
          }
        if(val>=0)              //win
          {
          grossprofit_cur+=val;                            // Gross Profit 
          proftrad_num++;                                  // Number of Profit Trades
          if(val>largproftrad_cur)largproftrad_cur=val;    // Largest profit trade
          nwins++;vwins+=val;
          if(nwins>=maxconswins_num)
            {
            maxconswins_num=nwins;
            if(vwins>maxconswins_cur)maxconswins_cur=vwins;
            }
          if(vloss>0){averlos+=vloss; nl+=nloss; naverl++;}
          nloss=0;vloss=0;
          }
        else                    //loss
          {
          grossloss_cur-=val;                                   // Gross Loss
          if(-val>larglosstrad_cur)larglosstrad_cur=-val;       // Largest loss trade
          nloss++;vloss-=val;
          if(nloss>=maxconsloss_num)
            {
            maxconsloss_num=nloss;
            if(vloss>maxconsloss_cur)maxconsloss_cur=vloss;
            }
          if(vwins>0){averwin+=vwins; nw+=nwins; naverw++;}
          nwins=0;vwins=0;
          }
        if(dtype==DEAL_TYPE_SELL)
          {
          longtrades_num++;                          // Number of Long Trades
          if(val>=0)longprof_num++;                  // Number of Long Profit Trades
          }
        else if(val>=0)shortprof_num++;               // Number of Short Profit Trades

        symb=HistoryDealGetString(ticket,DEAL_SYMBOL);   // Symbols
        k=1;
        for(m=0;m<SymNam.Total();m++)
          {
          if(SymNam.At(m)==symb)
            {
            k=0;
            nSymb.Update(m,nSymb.At(m)+1);
            }
          }
        if(k==1)
          {
          SymNam.Add(symb);
          nSymb.Add(1);
          }
        
        ValTrad.Add(val);
        TimTrad.Add(HistoryDealGetInteger(ticket,DEAL_TIME));
        }
      }
    }
  if(vloss>0){averlos+=vloss; nl+=nloss; naverl++;}
  if(vwins>0){averwin+=vwins; nw+=nwins; naverw++;}
  initbalance_cur=balabce_cur-netprofit_cur;
  if(totaltrades_num>0)
    {
    longtrades_perc=NormalizeDouble((double)longtrades_num/totaltrades_num*100,1);     // % of Long Trades
    shorttrades_num=totaltrades_num-longtrades_num;                                 // Number of Short Trades
    shorttrades_perc=100-longtrades_perc;                                           // % of Short Trades
    proftrad_perc=NormalizeDouble((double)proftrad_num/totaltrades_num*100,1);         // % of Profit Trades
    losstrad_num=totaltrades_num-proftrad_num;                                      // Number of Loss Trades
    losstrad_perc=100-proftrad_perc;                                                // % of All Loss Trades
    if(shorttrades_num>0)
      {
      shortprof_perc=NormalizeDouble((double)shortprof_num/shorttrades_num*100,1);     // % of Short Profit Trades
      shortloss_perc=100-shortprof_perc;                                            // % of Short Loss Trades
      }
    if(longtrades_num>0)
      {
      longprof_perc=NormalizeDouble((double)longprof_num/longtrades_num*100,1);        // % of Long Profit Trades
      longloss_perc=100-longprof_perc;                                              // % of Long Loss Trades
      }
    if(grossloss_cur>0)profitfactor=NormalizeDouble(grossprofit_cur/grossloss_cur,2);  // Profit Factor
    if(proftrad_num>0)averproftrad_cur=NormalizeDouble(grossprofit_cur/proftrad_num,2);// Average profit trade
    if(losstrad_num>0)averlosstrad_cur=NormalizeDouble(grossloss_cur/losstrad_num,2);  // Average loss trade
    if(naverw>0)
      {
      aveconswins_num=(int)NormalizeDouble((double)nw/naverw,0);
      aveconswins_cur=NormalizeDouble(averwin/naverw,2);
      }
    if(naverl>0)
      {
      aveconsloss_num=(int)NormalizeDouble((double)nl/naverl,0);
      aveconsloss_cur=NormalizeDouble(averlos/naverl,2);
      }
    p=initbalance_cur+ddownmax_perc;
    if(p!=0)
      {
      ddownmax_perc=NormalizeDouble(ddownmax_cur/p*100,1); // % of Balance Drawdown Maximal
      }
    if(ddownmax_cur>0)recovfactor=NormalizeDouble(netprofit_cur/ddownmax_cur,2); // Recovery Factor

    expectpayoff=netprofit_cur/totaltrades_num;                    // Expected Payoff
    
    sum=0;
    val=balabce_cur;
    for(m=ValTrad.Total()-1;m>=0;m--)
      {
      bal=val-ValTrad.At(m);
      p=val/bal;
      sum+=p;
      val=bal;
      }
    sum=sum/ValTrad.Total();
    stdev=0;
    val=balabce_cur;
    for(m=ValTrad.Total()-1;m>=0;m--)
      {
      bal=val-ValTrad.At(m);
      p=val/bal-sum;
      stdev+=p*p;
      val=bal;
      }
    stdev=MathSqrt(stdev/ValTrad.Total());
    if(stdev>0)sharperatio=NormalizeDouble((sum-1)/stdev,2);    // Sharpe Ratio

    stdev=0;
    for(m=0;m<ValTrad.Total();m++)
      {
      p=ValTrad.At(m)-expectpayoff;
      stdev+=p*p;
      }
    stdev=MathSqrt(stdev/ValTrad.Total());                      // Standard deviation
    if(stdev>0)
      {
      ArrayInitialize(Probab,0.0);
      for(m=0;m<ValTrad.Total();m++)                           // Histogram
        {
        i=16+(int)NormalizeDouble((ValTrad.At(m)-expectpayoff)/stdev,0);
        if(i>=0 && i<ArraySize(Probab))Probab[i]++;
        }
      for(m=0;m<ArraySize(Probab);m++) Probab[m]=NormalizeDouble(Probab[m]/totaltrades_num,5);
      }
    expectpayoff=NormalizeDouble(expectpayoff,2);                  // Expected Payoff  
    k=0;
    symbols_num=SymNam.Total();                                  // Symbols
    for(m=0;m<(6-symbols_num);m++)
      {
      if(k==0)
        {
        k=1;
        SymNam.Insert("",0);
        nSymb.Insert(0,0);
        }
      else
        {
        k=1;
        SymNam.Add("");
        nSymb.Add(0);
        }
      }
    }
  p=1.0/MathSqrt(2*M_PI)/4.0;
  for(m=0;m<ArraySize(Normal);m++)                             // Normal distribution
    {
    val=(double)m/4.0-4;
    Normal[m]=NormalizeDouble(p*MathExp(-val*val/2),5);
    }

  filesave();
  }
//-----------------------------------------------------------------------------------
// Save file
//-----------------------------------------------------------------------------------
void filesave()
  {
  int n,fhandle;
  string loginame,str="",br="";
  double sum;
  
  ResetLastError();
  fhandle=FileOpen("data.txt",FILE_WRITE|FILE_TXT|FILE_ANSI);
  if(fhandle<0){Print("File open failed, error ",GetLastError());return;}
  
  loginame="\""+(string)AccountInfoInteger(ACCOUNT_LOGIN)+", "+
                        TerminalInfoString(TERMINAL_COMPANY)+"\"";
  str+="var PName="+loginame+";\n";
  str+="var Currency=\""+AccountInfoString(ACCOUNT_CURRENCY)+"\";\n";
  str+="var Balance="+(string)balabce_cur+";\n";
  str+="var IniBalance="+(string)initbalance_cur+";\n";
  str+="var nDays="+(string)days_num+";\n";
  str+="var T1="+(string)(ulong)(tfrom_tim*1000)+";\n";
  str+="var T2="+(string)(ulong)(tend_tim*1000)+";\n";
  str+="var NetProf="+DoubleToString(netprofit_cur,2)+";\n";
  str+="var GrossProf="+DoubleToString(grossprofit_cur,2)+";\n";
  str+="var GrossLoss="+DoubleToString(grossloss_cur,2)+";\n";
  str+="var TotalTrad="+(string)totaltrades_num+";\n";
  str+="var NProfTrad="+(string)proftrad_num+";\n";
  str+="var ProfTrad="+DoubleToString(proftrad_perc,1)+";\n";
  str+="var NLossTrad="+(string)losstrad_num+";\n";
  str+="var LossTrad="+DoubleToString(losstrad_perc,1)+";\n";
  str+="var NLongTrad="+(string)longtrades_num+";\n";
  str+="var LongTrad="+DoubleToString(longtrades_perc,1)+";\n";
  str+="var NShortTrad="+(string)shorttrades_num+";\n";
  str+="var ShortTrad="+DoubleToString(shorttrades_perc,1)+";\n";
  str+="var ProfLong ="+DoubleToString(longprof_perc,1)+";\n";
  str+="var LossLong ="+DoubleToString(longloss_perc,1)+";\n";
  FileWriteString(fhandle,str); str="";
  str+="var ProfShort="+DoubleToString(shortprof_perc,1)+";\n";
  str+="var LossShort="+DoubleToString(shortloss_perc,1)+";\n";
  str+="var ProfFact="+DoubleToString(profitfactor,2)+";\n";
  str+="var LargProfTrad="+DoubleToString(largproftrad_cur,2)+";\n";
  str+="var AverProfTrad="+DoubleToString(averproftrad_cur,2)+";\n";
  str+="var LargLosTrad="+DoubleToString(larglosstrad_cur,2)+";\n";
  str+="var AverLosTrad="+DoubleToString(averlosstrad_cur,2)+";\n";
  str+="var NMaxConsWin="+(string)maxconswins_num+";\n";
  str+="var MaxConsWin="+DoubleToString(maxconswins_cur,2)+";\n";
  str+="var NMaxConsLos="+(string)maxconsloss_num+";\n";
  str+="var MaxConsLos="+DoubleToString(maxconsloss_cur,2)+";\n";
  str+="var NAveConsWin="+(string)aveconswins_num+";\n";
  str+="var AveConsWin="+DoubleToString(aveconswins_cur,2)+";\n";
  str+="var NAveConsLos="+(string)aveconsloss_num+";\n";
  str+="var AveConsLos="+DoubleToString(aveconsloss_cur,2)+";\n";
  str+="var ExpPayoff="+DoubleToString(expectpayoff,2)+";\n";
  str+="var AbsDD="+DoubleToString(ddownabs_cur,2)+";\n";
  str+="var MaxDD="+DoubleToString(ddownmax_cur,2)+";\n";
  str+="var RelDD="+DoubleToString(ddownmax_perc,1)+";\n";
  str+="var RecFact="+DoubleToString(recovfactor,2)+";\n";
  str+="var Sharpe="+DoubleToString(sharperatio,2)+";\n";
  str+="var nSymbols="+(string)symbols_num+";\n";
  FileWriteString(fhandle,str);

  str="";br="";
  for(n=0;n<ArraySize(Normal);n++)
    {
    str+=br+"["+DoubleToString(((double)n-16)/4.0,2)+","+DoubleToString(Normal[n],5)+"]";
    br=",";
    }
  FileWriteString(fhandle,"var Normal=["+str+"];\n");

  str="";
  str="[-4.25,0]";
  for(n=0;n<ArraySize(Probab);n++)
    {
    if(Probab[n]>0)
      {
      str+=",["+DoubleToString(((double)n-16)/4.0,2)+","+DoubleToString(Probab[n],5)+"]";
      }
    }
  str+=",[4.25,0]";
  FileWriteString(fhandle,"var Probab=["+str+"];\n");

  str=""; sum=0;
  if(ValTrad.Total()>0)
    {
    sum+=ValTrad.At(0);
    str+="["+(string)(ulong)(TimTrad.At(0)*1000)+","+DoubleToString(sum,2)+"]";
    for(n=1;n<ValTrad.Total();n++)
      {
      sum+=ValTrad.At(n);
      str+=",["+(string)(ulong)(TimTrad.At(n)*1000)+","+DoubleToString(sum,2)+"]";
      }
    }
  FileWriteString(fhandle,"var Prof=["+str+"];\n");
  FileWriteString(fhandle,"var Band=["+Band+"];\n");

  str="";br="";
  for(n=0;n<SymNam.Total();n++)
    {
    str+=br+"{name:\'"+SymNam.At(n)+"\',data:["+(string)nSymb.At(n)+"]}";
    br=",";
    }
  FileWriteString(fhandle,"var Sym=["+str+"];\n");

  FileClose(fhandle);
  }

Comme nous pouvons le constater, le code de script est plutôt lourd, mais cela n’est pas dû à la complexité de la tâche, mais plutôt au grand nombre de caractéristiques de trading, dont la valeur doit être déterminée. Pour le stockage de ces valeurs, le début du script déclare les , variables globales, fournies avec des commentaires pertinents.

La fonction OnStart() vérifie si le terminal est connecté au serveur de trading et, dans le cas contraire, le script termine son travail. En l’absence de connexion au serveur, nous ne serons pas en mesure de définir un compte actif et d’obtenir des informations à ce sujet.

L’étape suivante est le calcul de la date à partir de laquelle les données de trading pour le compte actif courant seront incluses dans le rapport. Comme date de fin, nous utilisons la valeur de la date et l’heure actuelles au moment de l’exécution du script. Le nombre de jours, inclus dans le rapport, peut être défini lors du chargement du script en modifiant le paramètre d’entrée « Nombre de jours », qui est par défaut égal à 30 jours. Une fois que nous avons défini l’heure de début et de fin du rapport, dans la variable de chaîne Band, une paire de valeurs de temps, correspondant au début et à la fin du week-end, est formée. Ces informations sont utilisées de manière à ce que sur le tableau de balance, les intervalles de temps, correspondant au samedi et au dimanche, puissent être marqués en jaune.

Ensuite, à l’aide de la fonction HistorySelect(), l’historique des deals et des commandes pour un intervalle indiqué devient disponible, et en appelant la fonction HistoryDealsTotal(), nous déterminons le nombre de deals dans l’historique. Après cela, en fonction du nombre de deals, un cycle est organisé, qui rassemble les statistiques nécessaires au calcul des caractéristiques de trading, et à la fin du cycle, leurs valeurs sont déterminées.

Lorsque nous avons créé le script, notre tâche était de préserver la signification des caractéristiques de trading conformément au rapport généré dans MetaTrader 5. Il est admis que les caractéristiques, calculées par le script, doivent correspondre à la description, qui est donnée dans le fichier d’aide du terminal. 

Les informations sur l’accès à l’historique du compte et les calculs des caractéristiques de trading peuvent être trouvées dans les articles suivants:

La majorité des caractéristiques sont calculées assez facilement, donc dans cet article, nous n’examinerons pas les opérations associées au calcul de chaque caractéristique, et nous n’examinerons en outre que les différences existantes par rapport au rapport standard et à ses suppléments.

Dans le rapport, qui est généré par le terminal, le tableau de balance est construit par un affichage successif des valeurs pour chaque fois qu’il change, et l’échelle X reflète le nombre de ces changements. Dans notre cas, pour la construction du graphique, nous utilisons une échelle de temps.

Par conséquent, le graphique des bénéfices est très différent du graphique, généré par le terminal. Nous avons choisi cette option de construction de graphique afin d’afficher l’heure de clôture des positions sur une échelle de temps réel. Par conséquent, nous pouvons constater quand l’activité de négociation a augmenté ou diminué au cours de la période de déclaration.

Lors de la construction d’un graphique, il faut garder à l’esprit que MQL5 fonctionne avec la valeur de date présentée comme le nombre de secondes écoulées depuis le 1er janvier 1970, tandis que la bibliothèque graphique exige cette valeur comme le nombre de millisecondes depuis le 1er janvier 1970. Par conséquent, les valeurs de date reçues dans le script doivent être multipliées par mille pour être correctement affichées.

Pour stocker la valeur du bénéfice et l’heure de clôture du deal, le script utilise les classes CArrayDouble et CArrayLong de la bibliothèquestandard. Chaque fois qu’un deal subséquent est détecté dans la boucle, des informations le concernant sont placés, à l’aide de la méthode Add(), dans l’élément, qui est ajouté à la fin du tableau. Cela nous permet de contourner la nécessité de déterminer à l’avance le nombre d’éléments requis. La taille du tableau augmente simplement avec le nombre de deals trouvés dans l’historique des deals.

Pour chaque transaction, une vérification est effectuée sur quel symbole elle a été exécutée, tout en conservant le nom du symbole et le nombre de deals effectués sur celui-ci. Tout comme pour le graphique des bénéfices, ces données, lors de l’affichage de l’historique, s’accumulent en les enregistrant dans un élément qui est ajouté à la fin du tableau. Pour stocker le nom du symbole et le nombre de deals, nous utilisons les classes CArrayString et CArrayInt de la bibliothèque standard.

La colonne unique du graphique sera trop large pour le cas si les deals ont été exécutés sur un seul symbole. Afin d’éviter cela, le tableau de données comporte toujours au moins 7 éléments. Les éléments inutilisés ne sont pas affichés sur le diagramme, car ils ont des valeurs nulles et ne permettent donc pas à la colonne de devenir trop large. Pour s’assurer que lorsqu’il y a un nombre plus petit symboles, les colonnes sont placées approximativement au milieu de l’axe X, les éléments insignifiants du tableau sont successivement insérés au début ou à la fin du tableau.

La différence suivante par rapport au rapport standard est la tentative de construire le graphique de probability distribution pour la séquence des valeurs de profit pour chaque deal.

Densité de probabilité

Figure 4. Densité de probabilité

Le plus souvent, ce type de graphique est présenté sous la forme d’un histogramme. Dans notre cas, le graphique de probabilité est créé en construisant un spline, axée sur les valeurs de colonne existantes d’un tel histogramme. Les valeurs calculées de la densité de probabilité sont complétées par à gauche et à droite, en dehors du graphique, avec des valeurs nulles. Ceci est nécessaire pour que le graphique construit par le spline ne soit pas interrompu à la dernière valeur connue et continue au-delà du graphique, en déclinant à zéro.

À titre de comparaison, sur le graphique de densité de probabilité, la couleur grise est utilisée pour mettre en évidence le graphique de la http://en.wikipedia.org/wiki/Normal_distribution la loi, normale,normalisée de telle sorte que la somme de ses lectures soit égale à un, tout comme le graphique, qui a été construit sur les valeurs de l’histogramme. Dans l’exemple de rapport fourni, le nombre de deals n’est pas suffisant pour donner une estimation plus ou moins fiable de la distribution de probabilité des valeurs des trades à profit. Nous pouvons admettre que lorsqu’il y a un grand nombre de deals dans l’histoire, ce graphique aura l’air plus authentique.

Une fois toutes les caractéristiques de trading calculées, la fonction filesave() est appelée à la fin du script. Cette fonction ouvre le fichier de données.txt, dans lequel les noms et les valeurs des variables sont enregistrés dans un format texte. Les valeurs de ces variables correspondent aux paramètres calculés, et leurs noms correspondent aux noms, qui sont utilisés dans le fichier HTML lors du transfert des paramètres vers les fonctions de la bibliothèque graphique.

Afin de réduire le nombre d’accès au disque pendant l’écriture du fichier, les lignes courtes sont fusionnées en une ligne plus longue, et ce n’est qu’alors qu’elles sont enregistrées dans le fichier. Le fichier de données.txt, comme il est coutumier dans MetaTrader 5, est créé dans le catalogue MQL5\Files; si ce fichier existe déjà, il est écrasé. Pour plus de commodité, vous pouvez copier le fichier ProfitReport.htm dans ce catalogue et l’exécuter à partir de là.

Dans le terminal MetaTrader 5, lors de l’enregistrement d’un rapport au format HTML, il est automatiquement ouvert par un navigateur, qui est enregistré comme navigateur par défaut. Cette possibilité n’a pas été implémentée dans l’exemple fourni dans cet article.

Pour ajouter une lecture automatique, insérez les lignes suivantes au début du script ProfitReport.mq5

#import "shell32.dll"
int ShellExecuteW(int hwnd,string lpOperation,string lpFile,string lpParameters,
                  string lpDirectory,int nShowCmd);
#import

et à la fin, après un appel à la fonction filesave(), ajoutez

string path=TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL5\\Files\\ProfitReport.htm";
ShellExecuteW(NULL,"open",path,NULL,NULL,1);

Si le fichier ProfitReport.htm existe dans le chemin d’accès indiqué dans la variable, lorsque la fonction ShellExecuteW() est appelée, elle sera ouverte par un navigateur. La fonction ShellExecuteW() se trouve dans la bibliothèque système shell32.dll, la déclaration de cette fonction est ajoutée au début du fichier pour y donner accès.


Conclusion

L’utilisation de navigateurs WEB nous permet d’afficher beaucoup d’informations différentes en même temps, ce qui peut être utile, par exemple, dans l’organisation du contrôle visuel sur l’état interne des modules individuels de l' Expert Advisor, en cours d’exécution dans le terminal client.

Les données de gestion du capital, les signaux de trading, l’arrêt de suivi et d’autres données de modules peuvent être facilement et simultanément affichés. Les rapports HTML multi-pages peuvent être utilisés s’il est nécessaire d’afficher trop d’informations.

Il convient de noter que les capacités du langage JavaScript sont beaucoup plus larges que le simple dessin de graphiques. En utilisant ce langage, nous pouvons créer des pages WEB véritablement interactives. Sur Internet, vous pouvez trouver un grand nombre de codes JavaScript prêts à l’emploi, inclus dans la page WEB, et divers exemples de l’utilisation de ce langage.

Par exemple, le terminal peut être directement géré à partir de la fenêtre du navigateur si l’échange bidirectionnel de données entre le terminal et le navigateur est organisé.

Nous espérons que la méthode, décrite dans cet article, sera utile.


Dossiers

JS_Lib.zip - highcharts.js et jquery.min.js
librariesTest.zip - highcharts.js, jquery.min.js et Test_01.htm
Exemple1.zip - highcharts.js, jquery.min.js, Example1.htm, Example1.mq5 et exdat.txt
Exemple2.zip - Exemple2.htm et exdat.txt
Rapport.zip - ProfitReport.htm et data.txt
ProfitReport.mq5 - Script pour la collecte de statistiques et la création du fichier de data.txt

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

Fichiers joints |
js_lib.zip (53.99 KB)
test.zip (54.53 KB)
example1.zip (55.31 KB)
example2.zip (54.3 KB)
report.zip (57.25 KB)
profitreport.mq5 (17.12 KB)
Implémentation  d'Indicateurs en tant que Classes par des Exemples de Zigzag et d' ATR Implémentation d'Indicateurs en tant que Classes par des Exemples de Zigzag et d' ATR
Le débat sur une manière optimale de calculer les indicateurs est sans fin. Où devrions-nous calculer les valeurs de l'indicateur - dans l'indicateur lui-même ou intégrer toute la logique dans un Expert Advisor qui l'utilise ? L'article décrit une des variantes de déplacement du code source d'un indicateur personnalisé iCustom directement dans le code d'un Expert Advisor ou d'un script avec optimisation des calculs et modélisation de la valeur prev_calculated.
Le Lecteur de Trading Axé sur l'Historique des Deals Le Lecteur de Trading Axé sur l'Historique des Deals
Le lecteur de trading Seulement quatre mots, aucune explication n'est nécessaire. Des pensées sur une petite boîte avec des boutons vous viennent à l'esprit. Appuyez sur un bouton - Ca lit, déplacez le levier - la vitesse de lecture change. En réalité, c'est assez similaire. Dans cet article, je souhaite montrer mon élaboration qui lit l'historique du trade presque comme en temps réel. L'article couvre certaines nuances de la POO, en travaillant avec des indicateurs et en gérant des graphiques.
Marche Aléatoire et l’Indicateur de Tendance Marche Aléatoire et l’Indicateur de Tendance
Marche Aléatoire ressemble beaucoup aux données réelles du marché, mais elle présente des caractéristiques importantes. Dans cet article, nous examinerons les propriétés de Marche Aléatoire, simulées à l’aide du jeu de lancer de pièces. Pour étudier les propriétés des données, l’indicateur de tendance est élaboré.
Moving Mini-Max : un nouvel indicateur pour l'analyse technique et son implémentation en MQL5 Moving Mini-Max : un nouvel indicateur pour l'analyse technique et son implémentation en MQL5
Dans l'article suivant, je décris un processus d’implémentation de l'indicateur Moving Mini-Max basé sur un article de Z.G.Silagadze « Moving Mini-max : un nouvel indicateur pour l'analyse technique ». L'idée de l'indicateur est basée sur la simulation des phénomènes d'effet tunnel quantique, proposée par G. Gamov dans la théorie de la désintégration alpha.