English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Grafici e diagrammi in HTML

Grafici e diagrammi in HTML

MetaTrader 5Esempi | 17 dicembre 2021, 15:11
689 0
Victor
Victor


Introduzione

Molto probabilmente, MetaTrader 5 è un prodotto completamente autosufficiente e non necessita di estensioni aggiuntive. MetaTrader 5 fornisce la connessione con il broker, mostra le quotazioni, ci consente di utilizzare una varietà di indicatori per l'analisi di mercato e, naturalmente, offre al trader l'opportunità di effettuare operazioni di trading. È abbastanza chiaro che, poiché MetaTrader 5 si focalizza principalmente sul rendere il trading agevole, non può, e tecnicamente non deve, essere uno strumento assolutamente universale, progettato per la ricerca, l'analisi di metodi matematici, la creazione di contenuti multimediali e così via.

Inoltre, l'eccessiva universalità di un prodotto software alla fine porta a una diminuzione della sua efficienza, affidabilità e sicurezza. D'altra parte, in alcuni casi, l'utente potrebbe aver bisogno di alcune funzionalità aggiuntive. In particolare, i trader sono persone con varie aree di competenza e vari percorsi formativi. Pertanto, eventuali funzionalità aggiuntive possono aumentare l'attrattiva della piattaforma di trading, se, ovviamente, vengono raggiunte in modo abbastanza semplice e non a scapito della sua affidabilità e sicurezza.

In questo articolo prenderemo in considerazione uno di questi supplementi, il quale fornisce l'opportunità di creare e mostrare grafici e diagrammi sulla base dei dati ottenuti dal terminale.

Ogni programma deve fare ciò che sa fare meglio. Se aderiamo a questo principio, allora ci affideremo a MetaTrader 5 per il trading con il broker, la raccolta e l'elaborazione delle informazioni in entrata, mentre utilizzeremo un programma diverso, e destinato a questi scopi, per la visualizzazione grafica di queste informazioni.


Il browser

Oggi è difficile trovare un computer che non abbia un browser installato. Da tanto tempo i browser si evolvono e migliorano. I browser moderni sono abbastanza affidabili, stabili nel loro lavoro e, soprattutto, gratuiti. Tenendo conto che il browser è praticamente lo strumento base per accedere a Internet, la maggior parte degli utenti lo conosce e incontra poche difficoltà nell'utilizzarlo.

Le capacità dei browser moderni sono così ampie che ci siamo abituati a guardare video, ascoltare musica, giocare e svolgere una serie di altre attività tramite essi. Pertanto, oggi un browser è uno strumento ben sviluppato per visualizzare diversi tipi di informazioni che possono essere presentate in vari formati.

Non si può non dire che attualmente ci sono diversi browser popolari: InternetExplorer, Mozilla Firefox, Google Chrome e Opera. Questi browser possono differire significativamente l'uno dall'altro nell'implementazione del software e nelle interfacce utente. Tuttavia, in teoria, devono supportare pienamente gli standard di base adottati in rete per lo scambio di informazioni, che riguardano principalmente gli standard del linguaggio HTML.

In pratica, nonostante gli sforzi degli sviluppatori, i browser presentano ancora alcune caratteristiche individuali in termini di implementazione di determinati protocolli o tecnologie. Se decidiamo che un particolare browser, a causa delle sue caratteristiche individuali, non è adatto a noi, questo problema può essere facilmente risolto installando uno o più browser sul nostro computer. Anche gli ardenti sostenitori di browser quali Firefox hanno almeno Internet Explorer installato nei loro sistemi.

Nonostante il fatto che i browser siano stati sviluppati come parte client, fornendo l'interazione con un server remoto, possono anche essere utilizzati per visualizzare le informazioni locali memorizzate sul tuo computer. Un esempio può essere la visualizzazione di pagine web, precedentemente salvate sul tuo computer. Il browser non ha bisogno dell'accesso a Internet per lavorare con le pagine locali.

Pertanto, un browser in esecuzione in modalità offline è un candidato molto interessante per svolgere il ruolo di programma utilizzato per espandere le capacità grafiche del client terminal MetaTrader 5. Per utilizzarlo non è necessario effettuare acquisti costosi, installazioni ingombranti e lunghe, né imparare a utilizzare un nuovo prodotto software.

