English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
preview
Sviluppare un Expert Advisor per il trading da zero (Parte 31): Verso il futuro (IV)

Sviluppare un Expert Advisor per il trading da zero (Parte 31): Verso il futuro (IV)

MetaTrader 5Trading | 23 settembre 2024, 13:10
378 0
Daniel Jose
Daniel Jose

Introduzione

Dopo aver rimosso Chart Trade dall'EA nell'articolo "Sviluppo di un EA per il trading da zero (Parte 29)", abbiamo trasformato il pannello Chart Trade in un indicatore. Le modalità di regolazione e manutenzione delle funzioni necessarie per mantenere l'indicatore funzionale sono descritte nella Parte 30. Questo è uno dei possibili approcci, sebbene in realtà esistono altri modi, con i loro vantaggi e svantaggi, ma li considereremo un'altra volta.

Quindi, rimane ancora qualcosa da rimuovere dall'EA. Ora lo rimuoveremo e l'articolo sarà l'ultimo di questa serie. L'elemento da rimuovere è il sistema audio. Questo può creare confusione se non si sono seguiti gli articoli precedenti.

Per capire come sarà l'intero processo (dato che include molte cose che necessitano di una spiegazione), utilizzeremo quasi lo stesso modello basato sull'articolo precedente. Questo renderà la spiegazione semplice e comprensibile anche a chi non è un programmatore professionista. Complicheremo anche un po' il sistema, solo per rendere le cose un po' più vivaci.

Questa volta la novità è il sistema audio. Cesserà di far parte dell'EA. Ma questo fornirà molti vantaggi in futuro. Tuttavia, non abbiamo fretta, perché l'importante è comprendere cosa succederà qui. L'articolo sarà relativamente breve, ma interessante.


Introduzione al servizio audio

Tutti questi cambiamenti possono farvi impazzire. Ma credetemi, l'idea non è di farvi impazzire, beh forse un po' sconcertare, ma di mostrare come a volte piccole modifiche possano fare una grande differenza e rendere l'utilizzo della piattaforma MetaTrader 5 molto più piacevole. Allo stesso tempo, vedrete come tutte queste azioni permettono di modulare le cose.

In questo modo è possibile scegliere ciò che serve e ciò che non serve. Se qualcosa è molto utilizzata, si potranno aggiungere miglioramenti in seguito per rendere la funzionalità ancora più utile e piacevole. Questo non richiederà grandi cambiamenti o la riprogrammazione di ciò che è stato creato tempo fa. L'idea è quella di RIUTILIZZARE SEMPRE.

Una di queste funzionalità è il sistema audio. Potrebbe sembrare che lasciare questo sistema all'interno dell'EA sia una buona idea. In un certo senso, questo sistema non interferisce con il funzionamento dell'EA nel suo complesso. Ma se lo rimuoviamo dall'EA e implementiamo una comunicazione tra loro, vedrete che è possibile utilizzare gli avvisi sonori in modo molto semplice, come se si trattasse di una libreria sonora. Questa soluzione sarà molto utile.

Non ha senso inserire un sistema di allerta solo all'interno di un EA. Può essere utile avere un sistema audio negli indicatori o anche negli script che vengono eseguiti in momenti specifici. Ciò sarà molto utile per l'analisi. In questo modo, la piattaforma MetaTrader 5 può diventare un vero e proprio mostro in termini di analisi, dove è possibile effettuare calcoli enormi per analizzare meglio il mercato in momenti molto specifici, sia che si tratti di entrata che di chiusura della posizione. Tutto questo può essere fatto con un minimo sforzo.

Si potrebbe dire: "Ma posso aggiungere tutti i suoni ad un file MQH (Header File), incorporarli negli eseguibili e ottenere il comportamento richiesto". Sì, è possibile. Ma pensate al seguente scenario: Nel corso del tempo, questo file MQH crescerà e alcuni programmi più vecchi potrebbero diventare incompatibili con questo header file (MQH). Se doveste ricompilare questi vecchi file, incontrereste dei problemi. E se si crea un sistema modulare in cui esiste un protocollo di comunicazione tra i processi, è possibile ampliare le funzionalità della piattaforma pur mantenendo la compatibilità con i programmi più vecchi.

Ecco il motivo di queste modifiche: mostrare come sia possibile creare e utilizzare uno qualsiasi dei percorsi possibili. E lo dimostro togliendo le cose dall'EA, pur mantenendole il più possibile simili al comportamento originale.

Nell'articolo precedente ho mostrato come ricreare Chart Trade in modo che si comporti come quando era integrato nell'EA. Tuttavia, dopo averlo rimosso dall'EA, è stato necessario creare un modo per farlo continuare a lavorare nello stesso modo. Il metodo che vi ho mostrato è uno dei tanti possibili e sebbene non sia il migliore, funziona. Ogni soluzione richiede una comprensione adeguata del funzionamento generale delle cose. A volte, limitarsi ad un solo modello di idea non aiuta a risolvere situazioni specifiche, anzi. Proprio a causa della mancanza di conoscenza, molti pensano che non sia possibile fare qualcosa o dicono che il sistema è limitato, quando in realtà il limite risiede nella mancanza di conoscenza della persona responsabile della pianificazione e dell'implementazione della soluzione.

Lo abbiamo visto quando abbiamo implementato il sistema degli ordini senza utilizzare alcuna struttura per memorizzare i dati. Molti pensavano che fosse una cosa impossibile da fare, che non c'è modo di fare queste cose. Ma ho dimostrato che era possibile. La cosa importante è sapere e comprendere cosa si sta facendo. Il primo passo è conoscere i limiti di ogni tipo di soluzione.

Impariamo quindi a rendere il sistema audio il più modulare possibile, tenendo presente che le sue funzionalità saranno ampliate man mano che il sistema crescerà.

Prima di tutto, non toccheremo la classe C_Sound, tranne nei casi in cui abbiamo bisogno di espanderne la funzionalità. Quindi, non ci saranno grandi cambiamenti in questa classe. In realtà, in questa fase questa classe rimarrà invariata, tuttavia è necessario apportare piccole aggiunte al sistema. La prima è il file header mostrato di seguito:

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


Si potrebbe pensare che utilizzeremo questo file nell'EA, ma no... l'EA non utilizzerà questo file, almeno non ancora. Utilizzerà un altro file che vedremo più avanti.

Dopodiché, possiamo creare un file che sarà il servizio audio. È mostrato nel codice sottostante:

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


Questo servizio controlla le variabili globali della MetaTrader 5. Riprodurrà il suono specificato non appena la variabile il cui nome dichiarato nel file header, viene lanciato da qualsiasi script, EA o indicatore, indipendentemente da quale sia e da quando avvenga.

È sufficiente specificare l'indice del file da riprodurre. In base alla struttura sopra descritta, sarete in grado di riprodurre un totale di 4.294.967.295 suoni differenti, che è il numero solo per i file esterni. Si può avere lo stesso numero di suoni interni, quindi si possono fare molte cose.

Per sapere quale tipo di suono riprodurre, il sistema controlla il valore della variabile u_local.info.i1, se il valore è 0, allora il suono da riprodurre sarà incorporato nel file di servizio e l'indice del suono sarà indicato dalla variabile u_local.info.i0, ma questo valore rappresenta l'enumeratore all'interno della classe C_Sound.

Ora possiamo compilare il servizio ed eseguirlo. Non appena le condizioni di cui sopra sono soddisfatte, il servizio esegue il suo lavoro, ricordando che quando la variabile globale viene catturata dal servizio, viene rimossa per poter essere utilizzata in un altro momento.

Prima di andare avanti, riflettiamo un po'. A differenza dell'indicatore Chart Trade, che comunicherà solo con l'EA, il sistema sonoro può comunicare con qualsiasi tipo di programma della piattaforma MetaTrader 5. Per riprodurre il suono desiderato, è necessario impostare il valore della variabile, che sarà sempre double.

Potreste pensare che sia facile, ma provate e vedrete che non lo è. Inoltre, si dovrà procedere a creare la variabile globale con il nome corretto ogni volta. Pertanto, ogni volta che si desidera riprodurre un suono salvato in precedenza, si dovrà fare un sacco di lavoro.

Ma esiste una soluzione pratica che evita tutti questi problemi. Poiché è piuttosto piacevole, in questa fase iniziale utilizzeremo questa soluzione al suo livello più elementare. Per vedere come si fa, passiamo all'argomento successivo.


