English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
preview
Sviluppare un Expert Advisor per il trading da zero (Parte 15): Accesso ai dati sul web (I)

Sviluppare un Expert Advisor per il trading da zero (Parte 15): Accesso ai dati sul web (I)

MetaTrader 5Integrazione | 30 gennaio 2023, 09:28
646 0
Daniel Jose
Daniel Jose

Introduzione

MetaTrader 5 è la piattaforma più versatile e completa che un trader possa desiderare. Nonostante altre opinioni, la piattaforma è estremamente efficace e potente, in quanto offre opportunità che vanno ben oltre la semplice osservazione del tracciato grafico, con operazioni di acquisto e vendita in tempo reale.

Tutta questa potenza deriva dal fatto che la piattaforma utilizza un linguaggio quasi uguale a quello più potente attualmente esistente - stiamo parlando di C/C++. Le possibilità che questo linguaggio ci offre vanno ben oltre ciò che i normali trader senza competenze di programmazione sono in grado di eseguire o comprendere.

Durante le operazioni sul mercato, dobbiamo essere in qualche modo connessi a varie questioni coinvolte a livello globale. Non possiamo semplicemente attenerci al grafico - è importante tenere conto di altre informazioni correlate che non sono meno rilevanti e che possono essere un fattore decisivo e fare la differenza tra vincere e perdere un trade.

Ci sono molti siti Web e luoghi sul Web, con un'enorme quantità di informazioni. Quello che devi sapere è dove cercare e come utilizzare nel modo migliore queste informazioni. Meglio sei informato durante il periodo giusto, meglio è per il trading. Tuttavia, se hai intenzione di utilizzare un browser, qualunque esso sia, scoprirai che è molto difficile filtrare bene determinate informazioni, che sei costretto a guardare molte schermate e monitor, e alla fine, sebbene le informazioni siano lì, è impossibile usarle.

Ma grazie a MQL5, che è molto vicino a C/C++, i programmatori possono fare molto di più che lavorare solo con un grafico così com'è: possiamo cercare, filtrare, analizzare i dati sul web e quindi eseguire operazioni in modo più coerente, rispetto alla maggior parte dei trader perché utilizzeremo tutta la potenza di calcolo a nostro favore.


1.0. Pianificazione

La parte progettuale è fondamentale. Innanzitutto, è necessario cercare dove prenderemo le informazioni che desideriamo utilizzare. Questo dovrebbe in realtà essere fatto con molta più cura di quanto possa sembrare, poiché una buona fonte di informazioni ci indicherà la giusta direzione. Tutti dovrebbero eseguire questo passaggio individualmente poiché ogni trader potrebbe aver bisogno di alcuni dati specifici in momenti diversi.

Indipendentemente dalla fonte scelta, quello che faremo dopo sarà fondamentalmente lo stesso per tutti, così questo articolo può servire come materiale di studio per coloro che desiderano utilizzare il metodo e gli strumenti che sono disponibili utilizzando solo MQL5, senza alcun programma esterno.

Per illustrare l'intero processo, utilizzeremo una pagina web di informazioni di mercato per mostrare come funziona l'intera cosa. Passeremo attraverso tutte le fasi del processo e sarai in grado di utilizzare questo metodo adattandolo alle tue esigenze specifiche.


1.0.1. Sviluppo di un programma di cattura

Per iniziare a lavorare con i dati, dobbiamo creare un piccolo programma per raccogliere dati ed essere in grado di analizzarli in modo efficiente e accurato. A tale scopo, utilizzeremo un programma molto semplice mostrato di seguito:

