Inhalte aufrufen

  • Über WindowsLive anmelden Log In with Google Anmelden
  • Mitglied werden
Profilbild

Schwerwiegender Fehler beim Vergleich von Dezimalzahlen

- - - - -

  • Du kannst leider keine neuen Themen eröffnen
  • Please log in to reply
5 Antworten zu diesem Thema

  #1
ONLINE   traderdoc

Manchmal denke ich, alles über MQL4 zu kennen und dann überrascht es einen eiskalt!

 

Folgende Situation hat mein eh schon schütteres Haar weiter stark geliftet:

 

Bei einem EA wurde eine Sell-StopOrder beim Broker QTrade und dem Handelsinstrument WS30 mit der Lotgröße von 1.4 gesetzt

und später erfolgreich getriggert.

Ein späterer, notwendiger Abgleich über eine in den Eigenschaften des EA aufgeführte double-Variable mit dem Wert 1.4

führte nach der if-Anweisung zum Ergebnis false!!

 

...

...

if (OrderLots() == Sell_Pending_Lot)

 

Eine nach dieser Abfrage eingefügte Print-Zeile ergab für OrderLots() den Wert 1.4 und für Sell_Pending_Lot auch 1.4, was

eigentlich zum Ergebnis true führen müsste. OrderLots() wird dabei wie gewohnt einfach ausgelesen und Sell_Pending_Lot ist eine nicht geänderte

Variable aus den Eigenschaften.

 

Grübel, grübel.... Auch die Printausgabe mittels DoubleToStr(OrderLots(), 10) und DoubleToStr(Sell_Pending_Lot, 10) ergab in beiden Fällen: 1.4000000000.

 

Würde man übrigens statt 1.4 die Lotgröße und Variablenwert von 1.2 verwenden, wird die if-Abfage mit true quittiert!!!

Warum aber nicht bei 1.4 und auch nicht bei 1.3?

 

So und jetzt kommt der Hammer:

 

if (NormalizeDouble(OrderLots(), 2) == Sell_Pending_Lot)

 

führt zum Ergebnis true!!!

 

Und jetzt erklärt mir mal einer, warum die Lotgröße 1.4 nach dem Auslesen mittels OrderLots() nicht mehr exakt 1.4 war. Da bei diesem Broker die Lotgrößen nur 2 Stellen

nach dem Komma haben können, dürfte logischerweise auch in der 15. Stelle nach dem Komma keine andere Ziffer als 0 auftreten.

 

Das Ergebnis false hatte nun im weiteren Verlauf des EA ein schwerwiegendes Versagen anderer Module zur Folge.

 

Hat jemand eine schlüssige Erklärung dafür?

 

traderdoc


Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierwünsche.

  #2
OFFLINE   -ixbone-

Schlüssige Antwort bei MQL4? Irgendwo habe ich gelesen das viele MQL Funktionen oder Werte wie Ask, Bid, OrderLot(), OrderOpenPrice(), OderClosePrice() etc. kein NormalizeDouble benötigen, aber das ist schon Jahre her. Was somit aussagt, schreibst du eigenes Zeug mußt du NormalizeDouble verwenden. Ich habe mich aber damals aus Zeitgründen nicht näher befaßt, mit Normalize hatte ich eine Lösung, damals vor Jahren als Anfänger in MQL gefunden und verwende diese heute an vielen Stellen, nicht nur bei Lots Berechnungen..


Bearbeitet von -ixbone-, 29 June 2019 - 05:22 Uhr,


  #3
OFFLINE   CashDigger

Floating Point Variablen bieten immer diese Stolperfallen. Man darf Fließkommazahlen nie auf direktem Wege auf Gleichheit prüfen.

Die Printausgabe entspricht nicht unbedingt der internen Darstellung der echten Variable im Dualsystem. DoubleToStr(OrderLots(), 10) zeigt nicht unbedingt die ganze Wahrheit.

 

Daher immer nur auf Gleichheit prüfen mit entsprechender Rücksichtnahme auf die Fließkommazahlen:

Please Login or Register to see this Hidden Content

oder man macht das Ganze per Toleranz anhand Epsilon dann bist du auf gar keine mql-Funktion mehr angewiesen.

 

Eine schlüssige Erklärung wäre in dem Falle nach meiner Logik so:

Nachdem die Order geöffnet wurde landen die zur Order gehörenden Values irgendwo für den Prozess Metatrader im RAM, spätestens dann wenn OrderSelect() intern eine Art Pointer (für zB OrderLots()) darauf zeigen lässt.

Und genau hier liegt das Problem, werden automatisch Fließkommazahlen in den RAM geschrieben, unterliegen die dann natürlich den bekannten Effekten.

OrderLots() holt sich dann den double Wert nur aus dem RAM, dieser ist natürlich ohne die eindeutige Präzision eines Integers.

Entsprechend ist es nicht ungewöhnlich, dass bei einem Abgleich direkt mit OrderLots() so ein Fehler auftreten kann. Daher Fließkommazahlen NIEMALS auf direktem Wege auf Gleichheit prüfen.

 

Grüße

C$D


  • traderdoc gefällt das

  #4
OFFLINE   -ixbone-

Floating Point Variablen bieten immer diese Stolperfallen. Man darf Fließkommazahlen nie auf direktem Wege auf Gleichheit prüfen.

Die Printausgabe entspricht nicht unbedingt der internen Darstellung der echten Variable im Dualsystem. DoubleToStr(OrderLots(), 10) zeigt nicht unbedingt die ganze Wahrheit.

 

Daher immer nur auf Gleichheit prüfen mit entsprechender Rücksichtnahme auf die Fließkommazahlen:

Please Login or Register to see this Hidden Content

oder man macht das Ganze per Toleranz anhand Epsilon dann bist du auf gar keine mql-Funktion mehr angewiesen.

 

Eine schlüssige Erklärung wäre in dem Falle nach meiner Logik so:

Nachdem die Order geöffnet wurde landen die zur Order gehörenden Values irgendwo für den Prozess Metatrader im RAM, spätestens dann wenn OrderSelect() intern eine Art Pointer (für zB OrderLots()) darauf zeigen lässt.

Und genau hier liegt das Problem, werden automatisch Fließkommazahlen in den RAM geschrieben, unterliegen die dann natürlich den bekannten Effekten.

OrderLots() holt sich dann den double Wert nur aus dem RAM, dieser ist natürlich ohne die eindeutige Präzision eines Integers.

Entsprechend ist es nicht ungewöhnlich, dass bei einem Abgleich direkt mit OrderLots() so ein Fehler auftreten kann. Daher Fließkommazahlen NIEMALS auf direktem Wege auf Gleichheit prüfen.

 

Grüße

C$D

 

Interessant! Vorrstellbar.



  #5
ONLINE   traderdoc

Ich benutze bereits soviele NormalizeDouble(), dass ich bisher solch ein Problem nicht hatte, weil ich auch aus der Vergangenheit sehr wohl um die

Problematik der direkten Vergleichbarkeit von Dezimalzahlen wusste.

 

Aber da ging es in der Regel nur um Dezimalzahlen, die aus den unterschiedlichsten Berechnungen heraus dann weiter

benutzt worden. Aber nicht bei OrderLots()!!

 

Nun, wie dem auch sei, wie Du schon geschrieben hattest - NIEMALS!!

 

traderdoc


Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierwünsche.

  #6
OFFLINE   CashDigger

Bei den Orders kommen die Daten vom Server des Brokers und müssen irgendwie in den RAM des eigenen Computers kommen.

Der Weg der Variable könnte ungefähr so aussehen:

 

- schreiben in den Server des Brokers nach dem Öffnen der Order.

- lesen vom Server des Brokers um es MT4 zu übermitteln (für die History, bzw offene Orders)

- schreiben vom Server des Brokers in das Transportmedium (TCP/IP) ggf serialisieren.

- lesen unter MT4 vom Transportmedium, dabei ggf ent-serialisieren.

- schreiben in den RAM des Prozesses Metatrader.

 

Jede dieser Stellen wo geschrieben/gelesen oder auch serialisiert wird, bietet das Potential die Präzision zu verlieren!

 

Und erst dann ruft man OrderLots() auf. Man sieht, davor kann mit dem Value auf der langen Reise einiges passieren :)







0 Benutzer lesen gerade dieses Thema

0 Mitglieder, 0 Gäste, 0 anonyme Nutzer