Experts: Programmation MQL5 pour les Traders - Codes Source du livre. Partie 7

 

Programmation MQL5 pour les Traders - Codes Source du livre. Partie 7:

La septième et dernière partie du livre traite des capacités avancées de l'API MQL5, qui seront utiles lors du développement de programmes pour MetaTrader 5. Il s'agit notamment des symboles financiers personnalisés, des évènements du calendrier économique intégré et de technologies générales telles que les réseaux, les bases de données et la cryptographie.

Programmation MQL5 pour les Traders - Codes Source du livre. Partie 7

Auteur : MetaQuotes

 
De bonnes ressources d'apprentissage
 
Apprendre
 
Voici de petites corrections de bugs et des améliorations pour le cache et le filtre du calendrier.
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...
Dossiers :
 

Pouvez-vous me dire s'il s'agit d'une erreur ou si je n'ai pas compris quelque chose ?

Fichier MarginProfitMeter.mqh.

// Convertir le montant de l'argent "courant" en argent "compte".
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;
  }

Il est impossible de diviser par zéro, n'est-ce pas ?


De plus, cette méthode devrait renvoyer la marge, mais elle renvoie le prix. Je comprends que ce prix doit être multiplié par la taille du contrat, mais je ne sais pas où le faire correctement.

Dois-je l'ajouter dans cette fonction ou à l'endroit où nous appelons cette fonction ?

 
Aleksandr Slavskii #:

Pouvez-vous me dire s'il s'agit d'une erreur ou si quelque chose m'échappe ?

Fichier MarginProfitMeter.mqh

Il est impossible de diviser par zéro, n'est-ce pas ?

En effet, c'est impossible.

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

Il y a un opérateur ternaire après le symbole de division avec l'affectation "/=". Donc si momet==0, alors :

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

sinon :

margin /= GetHistoricPrice(rate, moment, ask)

Mais j'ajouterais quand même une vérification de la présence de zéro dans les deux fonctions....


De plus, cette méthode devrait retourner la marge, mais elle retourne le prix. Je comprends que ce prix doit être multiplié par la taille du contrat, mais je ne vois pas où le faire plus correctement....

À en juger par la description

// Convertir le montant de l'argent "courant" en argent "compte".

la méthode convertit l'argent (devise) actuel en argent (devise) du dépôt. Et à en juger par le code, la méthode convertit la marge dans la devise du dépôt.

En cas de succès, la méthode renvoie true. Elle calcule également le nouveau montant corrigé de la marge et le stocke dans la variable margin. Il s'agit d'un paramètre dans le lien :

double &margin

Vous pouvez donc l'obtenir en tant que résultat du calcul.

 
Denis Kirichenko #:

Vous ne pouvez vraiment pas.

Il y a un opérateur ternaire après le symbole de division avec l'affectation "/=". Donc, si momet==0, alors :

Oui, c'est ça, un opérateur ternaire. Je suis fatigué ce matin, je deviens bête.


Denis Kirichenko #:

A en juger par la description

la méthode convertit la monnaie courante (devise) en monnaie de dépôt (devise). Et à en juger par le code, la méthode convertit la marge en monnaie de dépôt.

Non, c'est également correct maintenant.


Je m'excuse, j'ai fait une petite erreur dans le code.


De toute façon, cela ne sert pas à grand-chose, parce qu'en fin de compte, la marge est toujours calculée de manière incorrecte si le volume est supérieur à trois.

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

Calcul de la marge pour dix contrats.

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

Un petit problème. La condition(marge /= moment)==0 et ensuite l'opérateur ternaire...

 
Alexey Viktorov #:

Une petite erreur. La condition (marge /= moment)==0 et ensuite un opérateur ternaire...

Je ne suis pas d'accord. Essayez d'abord de remplir cette condition:

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

Ensuite, vous divisez des hérissons en hérissons, ce qui est discutable en soi.

Et les opérations d'affectation ont une priorité très faible, seul le zpt a une priorité plus faible.

Le compilateur se fâche aussi :

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

Et la logique de la fonction est la conversion de marge. Pour autant que je comprenne, moment = 0 est maintenant. Alors :

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

signifie que si c 'est maintenant, nous demandons le prix actuel. Et si c'est dans le passé, nous nous référons aux prix historiques. Et après avoir obtenu le prix souhaité, on divise à la fin la valeur de la marge par ce prix avec affectation..... et avec votre logique, il s'avère qu'à moment = 0, nous n'obtiendrons pas la conversion de la marge, mais seulement le prix du marché ou le prix du passé....


En général, il serait préférable d'écrire entre parenthèses pour un manuel :

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

Je ne suis pas d'accord. Essayez d'abord de remplir cette condition:

Cela divise les hérissons en hérissons, ce qui en soi est déjà discutable.

Et les opérations d'affectation ont une priorité très faible, seul le zpt a une priorité plus faible.

Et le compilateur se fâche aussi :

Et la logique de la fonction est la conversion des marges. Pour autant que je comprenne, moment = 0 est maintenant. Alors :

signifie que si c'est maintenant, nous demandons le prix actuel. Et si c'est dans le passé, nous nous référons aux prix historiques. Et après avoir obtenu le prix souhaité, nous divisons à la fin la valeur de la marge par ce prix avec affectation..... et avec votre logique, il s'avère que si moment = 0, on n'obtiendra pas de conversion de marge, mais juste un prix de marché ou un prix du passé...


En général, il serait préférable d'écrire entre parenthèses pour un manuel :

Convaincant. Je suis d'accord, j'étais inattentif. Mais si vous écrivez pour un manuel et pour que ce soit compréhensible même pour moi, alors ce serait mieux comme ceci

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