Zum Inhalt springen
View in the app

A better way to browse. Learn more.

#T/N/X/T

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Digits bei EURJPY

Geschrieben

Ich trau mich die Frage garnicht stellen, weil die Lösung vermutlich richtig peinlich für mich wird, aber ich komm selber einfach nicht drauf.

 

Folgendes Problem:

if(Open[i]-Point>=Close[i+1])
{
 UpArrow[i]=0;
 PutTextLabel(-1, Time[i], DoubleToStr(Open[i]-Point,Digits), 6, "Arial", DarkGreen);
}
else
{
 UpArrow[i]=EMPTY_VALUE;
 PutTextLabel(-1, Time[i], DoubleToStr(Open[i]-Point,Digits), 6, "Arial", DarkGreen);
}

Im Klartext: Wenn der aktuelle Eröffnungskurs mindestens einen Punkt über dem vorherigen Schlußkurs liegt, dann setze UpArrow auf 0, ansonsten auf EMPTY_VALUE.

Das PutTextLabel ist nur zum Debuggen.

Jetzt siehts so aus. Bei EURUSD funktioniert das immer, soweit so gut.

Probier ich das aber mit EURJPY (also ein 2-Digit-Wert), dann kommt es immer wieder mal vor, dass das UpArrow leer bleibt, obwohl mein Eröffnungskurs einen Punkt überhalb des Schlusskurses liegt.

Dies wird mir auch bei der Debugausgabe angezeigt.

Ich hab schon an allen möglichen Stellen "NormalizeDouble" versucht aber kein Erfolg.

 

Mir ist komplett schleierhaft, warum das nicht geht :hmmmm:

 

Irgendwer eine Idee?

Featured Replies

Geschrieben
  • Autor

Was ist das denn?

Wenn ich mir über Textlabels Point, Open und Close[i+i] ausgeben lasse, so bekomme ich an Bars, wo folgende Kurse auftraten

Open= 111.69

Close[i+1]= 111.68

folgendes Ergebnis:

Point= 0.01

Open= 111.6900000037

Close[i+i]=111.6800000065

 

Wo kommen denn die Werte an 9. und 10. Stelle hinter dem Komma her???

Die Berechnung stimmt somit, aber die Daten sind mir überhaupt nicht klar.

Geschrieben
  • Autor

Open= 111.6900000037

Close[i+i]=111.6800000065

Bitte diesen Mist wieder vergessen!

Die Nachkommastellen kamen nur durch das Überlappen der Textlabels zustande.

Hab wohl noch nicht richtig aus den Augen rausgesehen... :cleanglasses:

 

Bei meinem Problem bin ich somit immer noch nicht weiter gekommen

Geschrieben

Mh, könnte es passieren das er auf "Point" nicht so klar kommt? Hast du mal einen eigenen Zahlenwert dafür eingetragen?

 

Viele Grüße,

Rumpel

Geschrieben
  • Autor

Mh, könnte es passieren das er auf "Point" nicht so klar kommt? Hast du mal einen eigenen Zahlenwert dafür eingetragen?

 

Viele Grüße,

Rumpel

Ja, ich hab das Point, das ja den Wert von 0.01 haben sollte mal durch 0.01 ersetzt. Das funktioniert genau so wenig.

 

Irgendwo kann da was mit der Rundung nicht funktionieren.

Wenn ich mach

if(Open[i]-0.999999999*Point >= Close[i+1])

dann geht's. Aber warum nicht bei 1*Point???

Geschrieben

wenn es wirklich ein Rundungsfehler sein sollte (ich erinnere mich gelesen zu haben, dass man beim Vergleich von doubles wegen der ungenauigkeit immer NormalizeDouble verwenden sollte - tue ich aber auch nicht ;-) ), dann versuch doch mal

if(NormalizeDouble(Open-Point,Digits)>=Close[i+1])

 

Grüsse,

askerix

Geschrieben
  • Autor

wenn es wirklich ein Rundungsfehler sein sollte (ich erinnere mich gelesen zu haben, dass man beim Vergleich von doubles wegen der ungenauigkeit immer NormalizeDouble verwenden sollte - tue ich aber auch nicht ;-) ), dann versuch doch mal

if(NormalizeDouble(Open-Point,Digits)>=Close[i+1])

Danke!

 

Hab ich auch schon versucht. Geht genau sowenig, UFF!

Geschrieben

Hab ich auch schon versucht. Geht genau sowenig, UFF!

Laienfrage:

Kann es etwas mit dem Spread zu tun haben ?

Geschrieben
  • Autor

Laienfrage:

Kann es etwas mit dem Spread zu tun haben ?

Leider nicht!

Geschrieben

Point benötigst du nicht.

 

Wenn aktuelle OPEN grösser ist wie vorherige CLOSE, dann ist auch deine Regel in Kraft.

"Wenn der aktuelle Eröffnungskurs mindestens einen Punkt über dem vorherigen Schlußkurs liegt, dann setze UpArrow auf 0, ansonsten auf EMPTY_VALUE."


if(Open[i]>Close[i+1])
{
 UpArrow[i]=0;
 PutTextLabel(-1, Time[i], DoubleToStr(Open[i],Digits), 6, "Arial", DarkGreen);
}
else
{
 UpArrow[i]=EMPTY_VALUE;
 PutTextLabel(-1, Time[i], DoubleToStr(Open[i],Digits), 6, "Arial", DarkGreen);
}

Geschrieben
  • Autor

Point benötigst du nicht.

 

Wenn aktuelle OPEN grösser ist wie vorherige CLOSE, dann ist auch deine Regel in Kraft.

"Wenn der aktuelle Eröffnungskurs mindestens einen Punkt über dem vorherigen Schlußkurs liegt, dann setze UpArrow auf 0, ansonsten auf EMPTY_VALUE."

Danke, ja!

Das funktioniert schon. Der Code, den ich hier gepostet habe ist aber sozusagen nur der Kern des Problems. Real ist die if-Abfrage etwas komplexer, funktioniert per BarShift über einen anderen Zeitrahmen und die Differenz zwischen Open und Close ist auch nicht nur 1 Punkt, sondern flexibel. Der reine Vergleich Open>Close[i+1] ist somit leider nicht umsetztbar.

 

Mir ist halt total schleierhaft, warum diese Abfrage

if(Open>=Close[i+1]+ Point)

die ja eigentlich sowas von trivial ist, nicht funktioniert.

Geschrieben

Point benötigst du nicht.

 

Aber er will doch den Punkt drinn haben. Der Pfeil soll ja nur gezeichnet werden wenn der Wert einen ganzen Punkt größer ist.

Geschrieben

Mir ist halt total schleierhaft, warum diese Abfrage

if(Open>=Close[i+1]+ Point)

die ja eigentlich sowas von trivial ist, nicht funktioniert.

Meine früheren C/C++-Programmierungen mit dem Datentyp float führten zu ähnlichen Phänomenen. Das Problem war, dass "Kommazahlen" in den internen Registern des PCs nicht unbedingt so gespeichert werden, wie man sie reinschiebt. Oder eine Berechnung (wie bei dir ein einfaches -Point) führt zu Verschiebungen in den Kommazahlen. Siehe auch Microsoft-KB (deutsche Übersetzung). Das heißt bspw., dass ein float, gestartet mit 0.01 und 99mal 0.01 aufaddiert (wirklich aufaddiert, nicht 0.01*100 rechnen) nicht unbedingt 1 ergeben muss!

 

Ob dies auf dein Problem zutrifft, kann ich nicht sagen. Klingt aber danach. Du könntest das testen, indem du nicht nur NormalizeDouble verwendest, sondern jeden Part z.B. mit 1000 multiplizierst. So in etwa:

 

if((Open[i]*1000)>=((Close[i+1]*1000)+ (Point*1000)))

Und dann notfalls noch NormalizeDouble um jede Klammer.

Geschrieben

Ich verstehe nicht, wiso möchtest du + Point rechnen?

Was hat das für eine Sinn oder Funktion ?

Geschrieben

Ich verstehe nicht, wiso möchtest du + Point rechnen?

Was hat das für eine Sinn oder Funktion ?

 

Möchtest du das ein gleichmäßiger Abstand, der Pfeile über den BARS ensteht ?

Geschrieben
  • Autor

Möchtest du das ein gleichmäßiger Abstand, der Pfeile über den BARS ensteht ?

Der eigentliche Code soll mal inetwa so aussehen:

if(Open[i]>=Close[i+1]+Param*Point)
...

D.h. bei einer bestimmten Gap-Größe soll ein Signal gegeben werden.

Die Größe in Punkten wird über den Parameter eingestellt.

Geschrieben

Der eigentliche Code soll mal inetwa so aussehen:

if(Open[i]>=Close[i+1]+Param*Point)
...

