Come copiare il trading da MetaTrader 5 a MetaTrader 4

Mykola Demko | 11 gennaio, 2022

Introduzione

Non molto tempo fa, molti trader credevano che MetaTrader 5 fosse una piattaforma grezza, inadatta al trading reale. Ma ora, dopo poco tempo, l'opinione pubblica si chiede quando sarà disponibile fare il vero trading. Molti trader hanno già apprezzato i vantaggi implementati in MetaTrader 5. Inoltre, il campionato condotto da MetaQuotes Software Corp. ha aumentato l'interesse degli sviluppatori per il linguaggio MQL5. E ora questo interessante desiderio di essere realizzato sotto forma di profitto dal trading. La stessa domanda "Quando sarà disponibile fare del vero trading?" è data all'indirizzo sbagliato. La sua soluzione dipende dal particolare broker. Sono loro che prendono la decisione finale sul tempo di transizione alla nuova piattaforma.

Cosa può fare un trader solitario in questa situazione? La risposta è ovvia, dovresti utilizzare le opportunità di trading reale fornite da MetaTrader 4, come transito per MetaTrader 5. Cioè scrivere un copista. Il legame tra due MetaTrader 4 non è un'innovazione sul Web. Ora è il momento di implementare tale associazione con MetaTrader 5.


Prologo

Per implementare le idee espresse nell'argomento, è necessario chiarire le domande: "Da dove viene il profitto?" e "Come può un trader controllare la crescita dei profitti?" A prima vista, le risposte sono ovvie. Acquista a buon mercato, vendi a buon mercato. Ma consideriamo le componenti dei profitti. Il profitto è la differenza tra l'acquisto e la vendita, moltiplicata per la scommessa. Cioè, il profitto ha due componenti: le quotazioni e il volume di una posizione di trading.

Cosa può gestire il trader? Quale di questi due componenti è importante nel trading? Ovviamente è il volume di una posizione commerciale. Le quotazioni vengono ricevute dal broker e non possono essere modificate dal trader. Ecco la prima conclusione: per fare una copia del trading, è necessario mantenere in sincronia il volume delle posizioni di trading.


1. Confronto tra le due piattaforme


1.1 Differenze nel sistema contabile

Le piattaforme confrontate hanno diversi sistemi di contabilità commerciale e questo può complicare la questione della copia. Ma non dobbiamo dimenticare che il vantaggio in questo legame è MetaTrader 5. Ciò significa che in MetaTrader 4 abbiamo bisogno di ripetere virtualmente lo stesso sistema di contabilità.

Una posizione di trading in MetaTrader 5 deriva da singoli ordini di trading, che non contraddicono la contabilizzazione degli ordini adottata in MetaTrader 4. Il comune Stop Loss e Take Profit per una posizione può essere implementato inserendo lo stesso Stop Loss e Take Profit per ogni ordine aperto. Differenze significative tra le piattaforme appaiono solo sulla domanda su quale ordine chiudere in MetaTrader 4. Poiché MetaTrader 5 non ha una contabilità separata degli ordini in una posizione commerciale, questo problema potrebbe diventare un ostacolo.


1.2 Volumi delle posizioni commerciali

Consideriamo in dettaglio se c'è qualche differenza quale ordine chiudere. Influirà sul profitto? Ad esempio, abbiamo due ordini aperti in momenti diversi e chiusi allo stesso modo in momenti diversi, ma che esistono insieme da tempo. Cioè, cerchiamo di emulare una posizione di trading nel sistema di contabilità degli ordini.

Calcoliamo diverse varianti di cosa accadrà al profitto se cambiamo i livelli del livello di chiusura degli ordini:

Tipo Volume Livello aperto Chiudi livello
Sell 0.1 1.39388 1.38438
Sell 0.1 1.38868 1.38149

Scriviamo un codice di una calcolatrice:

void OnStart()
  {
   double open1=1.39388,close1=1.38438,
         open2=1.38868,close2=1.38149;
   Print("total  ",n1(profit((open1-close1),0.1)+profit((open2-close2),0.1)));
   Print("order2  pp=",ns(open2-close2),"  profit=",n1(profit((open2-close2),0.1)));
   Print("order1  pp=",ns(open1-close1),"  profit=",n1(profit((open1-close1),0.1)));
  }
