Sistemi Esperti: MQL5 Programming for Traders – Source Codes from the Book. Parte 7

 

MQL5 Programming for Traders – Source Codes from the Book. Parte 7:

La settima parte finale del libro discute le funzionalità avanzate dell'API MQL5, che saranno utili durante lo sviluppo di programmi per MetaTrader 5. Questi includono simboli finanziari personalizzati, eventi del calendario economico integrato e tecnologie generiche come reti, database e crittografia.

MQL5 Programming for Traders – Source Codes from the Book. Parte 7

Autore: MetaQuotes

 
Buone risorse di apprendimento
 
Imparare
 
Ecco piccole correzioni e miglioramenti per la cache e il filtro del calendario.
MQL5 Book: Advanced language tools / Economic calendar / Transferring calendar database to tester
MQL5 Book: Advanced language tools / Economic calendar / Transferring calendar database to tester
  • www.mql5.com
The calendar is available for MQL programs only online, and therefore testing news trading strategies poses some difficulties. One of the solutions...
File:
 

Potete dirmi se si tratta di un errore o se non ho capito qualcosa?

File MarginProfitMeter.mqh.

// Convertire l'importo del denaro "corrente" in denaro "conto".
bool Convert(const string current, const string account,
             const bool ask, double &margin, const datetime moment = 0)
  {
   string rate;
   int dir = FindExchangeRate(current, account, rate);
   if(dir == +1)
     {
      margin *= moment == 0 ?
                SymbolInfoDouble(rate, ask ? SYMBOL_BID : SYMBOL_ASK) :
                GetHistoricPrice(rate, moment, ask);
     }
   else
      if(dir == -1)
        {
         margin /= moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);
        }
      else
        {
         static bool once = false;
         if(!once)
           {
            Print("Can't convert ", current, " -> ", account);
            once = true;
           }
        }
   return true;
  }

È impossibile dividere per zero, vero?


Inoltre, questo metodo dovrebbe restituire il margine, ma restituisce il prezzo. Capisco che da qualche parte questo prezzo dovrebbe essere moltiplicato per la dimensione del contratto, ma non capisco dove farlo correttamente.

Devo aggiungerlo in questa funzione o da dove chiamiamo questa funzione?

 
Aleksandr Slavskii #:

Potete dirmi se si tratta di un errore o se mi sfugge qualcosa?

File MarginProfitMeter.mqh

È impossibile dividere per zero, vero?

Infatti, non è possibile.

margin /= moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);

Dopo il simbolo di divisione c'è un operatore ternario con assegnazione "/=". Quindi, se momet==0, allora:

margin /= SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID)

altrimenti:

margin /= GetHistoricPrice(rate, moment, ask)

Ma aggiungerei comunque un controllo per lo zero da entrambe le funzioni....


Inoltre, questo metodo dovrebbe restituire il margine, ma restituisce il prezzo. Capisco che da qualche parte il prezzo debba essere moltiplicato per la dimensione del contratto, ma non capisco dove farlo in modo più corretto....

A giudicare dalla descrizione

// Convertire l'importo del denaro "corrente" in denaro "conto".

il metodo converte il denaro (valuta) corrente in denaro (valuta) del deposito. E a giudicare dal codice, il metodo converte il margine nella valuta del deposito.

In caso di successo, il metodo restituisce true. E calcolerà anche il nuovo importo corretto del margine, memorizzandolo nella variabile margin. Si tratta di un parametro del collegamento:

double &margin

Quindi è possibile ottenerlo come risultato del calcolo.

 
Denis Kirichenko #:

Non si può davvero.

C'è un operatore ternario dopo il simbolo di divisione con assegnazione "/=". Quindi, se momet==0, allora:

Sì, esatto, un operatore ternario. Stamattina sono stanco, sto diventando scemo.


Denis Kirichenko #:

A giudicare dalla descrizione

il metodo converte il denaro corrente (valuta) in denaro di deposito (valuta). E a giudicare dal codice, il metodo converte il margine nella valuta del deposito.

No, anche questo è corretto ora.


Mi scuso, ho fatto un piccolo errore nel codice.


In ogni caso è poco utile, perché alla fine il margine viene comunque conteggiato in modo errato se il volume è superiore a tre.

EURUSD; margin = 24668.8  //  OrderCalcMargin()
EURUSD; margin = 10889.599999999999 // MarginProfitMeter.mqh 

Calcolo del margine per dieci contratti.

 
Denis Kirichenko #:
margine /= momento == 0? SymbolInfoDouble(tasso, ask ? SYMBOL_ASK: SYMBOL_BID): GetHistoricPrice(rate, moment, ask);

Un piccolo errore. La condizione(margine /= momento)==0 e poi l'operatore ternario...

 
Alexey Viktorov #:

Un piccolo errore. La condizione (margine /= momento)==0 e poi un operatore ternario...

In qualche modo non sono d'accordo. Prova prima a soddisfare questa condizione:

double margin = 1.5;
datetime moment = 0;
margin /= moment;

Poi stai dividendo i ricci in ricci, il che è discutibile di per sé.

E le operazioni di assegnazione hanno una priorità molto bassa, solo zpt ha una priorità inferiore.

Anche il compilatore si arrabbia:

possible loss of data due to type conversion from 'datetime' to 'double'

E la logica della funzione è la conversione del margine. Per quanto ho capito, momento = 0 è ora. Poi:

margin /= moment == 0 ?
                SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                GetHistoricPrice(rate, moment, ask);

significa che se è adesso, chiediamo il prezzo corrente. E se è nel passato, si fa riferimento ai prezzi storici. E dopo aver ottenuto il prezzo desiderato, alla fine dividiamo il valore del margine per questo prezzo con l'assegnazione.... e con la vostra logica, risulta che al momento = 0, non otterremo la conversione del margine, ma solo il prezzo di mercato o il prezzo del passato....


In generale, sarebbe meglio scrivere tra parentesi per un libro di testo:

margin /= (moment == 0) ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);
 
Denis Kirichenko #:

In qualche modo non sono d'accordo. Provate prima a soddisfare questa condizione:

Questo divide i ricci in ricci, il che è già di per sé discutibile.

E le operazioni di assegnazione hanno una priorità molto bassa, solo zpt ha una priorità inferiore.

E anche il compilatore si arrabbia:

E la logica della funzione è la conversione del margine. Per quanto ho capito, momento = 0 è ora. Poi:

significa che se è adesso, chiediamo il prezzo corrente. E se è nel passato, facciamo riferimento ai prezzi storici. E dopo aver ottenuto il prezzo desiderato, alla fine dividiamo il valore del margine per questo prezzo con l'assegnazione.... e con la vostra logica, risulta che se momento = 0, non otterremo una conversione del margine, ma solo un prezzo di mercato o un prezzo passato...


In generale, sarebbe meglio scrivere tra parentesi per un libro di testo:

Convincente. Sono d'accordo, sono stato disattento. Ma se si scrive per un libro di testo e in modo che sia comprensibile anche a me, allora sarebbe meglio così

margin /= ( moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask));