WOGO Posted February 7, 2011 Report Share Posted February 7, 2011 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 Irgendwer eine Idee? 1 Quote Link to comment Share on other sites More sharing options...
WOGO Posted February 8, 2011 Author Report Share Posted February 8, 2011 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 auftratenOpen= 111.69Close[i+1]= 111.68folgendes Ergebnis:Point= 0.01Open= 111.6900000037Close[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. Quote Link to comment Share on other sites More sharing options...
WOGO Posted February 8, 2011 Author Report Share Posted February 8, 2011 Open= 111.6900000037Close[i+i]=111.6800000065Bitte diesen Mist wieder vergessen! Die Nachkommastellen kamen nur durch das Überlappen der Textlabels zustande. Hab wohl noch nicht richtig aus den Augen rausgesehen... Bei meinem Problem bin ich somit immer noch nicht weiter gekommen Quote Link to comment Share on other sites More sharing options...
Rumpel Posted February 8, 2011 Report Share Posted February 8, 2011 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 Quote Link to comment Share on other sites More sharing options...
WOGO Posted February 8, 2011 Author Report Share Posted February 8, 2011 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,RumpelJa, 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??? Quote Link to comment Share on other sites More sharing options...
askerix Posted February 8, 2011 Report Share Posted February 8, 2011 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 Quote Link to comment Share on other sites More sharing options...
WOGO Posted February 8, 2011 Author Report Share Posted February 8, 2011 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! Quote Link to comment Share on other sites More sharing options...
Vola Posted February 8, 2011 Report Share Posted February 8, 2011 Hab ich auch schon versucht. Geht genau sowenig, UFF!Laienfrage:Kann es etwas mit dem Spread zu tun haben ? Quote Link to comment Share on other sites More sharing options...
WOGO Posted February 8, 2011 Author Report Share Posted February 8, 2011 Laienfrage:Kann es etwas mit dem Spread zu tun haben ?Leider nicht! Quote Link to comment Share on other sites More sharing options...
FinGeR Posted February 8, 2011 Report Share Posted February 8, 2011 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); } 3 Quote Link to comment Share on other sites More sharing options...
WOGO Posted February 8, 2011 Author Report Share Posted February 8, 2011 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. Quote Link to comment Share on other sites More sharing options...
Rumpel Posted February 8, 2011 Report Share Posted February 8, 2011 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. Quote Link to comment Share on other sites More sharing options...
RAiNWORM Posted February 8, 2011 Report Share Posted February 8, 2011 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. 1 Quote Link to comment Share on other sites More sharing options...
FinGeR Posted February 8, 2011 Report Share Posted February 8, 2011 Ich verstehe nicht, wiso möchtest du + Point rechnen?Was hat das für eine Sinn oder Funktion ? Quote Link to comment Share on other sites More sharing options...
FinGeR Posted February 8, 2011 Report Share Posted February 8, 2011 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 ? Quote Link to comment Share on other sites More sharing options...
WOGO Posted February 8, 2011 Author Report Share Posted February 8, 2011 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. Quote Link to comment Share on other sites More sharing options...
FinGeR Posted February 8, 2011 Report Share Posted February 8, 2011 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 { ... } 1 Quote Link to comment Share on other sites More sharing options...
WOGO Posted February 8, 2011 Author Report Share Posted February 8, 2011 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 gezeichnetif(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:Also Zahlen, die bei der 15. Nachkommastelle schwanken. Bei EURUSD bekomm ich an der 18. Nachkommastelle sowas: 1.3625000000000001Damit 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 Quote Link to comment Share on other sites More sharing options...
RAiNWORM Posted February 8, 2011 Report Share Posted February 8, 2011 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 Quote Link to comment Share on other sites More sharing options...
FinGeR Posted February 8, 2011 Report Share Posted February 8, 2011 Ich denke mal das = ist das Problem.Die Gleichheit von zwei reellen Zahlen kann nicht verglichen werden.benötigst du das = unbedingt ? Quote Link to comment Share on other sites More sharing options...
WOGO Posted February 8, 2011 Author Report Share Posted February 8, 2011 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 Hi Rainworm, hab in der Hektik dein Post total übersehen . Ja, genau das war's. Bei deinem Beispiel funktioniert es SUPER! Rainworm, Finger, ich seid echt spitze!Vielen Dank benötigst du das = unbedingt ?Nein, das kann ich auch umgehen. Quote Link to comment Share on other sites More sharing options...
RAiNWORM Posted February 8, 2011 Report Share Posted February 8, 2011 Ja, genau das war's. Bei deinem Beispiel funktioniert es SUPER! Passt ja dann sehr gut in das Unterforum "MQL Einsteiger" Quote Link to comment Share on other sites More sharing options...
FinGeR Posted February 8, 2011 Report Share Posted February 8, 2011 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)); } Quote Link to comment Share on other sites More sharing options...
RAiNWORM Posted February 8, 2011 Report Share Posted February 8, 2011 Hier noch ein schönes Beispiel.Du bist doch unser MQL5-Fachmann Ist das dort auch noch so, oder werden die Datentypen intern anders gespeichert? Quote Link to comment Share on other sites More sharing options...
FinGeR Posted February 9, 2011 Report Share Posted February 9, 2011 Ja ist dort auch noch so. das oben wäre ein alternatives Beispiel. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.