Expert Advisors: MQL5 Programming for Traders – Quellcodes aus dem Buch. Teil 7

 

MQL5 Programming for Traders – Quellcodes aus dem Buch. Teil 7:

Der abschließende siebte Teil des Buches befasst sich mit den erweiterten Möglichkeiten der MQL5-API, die bei der Entwicklung von Programmen für MetaTrader 5 nützlich sind. Dazu gehören nutzerdefinierte Finanzsymbole, integrierte wirtschaftliche Kalenderereignisse und allgemeine Technologien wie Netzwerke, Datenbanken und Kryptografie.

MQL5 Programming for Traders – Quellcodes aus dem Buch. Teil 7

Autor: MetaQuotes

 
Gute Lernressourcen
 
Lernen Sie
 
Hier sind kleine Bugfixes und Verbesserungen für den Kalender-Cache und den Filter.
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...
Dateien:
 

Können Sie mir sagen, ob dies ein Fehler ist oder ich etwas nicht verstehe?

MarginProfitMeter.mqh-Datei.

// Umrechnung des "aktuellen" Geldbetrags in "Kontogeld".
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;
  }

Es ist unmöglich, durch Null zu dividieren, nicht wahr?


Außerdem sollte diese Methode die Marge zurückgeben, aber sie gibt den Preis zurück. Ich verstehe, dass dieser Preis irgendwo mit der Kontraktgröße multipliziert werden sollte, aber ich verstehe nicht, wo ich das richtig machen soll.

Soll ich es in dieser Funktion hinzufügen oder von wo aus wir diese Funktion aufrufen?

 
Aleksandr Slavskii #:

Können Sie mir sagen, ob dies ein Fehler ist oder ob ich etwas übersehen habe?

Datei MarginProfitMeter.mqh

Es ist unmöglich, durch Null zu dividieren, nicht wahr?

In der Tat, das kann man nicht.

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

Es gibt einen ternären Operator nach dem Divisionssymbol mit der Zuweisung "/=". Wenn also momet==0, dann:

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

sonst:

margin /= GetHistoricPrice(rate, moment, ask)

Aber ich würde trotzdem eine Prüfung auf Null bei beiden Funktionen hinzufügen....


Außerdem sollte diese Methode die Marge zurückgeben, aber sie gibt den Preis zurück. Ich verstehe, dass dieser Preis irgendwo mit der Kontraktgröße multipliziert werden sollte, aber ich verstehe nicht, wo man das korrekter machen kann....

Der Beschreibung nach zu urteilen

// Umrechnung des "aktuellen" Geldbetrags in "Kontogeld".

wandelt die Methode aktuelles Geld (Währung) in Geld (Währung) der Einlage um. Und dem Code nach zu urteilen, wandelt die Methode die Marge in die Währung der Einlage um.

Im Erfolgsfall gibt die Methode true zurück. Außerdem berechnet sie den neuen, korrigierten Betrag der Marge und speichert ihn in der Variablen margin. Sie ist ein Parameter in der Verknüpfung:

double &margin

Sie können ihn also als Ergebnis der Berechnung abrufen.

 
Denis Kirichenko #:

Das kann man wirklich nicht.

Es gibt einen ternären Operator nach dem Divisionssymbol mit der Zuweisung "/=". Wenn also momet==0, dann:

Ja, das stimmt, ein ternärer Operator. Ich bin müde heute Morgen, ich werde langsam dumm.


Denis Kirichenko #:

Nach der Beschreibung zu urteilen

wandelt die Methode aktuelles Geld (Währung) in Einlagengeld (Währung) um. Und dem Code nach zu urteilen, wandelt die Methode die Marge in die Einlagenwährung um.

Nein, das ist jetzt auch richtig.


Ich entschuldige mich, ich habe einen kleinen Fehler im Code gemacht.


Es nützt sowieso wenig, denn am Ende wird die Margin immer noch falsch berechnet, wenn das Volumen mehr als drei beträgt.

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

Margin-Berechnung für zehn Kontrakte.

 
Denis Kirichenko #:
margin /= moment == 0? SymbolInfoDouble(Kurs, Nachfrage ? SYMBOL_ASK: SYMBOL_BID): GetHistoricPrice(Kurs, Moment, Ask);

Ein kleiner Fehler. Die Bedingung(margin /= moment)==0 und dann der ternäre Operator...

 
Alexey Viktorov #:

Ein kleines bisschen falsch. Die Bedingung (Rand /= Moment)==0 und dann ein ternärer Operator...

Irgendwie stimme ich nicht zu. Versuchen Sie zuerst, diese Bedingung zu erfüllen:

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

Dann teilst du Igel in Igel, was an sich schon fragwürdig ist.

Und Zuweisungsoperationen haben eine sehr niedrige Priorität, nur zpt hat eine niedrigere Priorität.

Der Compiler wird auch wütend:

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

Und die Logik der Funktion ist Randumwandlung. Soweit ich das verstehe, ist moment = 0 now. then:

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

bedeutet, wenn es jetzt ist, fragen wir nach dem aktuellen Preis. Und wenn es in der Vergangenheit ist, beziehen wir uns auf historische Preise. Und nachdem wir den gewünschten Preis erhalten haben, teilen wir am Ende den Margenwert durch diesen Preis mit der Zuordnung.... und mit Ihrer Logik stellt sich heraus, dass wir zum Zeitpunkt = 0 keine Margenumrechnung erhalten, sondern nur den Marktpreis oder den Preis aus der Vergangenheit....


Im Allgemeinen wäre es besser, für ein Lehrbuch in Klammern zu schreiben:

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

Irgendwie stimme ich dem nicht zu. Versuchen Sie zuerst, diese Bedingung zu erfüllen:

Dann werden Igel in Igel unterteilt, was an sich schon fragwürdig ist.

Und Zuweisungsvorgänge haben eine sehr niedrige Priorität, nur zpt hat eine niedrigere Priorität.

Und der Compiler wird auch sauer:

Und die Logik der Funktion ist Randumwandlung. Soweit ich das verstehe, ist jetzt Moment = 0. Dann:

bedeutet, wenn es jetzt ist, fragen wir nach dem aktuellen Preis. Und wenn es in der Vergangenheit ist, dann beziehen wir uns auf historische Preise. Und nachdem wir den gewünschten Preis erhalten haben, teilen wir am Ende den Margenwert durch diesen Preis mit der Zuordnung.... und mit Ihrer Logik stellt sich heraus, dass wir, wenn Moment = 0 ist, keine Margenumrechnung erhalten, sondern nur einen Marktpreis oder einen Preis aus der Vergangenheit...


Generell wäre es besser, für ein Lehrbuch in Klammern zu schreiben:

Überzeugend. Ich stimme zu, ich war unaufmerksam. Aber wenn du für ein Lehrbuch schreibst, und zwar so, dass es auch für mich verständlich ist, dann wäre es besser so

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