string ns(double v){return(DoubleToString(v,_Digits));}
string n1(double v){return(DoubleToString(v,1));}
double profit(double v,double lot){return(v/_Point*lot);}
Ecco il calcolo:
order1  pp=0.00950  profit=95.0
order2  pp=0.00719  profit=71.9
total  166.9

Ora scambiamo i valori di close1 e close2.

order1  pp=0.01239  profit=123.9
order2  pp=0.00430  profit=43.0
total  166.9

Figure 1. Varianti di chiusura dell'ordine

La figura 1 mostra che le aree AB e CD hanno in entrambe le versioni volumi pari a 0,1, mentre BC ha volume pari a 0,2, e non dipende dal fatto che il volume di cui ordini è chiuso.

Nei profitti dei singoli ordini, abbiamo differenze, ma il profitto totale delle posizioni è uguale. Voglio attirare la vostra attenzione sul fatto che questo esempio è stato calcolato per volumi uguali di ordini. Cioè, agli stessi livelli abbiamo implementato la chiusura non di un ordine, ma dello stesso volume. E, se aderiamo rigorosamente al principio della chiusura del volume, non importa quale sia il volume di un ordine. Se il volume di chiusura è maggiore del volume dell'ordine, ci sarà una chiusura parziale.

Quindi, ecco la conclusione principale: per la posizione totale, non importa quale ordine è stato chiuso, l'importante è che i volumi chiusi devono essere uguali a un dato livello.


1.3 Copiare operazioni

Dagli esempi sopra si vede che per ottenere lo stesso profitto non è necessario trasmettere segnali prodotti dall'Expert Advisor scritto in MQL5. Hai solo bisogno di ripetere i volumi delle posizioni di trading. Anche se, per alcuni motivi che verranno discussi in seguito, non sarà un trading del tutto identico. Tuttavia, questi motivi non possono essere un ostacolo al guadagno reale utilizzando un EA redditizio scritto in MQL5.

Il primo motivo per il calo del profitto è la differenza tra virgolette. Con alcuni broker può superare lo spread. Il fatto è che le citazioni vengono tradotte in tempo reale. E quando in MetaTrader 5 un EA decide di aprire una posizione, il broker a cui è collegata MetaTrader 4 può semplicemente avere un prezzo diverso. E il prezzo può essere peggiore o migliore in questo caso.

La seconda ragione per il declino del profitto è il fattore tempo. Una posizione viene copiata dopo che è già apparsa in MetaTrader 5, e quindi il ritardo è inevitabile.

Queste due ragioni mettono in ombra tutte le strategie di scalping. Pertanto, fino a quando il trading reale non sarà disponibile in MetaTrader 5, tali strategie non saranno applicabili.