Pertanto, più avanti in questo articolo discuteremo le possibilità di utilizzare i browser per la costruzione di grafici e diagrammi sulla base dei dati ottenuti su MetaTrader 5.


HTML e JavaScript

Scegliendo di utilizzare un browser come estensione, definiamo la regola di base alla quale d'ora in poi ci atterremo rigorosamente: la visualizzazione delle pagine HTML create deve essere effettuata senza il server web locale o remoto. Ovvero, non installeremo sul nostro computer nessun software e la visualizzazione delle nostre pagine non richiederà un accesso alla rete. Le pagine HTML che creiamo devono essere visualizzate solo tramite il browser e devono trovarsi sul nostro computer. Questa regola ridurrà al minimo il rischio connesso alla possibile riduzione della sicurezza dovuta all'accesso alla rete esterna.

Utilizzando solo le funzionalità di HTML 4 per la visualizzazione delle informazioni, possiamo creare pagine web con tabelle, testo formattato e immagini, ma queste opportunità non possono soddisfarci completamente poiché il nostro obiettivo è costruire grafici e diagrammi a tutti gli effetti, basati sui dati ricevuti da MetaTrader 5.

Nella maggior parte dei casi, ciò che vediamo nel browser quando navighiamo su siti diversi viene creato utilizzando le estensioni dell'HTML. In genere, queste estensioni vengono eseguite lato server e, per questo motivo, non sono adatte ai nostri scopi. Le tecnologie in grado di funzionare lato browser e che non richiedono software, come ad esempio Macromedia Flash, JavaScript e Java, potrebbero risultare interessanti per noi.

Se per l'esecuzione lato browser delle applicazioni Macromedia Flash e Java, avremo bisogno come minimo dell'installazione di plug-in aggiuntivi. Dopodiché i programmi utente, scritti in JavaScript, verranno eseguiti direttamente dal browser. Tutti i comuni browser hanno i propri interpreti JavaScript incorporati. Per evitare di dover installare software o plug-in aggiuntivi, scegliamo JavaScript.

Pertanto, di seguito, utilizzeremo solo MetaTrader 5 con MQL5 e un browser con HTML e JavaScript. Non sarà necessario alcun software aggiuntivo. Va ricordato che una pagina HTML non è altro che un file di testo. Pertanto, per creare un documento HTML, possiamo utilizzare qualsiasi editor di testo. Ad esempio, possiamo creare e modificare il codice HTML su MetaEditor 5. Durante la stesura di questo articolo, la modifica del codice HTML è stata eseguita sul browser Opera @ USB v10.63, il quale consente di modificare il contenuto della pagina, salvare la pagina modificata, e avere un anteprima della sua visualizzazione.

Una persona che non ha familiarità con i linguaggi HTML e JavaScript può giustamente preoccuparsi riguardo alle possibili difficoltà associate alla loro padronanza. Per facilitare il nostro compito ed evitare uno studio approfondito di HTML e JavaScript, cercheremo di utilizzare soluzioni già pronte basate su questa tecnologia. Poiché, nell'ambito di questo articolo, il nostro obiettivo è limitato solo alla costruzione di grafici e diagrammi, utilizzeremo librerie JavaScript pronte, scritte appositamente per questo scopo.

Il Emprise JavaScript Charts è una libreria grafica piuttosto avanzata. Forse il lettore sarà interessato a saperne di più attraverso il link fornito. Tuttavia, questa libreria non è del tutto gratuita. Perciò, spostiamoci su librerie gratuite quali Dygraphs JavaScript Visualization Library e Highcharts charting library. Dygraphs è interessante per la sua compattezza e semplicità, mentre la libreria Highcharts, a sua volta, include una maggiore quantità di funzionalità e sembra più universale. Nonostante il fatto che la libreria Highcharts sia di circa 75 KB e richieda un'ulteriore libreria jQuery, di circa altri 70 KB, la utilizzeremo comunque.

Puoi saperne di più sulla libreria Highcharts sul nostro sito web http://www.highcharts.com/ nella sezione "Demo Gallery". Per ciascuno degli esempi, cliccando su "Visualizza opzioni" è possibile vedere il codice JavaScript sorgente. La documentazione dettagliata sulla libreria si trova nella sezione "Documentation/Options Reference", dove puoi trovare anche molti esempi sull'uso di diverse opzioni. A prima vista, a causa dell'abbondanza del codice JavaScript e della sintassi insolita per un programmatore MQL, l'uso di questa libreria può sembrare piuttosto complicato. Ma non è così. Prendiamo in considerazione il primo esempio: un semplice file HTML che, tramite la libreria, mostrerà il grafico.

Creiamo, come esempio un file di testo denominato Test_01.htm nell'editor del Blocco note e copiamo il seguente semplice esempio di utilizzo della libreria.

<!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>

Il codice di esempio è separato in quattro sezioni dai commenti.

La prima parte superiore del codice contiene i soliti tag delle pagine HTML. Questa parte non è di particolare interesse per noi al momento.

È seguito da un'altra parte, che contiene due tag <script>. Nel primo caso diamo al browser un comando per scaricare dal sito ajax.googleapis.com il codice della libreria jquery.min.js. Il secondo caso presuppone che lato server il catalogo /js/ contenga la libreria highcharts.js, che il browser deve scaricare. Avendo precedentemente deciso che nel processo di visualizzazione delle nostre pagine non deve esserci alcun accesso a fonti esterne, questa parte del codice dovrà essere modificata.

Dopo aver apportato le modifiche, questa parte del codice sarà simile a questa

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

In questo caso, diamo il comando per scaricare entrambe le librerie dal catalogo che contiene il nostro file HTML, cioè dal catalogo corrente. Affinché le librerie possano essere scaricate dal browser, devono prima essere scaricate rispettivamente da ajax.googleapis.com e http://www.highcharts.com e copiate nello stesso catalogo in cui si trova il nostro file HTML. Entrambe queste librerie si trovano anche alla fine dell’articolo, negli allegati.

Nella sezione successiva del codice viene creato un oggetto di classe Highcharts.Chart. Il parametro "renderTo: 'container1'" indica che il grafico verrà visualizzato nell'elemento HTML denominato "container1", mentre il parametro "data" definisce i dati che verranno visualizzati sul grafico. Come possiamo vedere in questo esempio, i dati vengono definiti allo stesso modo dei parametri durante la creazione di un oggetto della classe Highcharts.Chart. Apportando semplici modifiche, individuiamo la definizione dei dati visualizzati in una parte separata del codice. Questo ci permetterà, nel caso in cui abbiamo bisogno di visualizzare più grafici, di raggruppare i loro dati.

Nell'ultima parte del nostro esempio, il tag <div> dichiara un elemento HTML chiamato "container1" e le dimensioni di questo elemento sono indicate. Come accennato in precedenza, questo è l'elemento HTML che verrà utilizzato per costruire il grafico, la cui dimensione sarà determinata dalla dimensione specificata nel tag <div> dell'elemento "contenitore1".

Tenendo conto delle modifiche apportate, il codice del nostro esempio sarà il seguente:

<!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>

Questo test case e tutte le librerie possono essere copiate dagli allegati alla fine dell’articolo. Il file di esempio Test_01.htm e i file delle librerie si trovano nella stessa cartella \Test, quindi sarà sufficiente fare doppio clic sul file HTML Test_01.htm per vedere i risultati del nostro lavoro.

Va tenuto presente che per una normale visualizzazione di questa pagina di test, l'esecuzione di JavaScript deve essere consentita nel browser. Poiché il browser, per motivi di sicurezza, consente di disabilitare tale opzione, può succedere che questa sia disattivata. Di conseguenza, dovremo vedere quanto segue:

Test_01.htm

Figura 1. Test_01.htm 

Questo è il nostro primo grafico di prova e, nonostante l'apparente complessità di questa tecnologia, la sua creazione non ha richiesto molto tempo.

Dobbiamo notare alcune caratteristiche dei grafici visualizzati, creati in questo modo. Nel catalogo copiato, apri il file Test_01.htm e, se il browser ti permette di zoomare sulle pagine visualizzate, noterai che, anche con un ingrandimento consistente, la qualità del grafico non peggiora.

Ciò è dovuto al fatto che questo grafico non è un'immagine statica, come i file PNG o JPEG, e viene ridisegnato dopo aver ingrandito o rimpicciolito l'area assegnata per il suo disegno. Pertanto, tale immagine non può essere salvata su un disco nello stesso modo in cui di solito salviamo un'immagine che ci è piaciuta. Poiché il grafico è stato costruito per mezzo di JavaScript, non dobbiamo dimenticare il fatto che browser diversi con i propri interpreti incorporati di questo linguaggio, potrebbero non eseguirlo sempre allo stesso modo.

I grafici creati utilizzando JavaScript a volte possono apparire diversi quando si utilizzano browser diversi. Molto spesso, queste differenze si verificano più spesso su Internet Explorer rispetto ad altri browser.

Ma speriamo che i creatori di librerie JavaScript si occuperanno della massima compatibilità possibile del loro codice con i browser più popolari.


MetaTrader 5 e MQL5

Nell'esempio sopra, i dati destinati ad essere visualizzati sul grafico sono stati impostati manualmente durante la creazione della pagina HTML. Per organizzare il trasferimento dei dati da MetaTrader 5 nel grafico creato, utilizzeremo il metodo più semplice. Consenti a MetaTrader 5 di registrare i dati in un file separato da cui verranno caricati nel browser quando visualizzi il grafico. Scriviamo un esempio che includa una pagina HTML che mostrerà il grafico scaricando i dati da un file e uno script in MQL5, il quale creerà questo file.

Come file HTML, utilizzeremo il file precedentemente creato Test_01.htm, dopo avergli apportato alcune piccole modifiche. Abbiamo chiamato il file modificato example1.htm. Tutte le modifiche apportate saranno ridotte a:

<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>
che sarà sostituito da
<script type="text/javascript">
var dat1=[0];
</script>
<script src="exdat.txt" type="text/javascript"></script>

Adesso, durante il download della pagina HTML, il browser dovrà caricare anche il file di testo exdat.txt, nel quale i valori destinati a essere visualizzati sul grafico verranno assegnati all'array dat1. Questo file deve contenere un frammento di codice JavaScript. Questo file può essere facilmente creato su MetaTrader 5 utilizzando lo script corrispondente.

Di seguito viene fornito un esempio di tale script.

//+------------------------------------------------------------------+
//|                                                     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);
  }
//+------------------------------------------------------------------+

Per memorizzare i dati visualizzati, questo script utilizza l'array gr[] che contiene 25 elementi. Questo array, ad esempio, viene compilato con i valori della funzione sinusoidale, con l'arrotondamento eseguito fino a quattro cifre decimali. Questo array, ovviamente, può essere riempito con qualsiasi altro dato più utile.

Inoltre, questi dati vengono formattati e combinati in un'unica stringa di testo. Per ridurre il volume del file di testo generato, nella stringa vengono inseriti i valori degli elementi dell'array gr[] con solo quattro punti decimali. A questo scopo abbiamo utilizzato la funzione DoubleToString().

Dopo che la stringa di testo str è stata formata, viene memorizzata nel file exdat.txt. In caso di corretta esecuzione dello script, il file di testo texdat.txt verrà creato nella sottocartella \MQL5\Files del client terminal; se il file esiste già, verrà sovrascritto.

I file jquery.min.js, highcharts.js, Example1.mq5, Example1.htm e exdat.txt sono presentati alla fine di questo articolo nella sezione degli allegati. Questi cinque file si trovano nel catalogo \Example1. Per visualizzare i risultati, è sufficiente copiare questo esempio e aprire il file Example1.htm nel catalogo \Example1. Il grafico sarà costruito in base ai dati del file exdat.txt.

Example1.htm 

Figura 2. Example1.htm

Ovviamente, per eseguire lo script Example1.mq5, questo deve trovarsi nella cartella \MQL5\Scripts del client terminal ed essere compilato.

Come accennato in precedenza, dopo il lancio dello script, il file exdat.txt verrà creato nella cartella \MQL5\Files ma, nel nostro esempio, il file HTML, i file delle librerie e il file di dati devono trovarsi tutti nella stessa cartella. Pertanto, dobbiamo copiare i file jquery.min.js, highcharts.js e Example1.htm nella cartella \MQL5\Files o copiare il file exdat.txt nella cartella in cui si trovano questi file.

In questo esempio, la pagina HTML e le librerie sono archiviate in file diversi. In fase di progettazione, può essere utile che diverse parti del progetto si trovino in file separati. Ciò aiuta ad evitare, ad esempio, modifiche casuali del codice delle librerie durante la modifica del file HTML. Ma dopo che la pagina HTML è stata completamente modificata e non sono previste ulteriori modifiche, le librerie possono essere integrate direttamente nel file di codice HTML.

Questo è possibile perché le librerie JavaScript non sono altro che semplici file di testo. Se apriamo jquery.min.js o highcharts.js con un editor di testo, non vedremo nulla di intelligibile perché il codice sorgente delle librerie è stato compresso alla massima capacità.

La compressione viene eseguita rimuovendo i simboli di servizio, ad esempio un avanzamento riga o una serie di spazi. Dopo tale compressione, si perde qualsiasi formattazione, ma il testo rimane come tale poiché il tipo del file non cambia. Pertanto, non fa differenza se il browser si collega al codice della libreria da un file esterno con estensione .js o se lo legge dal file HTML corrente, che a sua volta è anch’esso in formato testo.

Per combinare i file, sostituisci le righe su Example1.htm

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

insieme a

<script type="text/javascript">

</script>

Successivamente, utilizzando un editor di testo come Blocco note, apriamo il file della libreria jquery.min.js e, scegliendo il comando "Seleziona tutto", copiamo il contenuto del file. Quindi, apri il file Example1.htm, incolla il testo copiato della libreria tra i tag <script type=\"text/javascript\"> e </script>. Salva il file ottenuto come Example2.htm. Allo stesso modo, copia il contenuto della libreria highcharts.js in questo file, inserendolo tra il testo della libreria precedentemente copiata e il tag </script>.

Come risultato, le dimensioni del file HTML aumentano. Tuttavia, adesso non abbiamo bisogno di file separati delle librerie per visualizzarlo correttamente È sufficiente avere il file di dati exdat.txt nella cartella\Example2, che include i file Example2.htm e exdat.txt che si trovano alla fine di questo articolo nella sezione degli allegati.


Un report sulla storia del trading in forma grafica

Per una dimostrazione più completa del metodo di visualizzazione delle informazioni grafiche proposto, creeremo un report che mostra la cronologia del conto di trading in un intervallo di tempo specificato. Il report basato su HTML e che viene creato su MetaTrader 5 quando selezioni il comando "Report" nel menu contestuale della scheda "Cronologia", fungerà da prototipo. Questo rapporto include un gran numero di caratteristiche diverse, riassunte in un'unica tabella. Supponendo che queste caratteristiche siano più visive quando presentate sotto forma di grafici e diagrammi, visualizziamole utilizzando la libreria grafica highcharts.js.

Negli esempi sopra, per la costruzione del grafico abbiamo utilizzato i parametri di visualizzazione predefiniti, impostati in questa versione della libreria highcharts.js.

Ai fini pratici, questa opzione non avrà successo poiché, in ogni caso, dovremo adattare la visualizzazione del grafico per soddisfare le singole esigenze specifiche. A tal fine, la libreria highcharts.js offre un'ampia gamma di opportunità, con un gran numero di opzioni che possono essere applicate al grafico o al diagramma. Come già accennato, l'elenco delle opzioni insieme alle relative descrizioni ed esempi dettagliati, è disponibile all'indirizzo http://www.highcharts.com.

Non ci soffermeremo sulla descrizione delle opzioni della libreria grafica e sulle specifiche del suo utilizzo perché questo articolo ha il solo scopo di suggerire e dimostrare la capacità di utilizzare un browser per la visualizzazione delle informazioni ricevute da MetaTrader 5. Specialmente perché, a seconda dei requisiti specifici per la creazione di una pagina web, si può utilizzare qualche altra libreria JavaScript. Il lettore può selezionare autonomamente la biblioteca più adatta e studiarla tanto approfonditamente quanto la pratica del suo utilizzo richiede.

Per visualizzare la cronologia del conto di trading abbiamo creato il file ProfitReport.htm. Lo troverai negli allegati.  La cartella \Report contiene il file data.txt con i dati da visualizzare. Il file data.txt viene inserito nella cartella come esempio.

Quando copiamo la cartella \Report e apriamo il ProfitReport.htm, vediamo le caratteristiche di trading del conto di prova creato per questo esempio, in forma grafica.

ProfitReport.htm

Figura 3. ProfitReport.htm

Durante la creazione di ProfitReport.htm, abbiamo prima creato un layout di pagina approssimativo e determinato approssimativamente dove e che tipo di informazioni verranno posizionate.

Quindi abbiamo posizionato i grafici con le loro opzioni predefinite nella pagina.

Dopo aver creato questo modello, abbiamo scelto le opzioni più adatte per ogni singolo grafico. Dopo aver completato l'editing, abbiamo semplicemente copiato i testi delle librerie nella pagina. Come già detto, per una corretta visualizzazione della pagina, questa deve trovarsi nello stesso catalogo del file data.txt che contiene i dati destinati alla sua visualizzazione.

Il file data.txt è stato creato su MetaTrader 5, utilizzando lo script ProfitReport.mq5. In caso di corretta esecuzione di questo script, nella cartella \MQL5\Files viene creato il file data.txt, contenente le caratteristiche di trading del conto attualmente attivo.

Non dobbiamo dimenticare che lo script va posizionato nella cartella \MQL5\Scripts e compilato.

//-----------------------------------------------------------------------------------
//                                                                   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);
  }

Come possiamo vedere, il codice dello script è piuttosto macchinoso, ma ciò non è dovuto alla complessità del compito, bensì al gran numero di caratteristiche di trading il cui valore deve essere determinato. Per la memorizzazione di questi valori, l'inizio dello script dichiara le variabili globali con i relativi commenti.

La funzione OnStart() verifica se il terminale è connesso al server di trading e, in caso contrario, lo script termina il suo lavoro. In assenza di connessione al server, non potremo definire un account attivo e ottenere informazioni a riguardo.

Il passaggio successivo riguarda il calcolo della data a partire dalla quale i dati di trading per il conto corrente attivo saranno inclusi nel report. Come data di fine, utilizziamo il valore della data corrente e l'ora corrente al momento dell'esecuzione dello script. Il numero di giorni inclusi nel report può essere impostato durante il caricamento dello script modificando il parametro di input "Numero di giorni", che per impostazione predefinita è pari a 30 giorni. Una volta definito l'orario di inizio e fine del report, nella variabile stringa Band si forma una coppia di valori temporali corrispondenti all'inizio e alla fine del fine settimana. Questa informazione viene utilizzata in modo che sul grafico del bilancio gli intervalli di tempo, corrispondenti a sabato e domenica, possano essere contrassegnati in giallo.

Successivamente, utilizzando la funzione HistorySelect(), diventa disponibile la cronologia delle offerte e degli ordini per un intervallo specificato e, chiamando la funzione HistoryDealsTotal(), determiniamo il numero di operazioni nella cronologia. Successivamente, in base al numero di operazioni, viene predisposto un ciclo che raccoglie le statistiche necessarie per il calcolo delle caratteristiche di trading e, alla fine del ciclo, ne vengono determinati i valori.

Quando abbiamo creato lo script, il nostro compito era preservare il significato delle caratteristiche di trading in conformità con il report generato su MetaTrader 5. Si presume che le caratteristiche calcolate dallo script debbano corrispondere alla descrizione, riportata nel file Help del terminale. 

Le informazioni sull'accesso alla cronologia del conto e sui calcoli delle caratteristiche di trading si trovano nei seguenti articoli:

La maggior parte delle caratteristiche è calcolata abbastanza facilmente, quindi in questo articolo non prenderemo in considerazione le operazioni associate al calcolo di ciascuna caratteristica e terremo ulteriormente conto solo delle differenze esistenti rispetto al report standard e ai suoi supplementi.

Nel report, che viene generato dal terminale, il grafico del saldo è costruito secondo una visualizzazione sequenziale dei valori per ogni variazione e la scala X riflette il numero di tali variazioni. Nel nostro caso, per la costruzione del grafico utilizziamo una scala temporale.

Pertanto, il grafico dei profitti è molto diverso dal grafico generato dal terminale. Abbiamo scelto questa opzione di costruzione di un grafico per visualizzare il tempo di chiusura delle posizioni su una scala in tempo reale. Pertanto, possiamo vedere quando l'attività di trading è aumentata o diminuita nel periodo di riferimento.