#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnStart()
{
        Print(GetDataURL("https://tradingeconomics.com/stocks"));
}
//+------------------------------------------------------------------+
string GetDataURL(const string url, const int timeout = 750)
{
	string headers;
	char   post[], charResultPage[];
	int    handle;
   
	if (WebRequest("GET", url, NULL, NULL, timeout, post, 0, charResultPage, headers) == -1		return "Bad return";
	if ((handle = FileOpen("url.txt", FILE_WRITE | FILE_BIN)) != INVALID_HANDLE) 
        { 
                FileWriteArray(handle, charResultPage, 0, ArraySize(charResultPage)); 
                FileClose(handle); 
        }else
                return "Error saving file ...";
                
	return "File saved successfully...";
}

Questo programma è estremamente semplice, niente potrebbe essere più semplice.

Facciamo così: nella parte evidenziata indichiamo il sito da cui vogliamo ricevere informazioni. Perché stiamo usando questo e non il browser? Bene, è vero che possiamo acquisire informazioni nel browser, ma le useremo affinchè ci aiutino a trovare informazioni dopo aver scaricato i dati.

Ma è inutile solo digitare e compilare questo programma. C'è qualcos'altro che dovresti fare, altrimenti non funzionerà.

Nella piattaforma MetaTrader, prima di eseguire questo script, dobbiamo consentire alla piattaforma di ricevere i dati dal sito desiderato. Per evitare di farlo ogni volta che devi installare la piattaforma MetaTrader, puoi salvare una copia di backup di questi dati dopo che tutto è stato configurato. Il file deve essere salvato nel seguente percorso:

C:\Users\< USER NAME >\AppData\Roaming\MetaQuotes\Terminal\< CODE PERSONAL >\config\common.ini

USER NAME è il tuo nome utente nel sistema operativo. CODE PERSONAL è il valore che la piattaforma crea durante l'installazione. Pertanto, puoi facilmente trovare il file per fare un backup o sostituirlo dopo una nuova installazione. Solo un appunto: questo posto appartiene al sistema WINDOWS.

Ora torniamo allo script che abbiamo creato. Se lo usi senza una configurazione precedente, vedrai quanto segue nella finestra dei messaggi.

Questo messaggio è stato visualizzato perché non abbiamo autorizzato il sito web nella piattaforma MetaTrader. Questo dovrebbe essere implementato come mostrato nella figura seguente. Presta attenzione a ciò che è stato aggiunto. Notare che è l'indirizzo principale del sito a cui accederemo tramite la piattaforma di trading MetaTrader.

          

Ora, se eseguiamo nuovamente lo stesso script, vedremo il seguente output riportato dalla piattaforma:

Significa che l'accesso al sito è andato a buon fine, i dati sono stati scaricati sul tuo computer e ora puoi analizzarli. Un dettaglio importante è che ora non dobbiamo preoccuparci di aggiungere nuovamente lo stesso sito alla piattaforma, naturalmente a condizione che si crei un backup di questo file nel percorso mostrato sopra.

Per capire come funzionerà il tutto e per ottenere informazioni più dettagliate, puoi dare un’occhiata alla funzione WebRequest nella documentazione. Se vuoi approfondire ancora di più il protocollo di comunicazione di rete, ti consiglio di guardare le altre funzioni di rete, presenti in MQL5. Conoscere tali funzioni a volte può farti risparmiare molte fatiche.

Abbiamo completato, la prima parte del lavoro è fatta — abbiamo avuto modo di scaricare i dati dal sito desiderato. Ora dobbiamo passare al passaggio successivo, che non è meno importante.


1.0.2. Ricerca dei dati

Per tutti quelli che non sanno come cercare i dati da catturare tramite la piattaforma MetaTrader 5 all'interno di un sito web, ho realizzato un breve video, dove dimostro velocemente come procedere con questa ricerca.

È importante che tu sappia come utilizzare il tuo browser per analizzare il codice del sito Web da cui desideri ottenere i dati. Non è difficile, poiché il browser stesso aiuta molto in questo compito. Ma è qualcosa che devi imparare a fare. Una volta capito come farlo, ti si apriranno molte possibilità.

Utilizzerò Chrome per la ricerca, ma puoi utilizzare qualsiasi altro browser che offre l'accesso al codice utilizzando gli strumenti per sviluppatori.



Una volta appreso cosa cercare, dove cercare e come accedere alle informazioni desiderate, apri il file che hai scaricato dal sito, utilizzando la piattaforma MetaTrader e inizia a cercare i dati di cui hai bisogno.

Siamo interessati ad ottenere dati da questo blocco mostrato di seguito, che è lo stesso blocco che stavo guardando nel video qui sopra. È davvero importante sapere come cercare le cose usando il browser, altrimenti ti perderai in tutte queste informazioni scaricate.

Ma in alcuni casi, guardare i dati in questo modo potrebbe non essere sufficiente. Dobbiamo ricorrere a un editor esadecimale per sapere esattamente con cosa abbiamo a che fare. È vero che in alcuni casi la modellazione dei dati è relativamente semplice, ma in altri casi può essere molto più complessa, quando i dati contengono immagini, collegamenti e altre cose. Queste cose possono rendere difficile la ricerca poiché di solito forniscono falsi positivi, quindi dobbiamo sapere con cosa abbiamo a che fare. Cercando gli stessi dati in un editor esadecimale, otteniamo i seguenti valori.

Non siamo interessati agli offset in questo primo passaggio poiché possono cambiare in caso di pagine dinamiche, ma siamo interessati nel vedere quale tipo di modellazione viene utilizzata. In questo caso è molto chiaro, e possiamo utilizzare un sistema di ricerca basato su questo tipo di informazioni trovate qui nell'editor esadecimale. Ciò rende la ricerca tramite il nostro programma leggermente più semplice da implementare, anche se non è un sistema efficiente in questo primo momento. Il nostro database di ricerca è più facile da accedere - useremo gli input e non useremo caratteri aggiuntivi, come CARRIAGE o RETURN, che in realtà ci ostacolano più che aiutarci. Quindi, il codice del programma è il seguente.

#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnStart()
{
        while (!IsStopped())
        {
                Print(GetDataURL("https://tradingeconomics.com/stocks"));
                Sleep(200);
        }
}
//+------------------------------------------------------------------+
string GetDataURL(const string url, const int timeout = 100)
{
        string  headers, szInfo;
        char    post[], charResultPage[];
        int     handle;
   
        if (WebRequest("GET", url, NULL, NULL, timeout, post, 0, charResultPage, headers) == -1)
                return "Bad return";
   
        szInfo = "";
        for (int c0 = 0, c1 = ArraySize(charResultPage); c0 < c1; c0++) szInfo += CharToString(charResultPage[c0]);
        if ((handle = StringFind(szInfo, "data-symbol=\"INDU:IND\"", 0)) >= 0)
        {
                handle = StringFind(szInfo, "<td id=\"p\" class=\"datatable-item\">", handle);
                for(; charResultPage[handle] != 0x0A; handle++);
                for(handle++; charResultPage[handle] != 0x0A; handle++);
                szInfo = "";
                for(handle++; charResultPage[handle] == 0x20; handle++);
                for(; (charResultPage[handle] != 0x0D) && (charResultPage[handle] != 0x20); handle++) szInfo += CharToString(charResultPage[handle]);
        }
        return szInfo;
}

L'idea dello script è catturare il valore sulla pagina. Il vantaggio del metodo mostrato sopra è che anche se l'informazione cambia posizione a causa di un offset, possiamo ancora trovarla tra tutti quei comandi. Ma anche se tutto sembra ideale, c'è un piccolo ritardo nelle informazioni, quindi è necessario misurare come lavorerai con i dati acquisiti, quando lo script sopra viene eseguito. Il risultato dell'esecuzione può essere visto sotto.

Ti consiglio di condurre la tua analisi e vedere come vengono registrate le informazioni, perché è importante conoscere i dettagli che non sono così facili da descrivere in forma testuale: devi vederli per capire.

Ora pensiamo a quanto segue. Lo script sopra non è molto efficiente in termini di esecuzione, poiché esegue alcune manipolazioni che di fatto non sono necessarie quando si utilizza una pagina con un modello statico. Ma viene utilizzato con contenuti dinamici, come nel caso della pagina che stiamo considerando. In questo caso particolare, possiamo utilizzare l'offset per analizzare più velocemente e quindi catturare i dati in modo un po' più efficiente. Ma ricorda che il sistema può conservare le informazioni nella cache per alcuni secondi. Pertanto, le informazioni acquisite possono essere non aggiornate rispetto ai dati osservati nel browser. In questo caso, è necessario apportare alcune modifiche interne al sistema per correggere questo problema. Ma non è questo lo scopo di questo articolo.

Quindi, modificando lo script sopra in qualcosa che utilizza un offset per eseguire la ricerca, otteniamo il seguente codice, che viene mostrato per intero di seguito:

#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnStart()
{
        while (!IsStopped())
        {
                Print(GetDataURL("https://tradingeconomics.com/stocks", 100, "INDU:IND", 172783, 173474, 0x0D));
                Sleep(200);
        }
}
//+------------------------------------------------------------------+
string GetDataURL(const string url, const int timeout, const string szFind, int iPos, int iInfo, char cLimit)
{
        string  headers, szInfo = "";
        char    post[], charResultPage[];
        int     counter;
   
        if (WebRequest("GET", url, NULL, NULL, timeout, post, 0, charResultPage, headers) == -1)
	        return "Bad return";

        for (int c0 = 0, c1 = StringLen(szFind); c0 < c1; c0++) if (szFind[c0] != charResultPage[iPos + c0]) return "Error in Position";
        for (counter = 0; charResultPage[counter + iInfo] == 0x20; counter++);
        for (;charResultPage[counter + iInfo] != cLimit; counter++) szInfo += CharToString(charResultPage[counter + iInfo]);
        
        return szInfo;
}

Il risultato dell'esecuzione dello script può essere visto più avanti. Non ci sono cambiamenti che impantanano, mentre è solo una questione di tempo di calcolo che si riduce applicando il modello offset. Tutto questo migliora leggermente le prestazioni complessive del sistema.

Tieni presente che il codice sopra ha funzionato solo perché la pagina aveva un modello statico: sebbene il contenuto sia cambiato dinamicamente, il suo design non è cambiato, quindi possiamo usare un editor esadecimale, cercare la posizione delle informazioni, ottenere i valori di offset e navigare diritto verso queste posizioni. Ma per avere qualche garanzia che gli offset siano ancora validi, facciamo un semplice test che viene eseguito nella riga seguente:

for (int c0 = 0, c1 = StringLen(szFind); c0 < c1; c0++) if (szFind[c0] != charResultPage[iPos + c0]) return "Error in Position";

Questo è qualcosa di molto semplice, ma necessario per avere un minimo di sicurezza riguardo alle informazioni che vengono acquisite in base all'offset. Per fare ciò, dobbiamo analizzare la pagina e verificare se è possibile utilizzare il metodo offset per acquisire i dati. Se possibile, beneficerai di un minor tempo di elaborazione.


1.0.3. Un problema da risolvere

Sebbene il sistema spesso funzioni molto bene, può capitare che riceviamo la seguente risposta dal server:

Questa è la risposta del server alla nostra richiesta. Anche se WebRequest non indica alcun errore lato piattaforma, il server può restituire questo messaggio. In questo caso dovremmo analizzare l'header del messaggio restituito per capire il problema. Per risolvere questo problema, è necessario apportare piccole modifiche allo script offset, che puoi vedere di seguito:

#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnStart()
{
        while (!IsStopped())
        {
                Print(GetDataURL("https://tradingeconomics.com/stocks", 100, "<!doctype html>", 2, "INDU:IND", 172783, 173474, 0x0D));
                Sleep(200);
        }
}
//+------------------------------------------------------------------+
string GetDataURL(const string url, const int timeout, const string szTest, int iTest, const string szFind, int iPos, int iInfo, char cLimit)
{
        string  headers, szInfo = "";
        char    post[], charResultPage[];
        int     counter;
   
        if (WebRequest("GET", url, NULL, NULL, timeout, post, 0, charResultPage, headers) == -1
                return "Bad";
        for (int c0 = 0, c1 = StringLen(szTest); c0 < c1; c0++) if (szTest[c0] != charResultPage[iTest + c0])
                return "Failed";
        for (int c0 = 0, c1 = StringLen(szFind); c0 < c1; c0++) if (szFind[c0] != charResultPage[iPos + c0])
                return "Error";
        for (counter = 0; charResultPage[counter + iInfo] == 0x20; counter++);
        for (;charResultPage[counter + iInfo] != cLimit; counter++) szInfo += CharToString(charResultPage[counter + iInfo]);
        
        return szInfo;

Il test viene eseguito nella riga evidenziata è l’unica che esegue il test, poiché quando il messaggio restituito dal server è più complesso, il solo fatto di eseguire questo test ci garantisce già un buon margine di sicurezza sui dati che stiamo analizzando, evitando l'analisi di dati fantasma o immondizia di memoria, se il sistema supera il primo test che esisteva già nel codice precedente. Anche se questo accade raramente, non dobbiamo sottovalutare la probabilità che succeda.

Di seguito puoi vedere che il risultato non è diverso, il che significa che il sistema funziona come previsto.


Finora non abbiamo fatto molto - stiamo solo leggendo i valori da una pagina web, e non è di grande utilità, anche se è abbastanza interessante sapere e vedere come è fatto. Tuttavia, non è molto utile per coloro che vogliono effettivamente fare trading sulla base delle informazioni, che da questo momento in poi modellerai, poiché le catturi e le mostri in un altro modo. Quindi, dobbiamo fare qualcosa in modo che abbia un senso all'interno di un sistema più ampio. Tuttavia, prenderemo queste informazioni acquisite e le porteremo in un EA, in questo modo saremo in grado di fare cose ancora più impressionanti e questo rende MetaTrader 5 una piattaforma sensazionale.


Conclusioni

Bene, questa non è ancora la fine. Nel prossimo articolo, mostrerò come portare queste informazioni raccolte sul WEB all'interno dell’EA, e questo sarà davvero impressionante: dovremo utilizzare risorse poco esplorate all'interno della piattaforma MetaTrader. Quindi, non perderti il prossimo articolo di questa serie.

Tutti i codici utilizzati nell'articolo sono allegati di seguito.


Tradotto dal portoghese da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/pt/articles/10430

File allegati |
Scopri come progettare un sistema di trading tramite Ichimoku Scopri come progettare un sistema di trading tramite Ichimoku
Ecco un nuovo articolo della nostra serie su come progettare un sistema di trading con gli indicatori più comuni, parleremo in dettaglio dell'indicatore Ichimoku e di come progettare un sistema di trading con questo indicatore.
Sviluppare un Expert Advisor per il trading da zero (Parte 14): Aggiunta dei Volumi al Prezzo (II) Sviluppare un Expert Advisor per il trading da zero (Parte 14): Aggiunta dei Volumi al Prezzo (II)
Oggi aggiungeremo altre risorse al nostro EA. Questo interessante articolo può fornire alcune nuove idee e metodi di presentazione delle informazioni. Allo stesso tempo, può assistere a correggere piccoli difetti nei tuoi progetti.
Scopri come progettare un sistema di trading tramite Williams PR Scopri come progettare un sistema di trading tramite Williams PR
Un nuovo articolo della nostra serie sull'imparare a progettare un sistema di trading con gli indicatori tecnici più popolari tramite MQL5 per poterli utilizzare in MetaTrader 5. In questo articolo impareremo come progettare un sistema di trading tramite l'indicatore Williams %R.
Scienza dei Dati e Apprendimento Automatico (Parte 05): Alberi Decisionali Scienza dei Dati e Apprendimento Automatico (Parte 05): Alberi Decisionali
Gli alberi decisionali imitano il modo in cui gli esseri umani pensano nel classificare i dati. Vediamo come costruire alberi e utilizzarli per classificare e prevedere alcuni dati. L'obiettivo principale dell'algoritmo degli alberi decisionali è separare i dati con impurità in nodi puri o vicini.