Il sistema, che implica un profitto (da un'operazione), di gran lunga superiore allo spread e insensibile alle quotazioni di un determinato broker, può essere utilizzato per fare soldi veri utilizzando il copyist di posizione.


2. Impostare il problema

  1. Associazione per passare segnali tra MetaTrader 5 e MetaTrader 4
  2. Traduzione di posizioni da MetaTrader 5
  3. Ricezione di segnali in MetaTrader 4
  4. Ripetizione delle posizioni di trading in MetaTrader 4


2.1. Associazione per passare segnali tra MetaTrader 5 e MetaTrader 4

La prima variante consiste nel trasmettere segnali attraverso un file condiviso. La domanda è: La registrazione frequente sul file non danneggerebbe l'hardware? Se scrivi nuovi dati solo quando una posizione è cambiata, tali record non saranno molto frequenti. Non più frequentemente degli sviluppatori di Windows che apportano modifiche al file di paging. Questa, a sua volta, è una procedura collaudata che non danneggia l'hardware. La scrittura su un file condiviso è un'implementazione accettabile per richieste non molto frequenti. Questa è un'altra limitazione per le strategie di scalping, sebbene meno significativa del limite precedente.

Per il binding, puoi utilizzare la funzione MetaTrader 5 di scrivere sottodirectory a qualsiasi profondità. Non ho verificato che "any", ma sono scritte fino a 10 sottodirectory, questo è sicuro. E non abbiamo bisogno di altro. Puoi certamente usare una DLL per fornire l'accesso, ma non usare la DLL, se il problema può essere risolto senza, è la mia posizione principale. Per risolvere questo problema senza DLL, installa semplicemente MetaTrader 4 nella directory \Files\ del terminale MetaTrader 5 (vedi Lavorare con i file).

Pertanto, il percorso del file condiviso sarà simile al seguente:

C:\Program Files\MetaTrader 5\MQL5\Files\MetaTrader 4\experts\files\xxx      //where xxx is the name of the shared file.

Con questa posizione, il file sarà disponibile sia in MetaTrader 4 che in MetaTrader 5, la possibilità di condivisione di file è fornita dalle funzioni di MQL5.


2.2. Traduzione di posizioni da MetaTrader 5

Per la traduzione delle posizioni e l'uso economico delle risorse, abbiamo bisogno di una funzione che monitori l'aspetto/modifica/chiusura di una posizione di negoziazione per tutti gli strumenti. Sopra è stato riscontrato che per trasferire un trade abbiamo solo bisogno di conoscere il volume di una posizione di trading. Aggiungere al volume il simbolo dello strumento e i livelli SL e TP.

Per tenere traccia delle modifiche abbiamo bisogno di conoscere lo stato precedente di una posizione. E se lo stato precedente e quello presente non sono uguali (e quindi la posizione è cambiata), è necessario visualizzarlo nel file. Abbiamo anche bisogno di una funzione per scrivere queste informazioni nel file. Il file dovrebbe essere aperto in modo che sia disponibile per l'uso simultaneo da più programmi.

Per non perdere il momento della modifica della posizione, il sistema di tracciamento dovrebbe essere implementato nella funzione OnTimer(), perché abbiamo bisogno di tracciare tutti gli strumenti contemporaneamente e i tick arrivano in momenti diversi per simboli diversi. Inoltre dobbiamo inviare un segnale sulla modifica del contenuto del file.


2.3. Ricezione di segnali in MetaTrader 4

È necessario tracciare il segnale di aggiornamento del file. Questo può essere disposto tramite una variabile il cui stato viene monitorato per l'ingresso nella zona di cambio posizione. Abbiamo bisogno di una funzione per leggere un file con lo stato delle posizioni. È solo una funzione standard.

Passare il contenuto del file negli array per il calcolo. Qui abbiamo bisogno del parser. Poiché non verranno passati solo numeri ma anche simboli, è conveniente ricodificare tutto in stringa durante il trasferimento da MetaTrader 5. Inoltre, scrivendo tutti i dati per un simbolo in un'unica stringa di testo, eliminiamo la confusione dei dati.


2.4. Ripetizione delle posizioni di trading in MetaTrader 4

È il più grande insieme di funzioni. Dovrebbe essere diviso in diverse sottoclassi.

  1. Confronto di posizioni virtuali;
  2. Funzione di selezione degli ordini;
  3. Funzione di apertura dell'ordine;
  4. Funzione di chiusura dell'ordine;
  5. Funzione di modifica dell'ordine.


2.4.1. Confronto di posizioni virtuali

Il confronto delle posizioni virtuali è necessario per assicurarsi che le posizioni siano conformi. La funzione dovrebbe calcolare separatamente la posizione per ciascun simbolo ed essere anche in grado di filtrare le posizioni per le quali è vietato il commercio (se presente).

In pratica possono esserci situazioni in cui il broker non ha il simbolo, un segnale per il quale viene passato da MetaTrader 5. Ma questo non dovrebbe bloccare il trading in generale, anche se dovrebbe essere fornito un avvertimento. L'utente ha il diritto di essere informato su tale situazione.


2.4.2. Funzione di selezione degli ordini

Questa funzione deve scegliere gli ordini, a seconda del simbolo, per lavorare ulteriormente con essi. In questo caso, poiché trasmettiamo solo le posizioni aperte, anche gli ordini devono essere filtrati in modo da non avere ordini in sospeso.


2.4.3. Funzione di apertura dell'ordine

Dovrebbe contenere il numero massimo di calcoli. Pertanto, è sufficiente passare il volume e digitare.


2.4.4. Funzione di chiusura dell'ordine

Proprio come il precedente, dovrebbe calcolare tutto prima di dare un comando di chiusura.


2.4.5. Funzione di modifica dell'ordine

La funzione dovrebbe contenere un controllo di vicinanza al mercato. Inoltre, è auspicabile dissolvere nel tempo l'immissione di ordini e livelli di stop, poiché l'inserimento di livelli di stop durante l'apertura non è consentito con tutti i broker. Inoltre, l'apertura congiunta degli ordini e la fissazione di livelli di stop aumenta la probabilità di riquotazione.

Pertanto, la posizione verrà ripetuta rapidamente. E il posizionamento dei livelli di stop è una cosa minore, sebbene non meno importante.


3. Implementazione

I codici sono commentati in dettaglio, quasi riga per riga. Pertanto, nello spiegare i codici, mi soffermerò solo sui momenti più difficili.


Collegamento per passare segnali tra MetaTrader 5 e MetaTrader 4

Il legame è implementato in MetaTrader 5 dalla funzione:

void WriteFile(string folder="Translator positions") // by default it is the name of the shared file

Le bandiere di apertura significano:

FILE_WRITE|FILE_SHARE_READ|FILE_ANSI

il file è aperto per la scrittura | è consentito l'uso condiviso da diversi programmi per la lettura | Codifica ANSI

In MetaTrader 4 il binding è implementato dalla funzione:

int READS(string files,string &s[],bool resize)

Il parametro resize impedisce la ridistribuzione della memoria dell'array di dati ricevuti. Nel codice, la memoria per questa matrice viene allocata ad ogni iterazione, perché uno sviluppatore non può prevedere il numero di righe. Dipende dal numero di simboli selezionati in MetaTrader 5. Pertanto, non può essere calcolato in anticipo in MetaTrader.

Quindi, l'array dovrebbe essere aumentato di uno ad ogni passaggio. Ma questa operazione dovrebbe essere bloccata alla seconda chiamata di funzione, perché la lunghezza dell'array è già definita e non cambierà. A questo scopo usa la variabile bool resize.


Traduzione di posizioni da MetaTrader 5

Per organizzare la traduzione nella funzione OnTimer con la frequenza di 1 sec. i dati su tutte le posizioni vengono ricevuti nella funzione:

void get_positions()

Confrontando quindi il valore precedente delle posizioni con il valore attuale della funzione:

bool compare_positions()

E l'uscita con return(truereturn(true)si verifica nel caso in cui almeno una cella non corrisponda. Exit with return(true) significa che le posizioni non sono uguali e il file deve essere riscritto. Quando si riscrive il file, il contatore cnt_command viene aumentato di uno.


Ricezione di segnali in MetaTrader 4

Dopo aver letto il file utilizzando la funzione READS(), abbiamo un array pieno di stringhe s[].

Affinché queste stringhe si trasformino in informazioni utili, abbiamo bisogno di un parser.

La funzione:

int parser(int Size)

è solo un wrapper per la chiamata della funzione di identificazione della linea:

void parser_string(int x)

La funzione riconosce tutte le celle, tranne i simboli.

Il simbolo viene riconosciuto in un ciclo, una volta all'inizio di un algoritmo utilizzando la funzione:

void parser_string_Symbols(int x)

Successivamente, non applicheremo il codice in MQL5 e parleremo solo del codice in MQL4, a meno che non sia specificamente menzionato.


Confronto di posizioni virtuali

Il confronto delle posizioni è diviso in due parti. Il confronto del volume e del tipo di posizioni è implementato nella funzione:

bool compare_positions()

In questa shell, la chiamata per ottenere lo stato reale delle posizioni è implementata nella funzione:

void real_pos_volum()

e il confronto funziona secondo il suddetto principio "tutto o niente". Significa che se almeno una cella non è la stessa, tutte le posizioni sono considerate diverse. In real_pos_volum() sono implementati un certo numero di filtri, che sono descritti in dettaglio nel codice e verranno usati ripetutamente in altre funzioni.

In particolare, verrà utilizzato per la somma dei volumi di tutti gli ordini su un simbolo in una posizione virtuale. Affinché le posizioni di blocco (se presenti) vengano elaborate correttamente, gli ordini di acquisto avranno il volume con un meno e gli ordini di vendita con un più.

La seconda parte del confronto è confrontare i livelli di stop (i livelli di stop sono Stop Loss e Take Profit), è implementata nella funzione, simile a quella sopra:

bool compare_sl_tp_levels()
Come con i volumi, all'interno della shell c'è una chiamata per ottenere informazioni sui livelli di stop nella funzione:
void real_pos_sl_tp_levels()


Funzione di selezione degli ordini

Gli ordini dovrebbero essere selezionati solo per la chiusura del volume, ecco perché la complicata funzione di selezione specializzata viene implementata solo per la chiusura:

void close_market_order(string symbol,double lot)

Ha i parametri del simbolo e del volume, che dovrebbero essere chiusi. Per evadere il meno possibile gli ordini, nel primo ciclo della funzione, esso ricerca l'ordine il cui volume è uguale all'ordine in perdita passato nel parametro che si sta cercando un warrant, che è uguale al volume con il volume di chiusura passato in il parametro.

Se non esiste un tale ordine (noto dallo stato true del flag di chiusura FlagLot), allora il volume specificato viene chiuso nel primo ordine del ciclo (viene implementato il controllo dell'eccesso del volume dell'ordine nella funzione di chiusura Closes()).

La selezione degli ordini per la modifica dei livelli di stop è implementata nella funzione:

void modification_sl_tp_levels()

Gli ordini vengono filtrati solo dal simbolo, perché tutti i livelli di stop all'interno di un simbolo sono uguali.


Funzione di apertura dell'ordine

È implementato nella seguente funzione:

int open_market_order(string symbol,int cmd,double volume,
                     int stoploss=0,int takeprofit=0,int magic=0)

Contiene tutti i controlli necessari per una comoda apertura di un ordine utilizzando i dati specificati.


Funzione di chiusura dell'ordine

È implementato nella seguente funzione:

bool Closes(string symbol,int ticket,double lot)

Il codice contiene un segno di spunta nel caso in cui il parametro lot superi il volume reale dell'ordine precedentemente selezionato.


Funzione di modifica dell'ordine

È implementato nella seguente funzione:

bool OrderTradeModif(int ticket,string symbol,int cmd,double price,
                    double stoploss=0,double takeprofit=0,int magic=0)

Il codice ha dei controlli, nel caso in cui i livelli di stop non corrispondano al tipo di ordine, i valori verranno scambiati. Controlla anche se i livelli hanno già il valore richiesto.


4. Funzioni della logica

Il piano precedentemente disegnato è finito, ma il codice ha ancora alcune funzioni inspiegabili. Sono le funzioni logiche, possiamo dire che sono le funzioni di base, che guidano il processo.

void processing_signals()
void processing_sl_tp_levels()

Entrambe le funzionalità sono cicli infiniti con uscita con interruzione condizionale. Qui dobbiamo notare che lo script stesso è implementato come un ciclo infinito. Per consentire all'utente di rimuovere comodamente il programma, la condizione principale del ciclo ha la funzione IsStopped() incorporata.

Il codice viene trasferito da un Expert Advisor allo script in loop nel modo seguente:

// Init()
 while(!IsStopped())
    {
     // Start()
     Sleep(1000);
    }
 // Deinit()

L'intera logica dello script è descritta nello stesso ciclo infinito nella funzione standard start().

Il codice del ciclo che si trova in start() sarà simile a questo:

If the trade flow is not busy
          Read the file and save data in an array (not changing the array size);
          if there have been changes in the file
               write new comments;
               remember the time when cycles of compliance check start (located below);
               if the positions whose volumes are being compared are not equal
                    process the positions by volumes;
               if the positions whose stops are being compared are not equal
                    process the positions by stops;
               calculate the end time of checks;
          If time is not exceeded
               make a pause for the remaining time;

Le costruzioni logiche più complesse si trovano nelle funzioni processing_signals() e processing_sl_tp_levels().

Iniziamo a descrivere le funzioni sul principio "dal semplice al complesso". Anche se la chiamata nel codice è l'opposto.

//+------------------------------------------------------------------+
//| processing stop levels                                           |
//+------------------------------------------------------------------+
void processing_sl_tp_levels()
  {
//--- remember the time of entering the cycle   
   int start=GetTickCount();
   while(!IsStopped())
     {
      //--- if the trade flow is not busy
      if(Busy_and_Connected())
        {
         //--- select the order and modify stop levels           
         modification_sl_tp_levels();
        }
      //--- if the delay time is over, update information from the file  
      if(GetTickCount()-start>delay_time)READS("Translator positions",s,false);
      //--- if the update counter has changed in the file, exit the cycle      
      if(cnt_command!=StrToInteger(s[0]))break;
      //--- micro-pause      
      Sleep(50);
      //--- if real stop levels and those in the file are equal, exit the cycle     
      if(!compare_sl_tp_levels())break;
     }
   return;
  }

Come accennato in precedenza, la funzione è un ciclo infinito con l'uscita a due condizioni:

La prima condizione di uscita dal ciclo si verifica nel caso in cui il valore di cnt_command non sia uguale allo stesso valore nel file. Prima di ciò riceviamo le ultime informazioni sul file a condizione che il tempo dell'operazione di ciclo superi il ritardo impostato nella variabile globale delay_time.

Il tempo può essere superato perché tutte le modifiche sono protette dal filtro Busy_and_Connected(). Cioè, entra solo se il flusso commerciale è libero.

Va spiegato qui che nella MetaTrader 4 (a differenza della MetaTrader 5) è impossibile inviare una serie di comandi al server senza avere un requote. Il server può accettare solo la prima richiesta, il resto andrà perso. Pertanto, prima di dare un comando al server, dobbiamo verificare se il flusso commerciale è libero.

Il secondo controllo per uscire dal ciclo è la funzione sopra descritta di confronto di posizione per livelli di stop compare_sl_tp_levels(): se le posizioni sono uguali, allora esci dal ciclo.

Ora passiamo al complesso: la funzione processing_signals () è organizzata in modo simile, ma la parte logica è molto diversa nelle sue funzionalità.

Analizziamo nel dettaglio questa parte:

//--- convert the direction of the position stored in the file to the form -1,+1            
int TF=SymPosType[i]*2-1;
//--- convert the direction of the real position to the form -1,+1
int TR=realSymPosType[i]*2-1;
//--- save the volume of the position stored in the file                     
double VF=SymPosVol[i];
//--- save the volume of the real position 
double VR=realSymPosVol[i];
double lot;
//--- if the positions for the current symbol are nor equal
if(NormalizeDouble(VF*TF,8)!=NormalizeDouble(VR*TR,8))
  {
//--- if the real volume is not equal to zero and the directions are not equal or
//--- if the directions are equal and the real volume is larger than that in the file                              
   if((VR!=0 && TF!=TR) || (TF==TR && VF<VR))
     {
      //--- if the directions are equal and the real volume is larger than that in the file 
      if(TF==TR && VF<VR)lot=realSymPosVol[i]-SymPosVol[i];
      //--- if the real volume is not equal to zero and the directions are not equal
      else lot=realSymPosVol[i];
      //--- close the calculated volume and exit the cycle                  
      close_market_order(Symbols[i],lot);
      break;
     }
   else
     {
      //--- if the directions are equal and the real volume is less than that in the file 
      if(TF==TR && VF>VR)lot=SymPosVol[i]-realSymPosVol[i];
      //--- if the directions are not the same and the volume is equal to zero                  
      else lot=SymPosVol[i];
      //--- open the calculated volume and exit the cycle 
      open_market_order(Symbols[i],SymPosType[i],lot);
      break;
     }
  }

Le variabili TF e TR memorizzano il valore del tipo di posizione sotto forma di buy=-1,sell=1. Di conseguenza, TF è il valore memorizzato nel file e TR è il valore reale della posizione virtuale. Lo stesso vale per i volumi VF,VR.

Quindi la disuguaglianza:
if(VF*TF!=VR*TR)

sarà vero nel caso in cui i volumi o i tipi di posizione non siano uguali.

Poi arriva il connettivo logico:

if((VR!=0 && TF!=TR) || (TF==TR && VF<VR))

il che significa che se il volume reale non è uguale a zero e i tipi non sono uguali, allora dovresti chiudere l'intera posizione.

Ciò include le opzioni quando il volume nel file è zero e l'opzione quando la posizione è invertita nella direzione. Nella variante, quando la posizione è invertita, bisogna prima preparare la posizione per l'apertura, cioè chiudere il volume precedente. Quindi con l'iterazione successiva la logica passa all'altro ramo, all'apertura.

La seconda condizione complessa del connettivo logico significa che se il tipo è corretto, ma il volume reale è maggiore di quello memorizzato nel file, è necessario ridurre il volume reale. A tal fine, abbiamo prima calcolato la dimensione del lotto di cui è necessario ridurre il volume.

Se nessuna condizione di chiusura è adatta a questa situazione e le posizioni (come abbiamo scoperto nel primo filtro) non sono uguali, dovrebbe essere aperto un nuovo ordine. Anche qui ci sono due varianti: per aprire un ordine per l'intera dimensione della posizione nel file o aggiungere agli ordini esistenti. Qui ci tengo a precisare che il controllo per il superamento del limite di volume è disponibile in funzione di apertura, quindi il volume mancante (se non fosse stato possibile con il controllo) verrà aperto alla successiva iterazione dell'algoritmo. A causa del fatto che prima viene gestita la situazione di chiusura, e solo dopo l'apertura, la situazione di chiusura è quasi impossibile.

Vorrei menzionare un sottile codice posto. La situazione di riapertura dell'ordine, che si è appena chiuso in MetaTrader 4, si ferma. Ho detto prima che la discrepanza tra le virgolette è spesso entro i 2-3 punti di 5 cifre. Con lo spread pari a 15 la differenza è insignificante. Ma con questa differenza, se stop loss o take profit si attivavano in MetaTrader 4 prima rispetto a MetaTrader 5, si verificava una situazione in cui l'algoritmo cercava di ricreare la posizione appena chiusa, con la sua successiva rimozione con gli stop attivati in MetaTrader 5.

Non ha portato a grandi perdite, ma uno spread è stato sprecato. Pertanto, l'algoritmo è stato riprogettato in modo tale che dopo la rimozione di una posizione, MetaTrader 4 non la ripristinerà, ma attenderà che lo stato del file cambi. E solo allora ricomincerà a recitare. In questa situazione, il trader può rimuovere manualmente la posizione, se la trova sbagliata. E non verrà ripristinata fino a quando MetaTrader 5 non apporterà modifiche al file.

L'unico punto debole è la rara situazione in cui gli stop di MetaTrader 4 rimuoveranno la posizione e in MetaTrader 5 la posizione non verrà chiusa. In questo caso, posso consigliare di riavviare le posizioni del copista di script. E l'ultima clausola: il codice non controlla il lavoro durante il fine settimana. Non è un grosso problema, ma il registro sarà pieno di riquotazioni inutili.


5. Verifica dell'attuazione nella pratica

Installa MetaTrader 4 nella directory C:\Program Files\MetaTrader 5\MQL5\Files\

Esegui le posizioni compilate di Expert Advisor Translator su qualsiasi grafico in MetaTrader 5 (il lavoro di Expert Advisor non dipende dal grafico su cui è in esecuzione).

Figura 2. Posizioni del traduttore in MetaTrader 5

Vediamo un commento multilinea con lo stato del contatore sulla prima riga e il log di tutte le posizioni riga per riga.

Esegui lo script compilato Copyist positions su qualsiasi grafico in MetaTrader 4 (il lavoro dello script in loop non dipende dal grafico, su cui è in esecuzione).

Figura 3. Posizioni del copista in MetaTrader 4

Quindi possiamo eseguire qualsiasi Expert Advisor in MetaTrader 5 . I risultati della sua operazione verranno rapidamente copiati su MetaTrader 4.

Figura 4. Posizioni e ordini in MetaTrader 4 (in alto) e MetaTrader 5 (in basso)

A proposito, la gestione dell'account in MetaTrader 5 può essere eseguita manualmente oppure è possibile accedere all'account utilizzando la password dell'investitore.

Quindi, ad esempio, puoi avviare il copista su qualsiasi account del campionato.


Conclusione

Questo articolo ha lo scopo di accelerare il passaggio dei trader alla nuova piattaforma e di incoraggiare lo studio di MQL5.

In conclusione vorrei dire che questo codice non può sostituire completamente il trading diretto su un conto reale in MetaTrader 5. È scritto come un codice universale per qualsiasi sistema di trading senza tener conto della logica, quindi, come tutto ciò che è universale, non è perfetto. Ma sulla base di ciò, puoi scrivere un traduttore di segnali per una strategia specifica. Per molti trader che sono lontani dalla programmazione, può servire come fase di transizione in previsione del rilascio.

A chi è esperto di programmazione consiglio di modificare il codice in modo che riconosca gli ordini tramite il loro numero magico e implementi il trasferimento e l'inoltro degli ordini pendenti. L'immissione di ordini in sospeso non influirà sul profitto, a condizione che vi sia una connessione stabile al server. Se la perdita di connessione si verifica spesso, è necessario copiare tutto il percorso del server, inclusi gli ordini in sospeso.

Impara la nuova lingua e usala per sviluppare un sistema robusto. Buona fortuna nel tuo trading.