Quando si costruisce un grafico, bisogna tenere presente che MQL5 opera con il valore della data presentato come numero di secondi trascorsi dal 1 gennaio 1970, mentre la libreria grafica richiede questo valore come numero di millisecondi dal 1 gennaio 1970. Pertanto, i valori di data ricevuti nello script devono essere moltiplicati per mille per essere visualizzati correttamente.

Per memorizzare il valore del profitto e l'ora di chiusura dell'operazione, lo script utilizza le classi CArrayDouble e CArrayLong della Libreria Standard. Ogni volta che viene rilevata una transazione risultante nel ciclo, le informazioni su di essa vengono inserite nell'elemento che viene aggiunto alla fine dell'array utilizzando il metodo Add(). Questo ci consente di aggirare la necessità di determinare in anticipo il numero richiesto di elementi. La dimensione dell'array aumenta semplicemente con il numero di operazioni presenti nella cronologia.

Per ogni operazione viene effettuato un controllo sul simbolo eseguito, mantenendo il nome del simbolo e il numero di operazioni eseguite su di esso. Proprio come per il grafico dei profitti, quando si visualizza la cronologia, questi dati si accumulano registrandoli in un elemento che viene aggiunto alla fine dell'array. Per memorizzare il nome del simbolo e il numero di operazioni, utilizziamo le classi CArrayString e CArrayInt della libreria standard.

La singola colonna sul grafico sarà troppo ampia nel caso in cui le operazioni siano state eseguite su un simbolo. Per evitare che questo accada, l'array di dati contiene sempre almeno 7 elementi. Gli elementi non utilizzati non vengono visualizzati sul diagramma, poiché hanno valore zero e quindi non consentono alla colonna di diventare troppo ampia. Per assicurarsi che in presenza di un piccolo numero di simboli le colonne siano posizionate approssimativamente al centro dell'asse X, gli elementi insignificanti dell'array sono inseriti in sequenza all'inizio o alla fine dell'array.

La prossima differenza rispetto al report standard è il tentativo di costruire il grafico della probabilità di distribuzione per la sequenza dei valori di profitto per ogni operazione.

Densità di probabilità

Figura 4. Densità di probabilità

Molto spesso questo tipo di grafico è presentato sotto forma di istogrammi. Nel nostro caso, il grafico delle probabilità viene creato costruendo una spline, basata sui valori delle colonne esistenti di tale istogramma. I valori calcolati della densità di probabilità sono integrati da a sinistra e a destra, al di fuori del grafico, con valore zero. Ciò è necessario affinché il grafico costruito dal grafico spline non venga interrotto all'ultimo valore noto e prosegua oltre il grafico, scendendo a zero.

Per fare un confronto, sul grafico della densità di probabilità il colore grigio viene utilizzato per evidenziare il grafico della distribuzione normale, normalizzata in modo tale che la somma delle sue letture sia uguale a uno, proprio come il grafico che è stato costruito sui valori dell'istogramma. Nel report di esempio fornito, il numero di operazioni non è sufficiente per fornire una stima più o meno attendibile della distribuzione di probabilità dei valori delle operazioni di profitto. Possiamo presumere che quando c'è un gran numero di operazioni nella cronologia, questo grafico sembrerà più autentico.

Una volta calcolate tutte le caratteristiche di trading, la funzione filesave() viene chiamata alla fine dello script. Questa funzione apre il file data.txt, nel quale vengono registrati i nomi e i valori delle variabili in formato testo. I valori di queste variabili corrispondono ai parametri calcolati e i loro nomi corrispondono ai nomi utilizzati nel file HTML durante il trasferimento dei parametri alle funzioni della libreria grafica.

Per ridurre il numero di accessi al disco durante la scrittura del file, le righe corte vengono unite in una riga più lunga e solo allora vengono registrate nel file. Il file data.txt, come di consueto su MetaTrader 5, viene creato nel catalogo MQL5\Files; se questo file esiste già, viene sovrascritto. Per comodità, puoi copiare il file ProfitReport.htm in questo catalogo ed eseguirlo da lì.

Nel terminale MetaTrader 5, quando si salva un report in formato HTML, questo viene automaticamente aperto da un browser registrato come predefinito. Questa possibilità non è stata implementata nell'esempio fornito in questo articolo.