D.h. bei einer bestimmten Gap-Größe soll ein Signal gegeben werden.

Die Größe in Punkten wird über den Parameter eingestellt.

 

Versuch das Mal

   double current_openprice=iOpen(Symbol(), Period(), 0);
  double previous_closeprice=iClose(Symbol(), Period(), 1);
  double point_gap=MarketInfo(Symbol(), MODE_POINT);
     int spread_gap=MarketInfo(Symbol(), MODE_SPREAD);
     int    min_gapsize = 1;

  if(current_openprice > previous_closeprice + (min_gapsize + spread_gap)*point_gap
    {
     ...
    }

 

Geschrieben
  • Autor

So, bin jetzt doch noch ein Stück weiter gekommen.

Ich hab mal einwenig rumgespielt, ab wieviel Digits die Abfrage klappt/nicht klappt.

Bei EURJPY ist ein Punkt ja 0.01 (4-Digit-Broker) also hab ich mit den Nachkommastellen gespielt.

 

if(Open>=Close[i+1]+0.009999999999999) funktioniert noch, d.h. der Pfeil wird bei einem Punkt Abstand Open/Close gezeichnet

if(Open>=Close[i+1]+0.0099999999999999) geht nicht

 

Dann hab ich Open Close nochmal genauer untersucht.

Es gibt in der stdlib die Funktion DoubleToStrMorePrecision(), die mehr Nachkommastellen als DoubleToStr ausgibt.

Label="Text_"+Time[i]+"b";
PutTextLabel(Label,-1.3, Time[i], DoubleToStrMorePrecision(Close[i+1],15), 6, "Arial", DarkGreen);
Label="Text_"+Time[i]+"c";
PutTextLabel(Label,-1.6, Time[i], DoubleToStrMorePrecision(Open[i],15), 6, "Arial", DarkGreen);		

Das gibt mir dann für Close[i+1] (oben) und Open (unten) folgendes aus:

DtS.jpg

Also Zahlen, die bei der 15. Nachkommastelle schwanken.

 

Bei EURUSD bekomm ich an der 18. Nachkommastelle sowas: 1.3625000000000001

Damit schein die Abfrage aber noch zu funktionieren.

 

Ok, komischer Effekt ... was dann aber noch dazu kommt: Wenn ich NormalizeDouble() mache, funktioniert die Abfrage für EURJPY trotzdem nicht.

 

Ächtz :laie70b:

Geschrieben

Also Zahlen, die bei der 15. Nachkommastelle schwanken.

Das ist das Problem der Genauigkeit, da der Datentyp aufgrund seiner Größe im Speicher nicht anders arbeiten kann. Probier mal meinen Tipp von oben aus. Interessiert mich :wink2:

Geschrieben

Ich denke mal das = ist das Problem.

Die Gleichheit von zwei reellen Zahlen kann nicht verglichen werden.

benötigst du das = unbedingt ?

Geschrieben
  • Autor

Das ist das Problem der Genauigkeit, da der Datentyp aufgrund seiner Größe im Speicher nicht anders arbeiten kann. Probier mal meinen Tipp von oben aus. Interessiert mich :wink2:

Hi Rainworm,

 

hab in der Hektik dein Post total übersehen :cleanglasses: .

 

Ja, genau das war's. Bei deinem Beispiel funktioniert es SUPER! :claphands:

 

Rainworm, Finger,

ich seid echt spitze!

Vielen Dank :flowers:

benötigst du das = unbedingt ?

Nein, das kann ich auch umgehen.

Geschrieben

Ja, genau das war's. Bei deinem Beispiel funktioniert es SUPER! :claphands:

Passt ja dann sehr gut in das Unterforum "MQL Einsteiger" :wink2:

Geschrieben

Hier noch ein schönes Beispiel.

 


bool CompareDoubles(double number1,double number2)
 {
  if(NormalizeDouble(number1-number2,8)==0) return(true);
  else return(false);
 }
void OnStart()
 {
  double d_val=0.3;
  float  f_val=0.3;
  if(CompareDoubles(d_val,f_val)) Print(d_val," equals ",f_val);
  else Print("Different: d_val = ",DoubleToString(d_val,16),
             "  f_val = ",DoubleToString(f_val,16));
 }

Geschrieben

Hier noch ein schönes Beispiel.

Du bist doch unser MQL5-Fachmann :nictation: Ist das dort auch noch so, oder werden die Datentypen intern anders gespeichert?

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

Account

Navigation

Suche

Suche

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.