Creare una libreria per accedere al servizio audio

Il motivo per cui si crea una libreria è che ci faciliterà la vita in qualche modo. Non importa come, ma ci renderà la vita più facile. Nell'argomento precedente, ho detto che quando un programma accede al servizio audio, non è necessario conoscere il nome della variabile globale che dà accesso al servizio. Per quanto suoni strano, il modo migliore per passare informazioni tra i processi è aggiungere un livello al sistema. Questo livello è la libreria.

Queste librerie "nasconderanno" la complessità della modellazione dei dati tra i processi, in modo che non ci si preoccupi più di quale forma debba assumere la modellazione. Ci si occupa solo delle chiamate stesse e dei risultati attesi.

Quando si crea una libreria ci sono solo due preoccupazioni:

  1. Dichiarare chiaramente le funzioni che verranno esportate.
  2. Nascondere il più possibile la complessità della modellazione interna, in modo che l'utente della libreria non abbia bisogno di sapere cosa sta succedendo. L'utente deve vedere solo i dati in entrata e i risultati in uscita.

Pertanto, qualsiasi procedura o funzione all'interno di una libreria è progettata per avere un comportamento molto semplice dal punto di vista dell'utente. Ma all'interno può esserci un livello estremamente complesso di operazioni che portano ai risultati finali. Ma il programmatore che utilizzerà la libreria non ha bisogno di sapere cosa succede al suo interno. È importante sapere che i risultati vengono forniti correttamente.

Diamo quindi un'occhiata alla nostra libreria che nasconderà la modellazione dei dati utilizzata nel servizio audio. Ogni programma deve segnalare due cose: la prima è se il suono è interno o esterno; la seconda è l'indice del suono. Sembra complicato? Vediamo il codice di queste chiamate all'interno della libreria:

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


Queste due funzioni nascondono qualsiasi complessità nella modellazione dei dati. Notare che stiamo usando la parola chiave export, che indica al compilatore di creare un collegamento simbolico a queste funzioni. Si tratta in realtà di procedure, perché non restituiscono alcun valore. In questo modo saranno visibili all’esterno del file, come se questo fosse una DLL.

Ma se si esamina il codice, non si trova alcuna funzione chiamata Sound. Dove si trova? Si trova nella libreria stessa, ma non sarà visibile al di fuori di essa. Guarda il codice completo della libreria qui sotto:

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


Notare che la procedura Sound conterrà tutta la complessità necessaria richiesta per assemblare il valore adeguato, in modo che il servizio possa eseguire il compito richiesto da uno script, un indicatore o un EA. Ma invece di inserire questo codice all'interno del programma che accederà al servizio, useremo solo chiamate semplificate, il che rende il debug del programma più comodo e meno faticoso.

Per capire come funziona, vediamo un esempio di script:

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


Guardate il codice qui sopra. Non è necessario sapere che tipo di comunicazione è stata implementata, dove e quando avverrà l'evento sonoro — può avvenire ovunque, all'interno della piattaforma, del sistema operativo o anche in remoto, non importa. L'unica cosa che dobbiamo sapere è se il suono è interno o esterno al sistema e il suo indice.

Ora, prima di continuare, voglio che facciate un esperimento. Scambio di funzioni. In questo caso si esegue Sound_WAV e poi Sound_Alert. Eseguitelo e vedete il risultato. Poi, cambiate l'ordine: eseguite Sound_Alert, poi Sound_WAV e vedete il risultato. Per chi non avesse capito, il codice all'interno dell'evento OnStart sarebbe simile a questo nella prima situazione:

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


E così nel secondo caso:

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


Anche se può sembrare sciocco, questo esperimento è necessario per capire alcune cose. Non ignoratelo, sarà interessante vedere i risultati.

Ora che abbiamo visto cosa dovremmo aggiungere ai nostri programmi per poter riprodurre i suoni, dobbiamo semplicemente aggiungere il seguente codice:

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


Ogni volta che è necessario riprodurre un suono, basta utilizzare la funzione giusta con il valore giusto, senza preoccuparsi di come verrà eseguito. Il sistema stesso si assicurerà che tutto funzioni perfettamente. Nel nostro EA, il codice sarà questo:

// ...

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

// ...