Per aggiungere un autoplay, inserisci le seguenti righe all'inizio dello script ProfitReport.mq5

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

e alla fine, dopo aver chiamato la funzione filesave(), aggiungi

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

Se il file ProfitReport.htm esiste nel percorso della variabile specificato, quando viene chiamata la funzione ShellExecuteW(), verrà aperto da un browser. La funzione ShellExecuteW() si trova nella libreria di sistema shell32.dll. La dichiarazione di questa funzione viene aggiunta all'inizio del file per fornire l'accesso.


Conclusione

L'uso dei browser ci consente di mostrare molte informazioni diverse contemporaneamente, le quali possono essere utili, ad esempio, nell'organizzazione del controllo visivo sullo stato interno dei singoli moduli dell’ Expert Advisor in esecuzione nel client terminal.

I dati di gestione del capitale, i segnali di trading, il trailing stop e altri dati dei moduli possono essere visualizzati comodamente e contemporaneamente. I report HTML multipagina possono essere utilizzati se è necessario visualizzare molte informazioni.

Va notato che le capacità del linguaggio JavaScript sono molto più ampie dei grafici disegnati. Usando questo linguaggio, possiamo creare pagine web realmente interattive. Su Internet è possibile trovare un gran numero di codici JavaScript già pronti e inclusi nella pagina web, oltre a vari esempi dell'uso di questo linguaggio.

Ad esempio, il terminale può essere gestito direttamente dalla finestra del browser nel caso di scambio dati bidirezionale tra il terminale e il browser.

Speriamo che il metodo descritto in questo articolo vi sia utile.


File

JS_Lib.zip            - highcharts.js and jquery.min.js
librariesTest.zip   - highcharts.js, jquery.min.js and Test_01.htm
Example1.zip       - highcharts.js, jquery.min.js, Example1.htm, Example1.mq5 and exdat.txt
Example2.zip       - Example2.htm and exdat.txt
Report.zip           - ProfitReport.htm and data.txt
ProfitReport.mq5 - Script for the collection of statistics and the creation of the data.txt file

Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/244

File allegati |
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)
Implementazione degli indicatori come classi mediante esempi di Zigzag e ATR Implementazione degli indicatori come classi mediante esempi di Zigzag e ATR
Il dibattito su un modo ottimale per calcolare gli indicatori è infinito. Dove dovremmo calcolare i valori dell'indicatore? Nell'indicatore stesso o occorre incorporare l'intera logica in un Expert Advisor che lo utilizza? L'articolo descrive una delle varianti dello spostamento del codice sorgente di un indicatore personalizzato iCustom direttamente nel codice di un Expert Advisor o di uno script con ottimizzazione dei calcoli e modellazione del valore prev_calculated.
Il lettore di trading basato sulla cronologia delle operazioni Il lettore di trading basato sulla cronologia delle operazioni
Il lettore di trading. Solo quattro parole, nessuna spiegazione necessaria. Ti viene in mente una piccola scatola con dei pulsanti. Premi un pulsante e inizi a giocare, sposti la leva e la velocità cambia. In realtà, è abbastanza simile. In questo articolo, voglio mostrare ciò che ho sviluppato e che riproduce la cronologia di trading quasi come se fosse in tempo reale. L'articolo tratta alcuni cenni sull’OOP, lavorando con indicatori e gestendo grafici.
Random Walk e l'indicatore di tendenza Random Walk e l'indicatore di tendenza
Random Walk sembra molto simile ai dati di mercato reali, ma ha alcune caratteristiche significative. In questo articolo considereremo le proprietà di Random Walk, simulato utilizzando il gioco del lancio della moneta. Per studiare le proprietà dei dati, viene sviluppato l'indicatore di tendenza.
Moving mini-max: un nuovo indicatore per l'analisi tecnica e la sua implementazione in MQL5 Moving mini-max: un nuovo indicatore per l'analisi tecnica e la sua implementazione in MQL5
Nel seguente articolo descriverò un processo di implementazione dell'indicatore Moving Mini-Max basato su un documento di Z.G.Silagadze "Moving Mini-max: a new indicator for technical analysis". L'idea dell'indicatore si basa sulla simulazione di fenomeni di tunneling quantistico proposta da G. Gamov nella teoria del decadimento alfa.