La domanda sorge spontanea: Cosa fa il codice evidenziato? Non possiamo semplicemente usare la libreria? Sì, ma si può utilizzare un'enumerazione per identificare i codici numerici dei suoni, come si faceva prima, e a meno che non si utilizzi un numero molto basso di suoni o di avvisi, può essere molto difficile capire cosa rappresenta ognuno di essi solo guardando il codice. Per questo motivo, il file header Sound.mqh ha ricevuto un'aggiunta che è evidenziata nel codice sottostante:

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


Quindi, possiamo ritrovarci con un codice come questo:

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

// ... The rest of the function

È molto più rappresentativo dello stesso codice che utilizza indici invece di enumerazioni:

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

// ... Rest of the code


Quale dei due è più facile da capire?

Dopo tutto questo lavoro, avrai il flusso di informazioni nella piattaforma come quello mostrato nella figura seguente:

Come si può notare, indipendentemente da chi fornisce il segnale, avremo sempre la stessa destinazione.


Conclusioni

Anche se non sembra una cosa importante, quanto illustrato in questo articolo contribuisce ad aumentare l'usabilità del vostro codice, dei programmi e delle informazioni. Quando si inizia a programmare sempre meno e si diventa sempre più produttivi, allo stesso tempo il codice diventa più sicuro e stabile, poiché il riutilizzo e i test vengono ripetuti in molti scenari differenti.

Qui abbiamo visto un altro percorso, diverso da quello visto nell'articolo precedente, ma anche questo può essere migliorato molto, offrendoci una pletora di nuove possibilità. Ma questo lo vedremo in un'altra serie, dove imparerete a rendere i vostri programmi e progetti in MetaTrader 5 molto più modulari, con un livello di sicurezza, usabilità e stabilità molto più elevato rispetto a qualsiasi metodo mostrato qui.

Ma la cosa principale e più importante è sapere come progettare e utilizzare alcune soluzioni differenti, perché ci sono casi in cui una soluzione è migliore di un'altra, per un motivo o per l'altro.

Tutti i codici sono disponibili nel file allegato. A chi non è molto abituato a questo modo di programmare, utilizzando le librerie, consiglio di studiare bene questa fase dello sviluppo di EA. Non rimandate a domani ciò che potete fare oggi, perché il domani potrebbe non arrivare come vi aspettate.

Questo articolo completa la fase di sviluppo dell'EA. Presto presenterò un altro tipo di materiale, incentrato su un altro tipo di situazione, in cui il livello di complessità coinvolto è molto più alto, ma comunque notevolmente più interessante. Un abbraccio a tutti e a presto.


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

File allegati |
EA_-_j_Parte_31_f.zip (14533.52 KB)
Multibot in MetaTrader: Avvio di più robot da un singolo grafico Multibot in MetaTrader: Avvio di più robot da un singolo grafico
In questo articolo, prenderò in considerazione un semplice modello per la creazione di un robot MetaTrader universale che può essere utilizzato su più grafici, pur essendo allegato a un solo grafico, senza la necessità di configurare ogni istanza del robot su ogni singolo grafico.
Sviluppare un Expert Advisor da zero (Parte 30): CHART TRADE come indicatore? Sviluppare un Expert Advisor da zero (Parte 30): CHART TRADE come indicatore?
Oggi utilizzeremo nuovamente Chart Trade, ma questa volta si tratterà di un indicatore su grafico che può essere presente o meno sul grafico.
Gli Swap (Parte I): Posizioni di Blocco e Sintetiche Gli Swap (Parte I): Posizioni di Blocco e Sintetiche
In questo articolo cercherò di ampliare il concetto classico dei metodi di swap trading. Spiegherò perché sono giunto alla conclusione che questo concetto merita un'attenzione particolare ed è assolutamente da studiare.
Sviluppare un Expert Advisor per il trading da zero (Parte 29): La piattaforma parlante Sviluppare un Expert Advisor per il trading da zero (Parte 29): La piattaforma parlante
In questo articolo scopriremo come far parlare la piattaforma MetaTrader 5. E se rendessimo l'EA più divertente? Il trading sui mercati finanziari è spesso troppo noioso e monotono, ma possiamo rendere questo lavoro meno faticoso. Notare che questo progetto può essere pericoloso per chi ha problemi di dipendenza. Tuttavia, in generale, rende le cose meno noiose.