|
Programmierung MQL4 Hier gehts rund ums Programmieren in MQL4. |
|
Themen-Optionen | Thema durchsuchen | Ansicht |
|
|||
Leute ich habe ein Problem mit meinem EA und brauche dringend eure Hilfe.
Ich habe folgenden Code in OnTick geschrieben: Code:
//3.//Zeitabfrage Zeit=TimeLocal(); Uhrzeit=TimeToString(Zeit,TIME_MINUTES); VierzehnUhrRoutine=(StringSubstr(Uhrzeit,0,5)=="14:00")==true; //5.//Kauf,- und VerkaufLevel berechnen VorperiodenTief=(iLow(NULL,PERIOD_H1,1)); MinusSpread=VorperiodenTief-0.60; VerkaufPreis=(NormalizeDouble(MinusSpread,Digits())); VorperiodenHoch=(iHigh(NULL,PERIOD_H1,1)); PlusSpread=VorperiodenHoch+0.60; KaufPreis=(NormalizeDouble(PlusSpread,Digits())); //8.//14:00 Uhr Routine StopNachziehen oder PendingOrders eröffnen //14:00 Uhr Routine 1.0 - Order öffnen wenn keine Order besteht if((VierzehnUhrRoutine==true)&&(TradeActionVierZehnUhr==0)) { bool OrderLoeschenLong; bool OrderLoeschenShort; int t=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderComment()=="DAX_H1_StrategieLong") { t++; } if(OrderComment()=="DAX_H1_StrategieShort") { t++; } } } if(t==0) { LotSize(); LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); { if((LongOrder1>0)&&(ShortOrder1>0)) { TradeActionVierZehnUhr++; } } } Und habe jetzt folgendes Problem.. Er hat heute um 14 Uhr die falsche Kerze zur Berechnung vom Kauf und Verkaufslevel genommen. Eigentlich sollte er die Kerze von 13-14 Uhr nehmen, genommen hat er aber die Kerze 12-13 Uhr. Die einzige Erklärung die ich habe, der erste Tick um 14:00 Uhr in der ersten Millisekunde wurde auf dem Chart noch zur vorherigen 13-14 Uhr Kerze gezählt obwohl dieser Preis bereits zur 14-15 Uhr Kerze gehören sollte. Er hat bei der Berechnung sozusagen eine Kerze zu weit zurück geschaut. Ich müsste irgendwie eine Regel davor setzen das er erst dann anfängt zu Berechnen, wenn die neue Periode begonnen hat. Könnt ihr mir bitte helfen??? MfG Lampe |
|
|||
Sorry für den Doppelpost aber ich war jetzt schonmal aktiv, brauche aber DRINGEND euren Rat ob der Code so richtig ist oder falsch..
Ich habe jetzt folgenden Zusatz eingebraut: OnTick Code:
//Periodenbeginn prüfen if(PeriodenStartZeit != Time[0]) { NeuePeriodeBegonnen = true; } else NeuePeriodeBegonnen = false; Daher habe ich jetzt immer folgendes gemacht: Code:
if(t==0) { LotSize(); LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); { if((LongOrder1>0)&&(ShortOrder1>0)) { TradeActionVierZehnUhr++; PeriodenStartZeit=Time[0]; } } } Dieses Vorgehen habe ich jetzt immer angewendet wenn ich irgendeine Aktion zu einem neuen Periodenbeginn ausführen möchte. Könnt ihr mir bitte sagen, ist das so korrekt oder ist das vorgehen fehlerhaft? Lampe |
|
|||
TimeLocal() gibt die Zeit Deines Computers wieder.
TimeCurrent() gibt die Server-Zeit Deines Brokers wieder. Daher kommt wahrscheinlich die eine Stunde Differenz. Wenn Du Dich auf die Zeit im Chart beziehen möchtest, must Du TimeCurrent() verwenden. |
|
|||
Die Zeit an sich ist nicht das Problem, zumindest hat er bisher immer zu der richtigen Zeit seine Handlungen ausgeführt.
Das Problem war, das ich eben sage if 14 Uhr true - tue dies und das, aber die Kerze im Chart nur ein paar Millisikunden noch in der alten Kerze ist, berechnet er die Hoch und Tief der flaschen Kerze. Beispiel 13-14 Uhr Kerze läuft. PUNKT 14:00:000 sollte eine neue Kerze beginnen. Jetzt haben wir einen Tick der 14:00:010 entsteht, also wenige Millisekunden nach Punkt 14:00. Wenn dieser eine Tick noch in der alten Kerze abgebildet wird, also in der 13-14 Uhr Kerze, dann nimmt mein EA Hoch und Tief der 12-13 Uhr Kerze zur Berechnung. Versteht man das was ich hier so ungeschickt zu beschreiben versuche? Ich habs jetzt so gelöst: Code:
//Periodenbeginn prüfen if(PeriodenStartZeit != Time[0]) { NeuePeriodeBegonnen = true; } else NeuePeriodeBegonnen = false; Code:
if((NeunUhrEins==true)||(ZehnUhrEins==true)||.......) { PeriodenStartZeit=Time[0]; } Traderdoc kannst auch du mir bitte kurz deine Meinung sagen ob dies so OK ist? Alle anderen natürlich bitte auch. MfG Lampe |
|
|||
Wenn die Abfrage innerhalb des Währungspaares bleibt, auf welchem sich der EA befindet, sollte es kein Problem geben, weil die neue Kerze erst gebildet wird, wenn für dieses WP auch ein Tick kommt.
Anders, wenn der EA ein "fremdes" WP abfragt, zu dessen Zeit noch kein neuer Tick vorliegt. Dann werden in der Tat die Werte der alte Kerze benutzt. traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
|||
Also der EA handelt ausschließlich im Dax. Allegmein läuft auf dem Metatrader nur dieser eine EA in einem Markt.
Ich persönlich konnte es mir auch erst nicht erklären wieso er plötzlich die falsche Kerze für die Pendingorders nimmt. Denkst du meine Analyse ist richtig, das es eben mal vorkommen kann das 14 Uhr und paar Millisekunden, noch ein Tick zur alten Kerze gerechnet wird? Mein Gedanke damals war, Punkt 14 Uhr, sobald da ein Tick kommt muss es ja zwangsläufig eine neue Kerze sein. Aber irgendwas lief heute schief und ich weiß das der EA auch nicht vor 14:00 aktiv war. Ausführungszeit der Orders war 14:00:00:157, ungefähr. Ich kann es mir nur so erklären, das der Tick der zu dieser Zeit kam, und den mein EA aktiviert hat, noch nicht in einer neuen Kerze abgebildet wurde und daher die falsche Kerze für Entry und Stop genommen wurde. Ich hoffe das die zusätzliche Abfrage mit Time[] das Problem löst, denn andernfalls würde ja jede Aktion die der EA macht gefahr laufen falsch berechnet zu werden. Seien es andere Entrys oder auch Stopmarken.. |
|
|||
Nur kurz...
Ich würde beim Programmieren keine festen Werte als Spread definieren, sondern ihn immer abrufen. Das "==true" kannst du auch weglassen und nur die Variable stehen lassen. Bei false-Abfrage dann die Variable mit einem Ausrufezeichen davor. Zitat:
Denk dran, beim Löschen einer Order, wenn es in einer for-Schleife passiert, OrdersTotal() nicht im for-Kopf aufzurufen. Zitat:
Zitat:
Das könnte man doch, wenn überhaupt nötig, deutlich vereinfachen... Außerdem verstehe ich nicht, warum du in einem Code weiter oben die Zeit nach dem setzen der Orders angleichst, jetzt aber entschieden hast, dies immer nach einer Minute zu tun? In einer Minute kann viel passieren... |
|
|||||
Vielen Dank Next für deinen Beitrag!!!
Ich möchte darauf eingehen und hoffe das ich noch mehr lerne. Zitat:
Zitat:
Zitat:
Code:
if((VierzehnUhrRoutine==true)&&(TradeActionVierZehnUhr==0)&&(NeuePeriodeBegonnen==true)) { bool OrderLoeschenLong; bool OrderLoeschenShort; int t=0; int i=OrdersTotal(); for(int i-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderComment()=="DAX_H1_StrategieLong") { t++; } if(OrderComment()=="DAX_H1_StrategieShort") { t++; } } } Zitat:
(Das Fett markierte) Code:
if(a==0) { LotSize(); LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); { if((LongOrder1>0)&&(ShortOrder1>0)) { TradeActionZehnUhr++; } } } } Nun bitte noch zu dem Wichtigsten Punkt nämlich: Zitat:
Ich vermute ich muss mit einer While Schleife arbeiten, die solange die Orders sendet bis beide im Markt sind. Anschließend dann TradeAction++. Ich versuche es mal: Code:
void OnTick() { if(ZehnUhrRoutine==true&&TradeActionZehnUhr==0&&NeuePeriodeBegonnen==true) { int a=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderComment()=="DAX_H1_StrategieLong") { a++; } if(OrderComment()=="DAX_H1_StrategieShort") { a++; } } } if(a==0) { while((LongOrder1<=0)||(ShortOrder1<=0)) { LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); { if((LongOrder1>0)&&(ShortOrder1>0)) { TradeActionZehnUhr++; } } } } } Vielleich ehr so: Code:
void OnTick() { if(ZehnUhrRoutine==true&&TradeActionZehnUhr==0&&NeuePeriodeBegonnen==true) { int a=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderComment()=="DAX_H1_StrategieLong") { a++; } if(OrderComment()=="DAX_H1_StrategieShort") { a++; } } } if(a==0) { while(LongOrder1<=0) { LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); } while(ShortOrder1<=0) { ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); } if(LongOrder1>=0&&ShortOrder1>=0) { TradeAction++; } } } Ich bedanke mich vielmals bei dir Next, das du dir soviel Mühe machst mir zu helfen und Tipps zu geben!!! MfG Lampe |
|
|||
Zitat:
Code:
for(int i=OrdersTotal()-1; i>=0; i--) { ... OrderDelete(); ... } Code:
for(int i=0; i<=OrdersTotal()-1; i++) { // Beispiel: Es sind 3 Orders offen... // Durchgang 1: i=0 -->> i<=2 -->> i++ OrderClose(...); // Durchgang 2: i=1 -->> i<=1 -->> i++ OrderClose(...); // Durchgang 3: i=2 -->> i<=0 -->> i++ // Durchgang 3 gibt es also nicht. Die letzte Order // würde nicht geschlossen werden OrderClose(...); } Da du es aber richtig angewandt hast, kannst du diesen Hinweis vergessen. Ich habe nur schon häufig Code von anderen gesehen, wo die beiden for-Schleifen (richtige und fehlerhafte), oder sogar nur die fehlerhafte im Code vorhanden war, daher einfach nur den Hinweis in den Raum geworfen. Zitat:
Aus den ersten Seiten dieses Themas habe ich deine Funktion zusammen mit dem Rückgabetyp "double" gesehen. Da du hier aber keine Zuweisung beim Aufruf vornimmst, hast du entweder die Variable "LotSize" global erstellt und weist ihr in der Funktion die Berechnung zu, oder die Variable ist nicht global und ich sehe dann aber nicht, wo sie bei dir mit einem Wert gefüllt wird. Wenn die Funktion bei dir noch genauso ist (mit Rückgabewert, ohne das du in ihr eine globale Variable fütterst), dann müsste es doch so aussehen: Code:
double lot = LotSize(); LongOrder1=OrderSend(NULL,OP_BUYSTOP,lot,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); ShortOrder1=OrderSend(NULL,OP_SELLSTOP,lot,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); Code:
LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize(),KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize(),VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); Zitat:
In einer Schleife, die NUR bei erfolgreicher Platzierung endet, sendest du immer die gleiche Anfrage mit gleichem Stop und schon haste eine Endlosschleife. Nun zu folgendem: Code:
void OnTick() { if(ZehnUhrRoutine==true&&TradeActionZehnUhr==0&&NeuePeriodeBegonnen==true) { int a=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderComment()=="DAX_H1_StrategieLong") { a++; } if(OrderComment()=="DAX_H1_StrategieShort") { a++; } } } if(a==0) { while((LongOrder1<=0)||(ShortOrder1<=0)) { LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); { if((LongOrder1>0)&&(ShortOrder1>0)) { TradeActionZehnUhr++; } } } } }
Du must halt auf mögliche Probleme bei einer Orderplatzierung reagieren, vor allem in einer Schleife! Code:
void OnTick() { if(ZehnUhrRoutine && !TradeActionZehnUhr && NeuePeriodeBegonnen) { int a=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderComment()=="DAX_H1_StrategieLong") { a++; } if(OrderComment()=="DAX_H1_StrategieShort") { a++; } } } if(!a) { while((LongOrder1<=0)||(ShortOrder1<=0)) { LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); if((LongOrder1>0)&&(ShortOrder1>0)) { TradeActionZehnUhr++; } else { // Entweder Schleife mit Fehlercode abbrechen, // oder Schleife nur bei Fehler abbrechen, die sonst zur // Endlosschleife führen würden. // Z.B: fehlerhafter Stop, Trading nicht erlaubt (EA) oder falsche Preisangaben... // Oder sonst irgendwie hier im else darauf reagieren... } } } } } |
|
|||
Hi Next! Mir raucht schon wieder der Kopf ey
Das mit dem LotSize wird ich morgen umsetzen. Ich habe halt ausserhalb von OnTick, also vermutlich Global, die LotSize Berechnung die ungefähr so aussieht: Code:
double LotSize() { if(Kontostand==5000) { LotSize=6; } .... return(LotSize) } Ich denke der allerwichtigste Punkt ist die Geschichte mit dem OrderSend, und verstanden habe ich das noch nicht.. So wie ich das jetzt verstehe sieht dein Code die While Schleife vor zum OrderSenden und mit Else fragst du dann, eventuelle Fehler ab. Soweit so gut. Selbst wenn ich jetzt mal ausser acht lasse das ich keine Ahnung habe wie ich konkret die Fehler auslesen kann..., stell ich mir noch eine andere Frage. Wie schaffe ich es denn dann, das er die Fehlerhafte Order noch sendet? Nehmen wir an er schickt nur die Longorder raus und die Shortorder geht, aus welchen Gründen auch immer, nicht raus. Dann habe ich die LongOrder im Markt liegen und möchte nurnoch die ShortOrder hinterher schicken. Wie geh ich denn das nun an? Alternativ, habe ich denn noch andere Möglichkeiten ausser mit einer Schleife zu arbeiten? *ich wechsel mal kurz in den Editor und schreib dann hier weiter* So. Ich habe jetzt mal folgendes geschrieben. Code:
if(a==0) if(t==0) { LotSize(); LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); if(LongOrder1<=0) { LongOrder1=OrderSend(NULL,OP_BUYSTOP,LotSize,KaufPreis,NULL,VerkaufPreis,0,"DAX_H1_StrategieLong",MagicNummer,0,clrGreenYellow); } if(ShortOrder1<=0) { ShortOrder1=OrderSend(NULL,OP_SELLSTOP,LotSize,VerkaufPreis,NULL,KaufPreis,0,"DAX_H1_StrategieShort",MagicNummer,0,clrRed); } if((LongOrder1>0)&&(ShortOrder1>0)) { TradeActionVierZehnUhr++; } } } Mein Gedanke, wenn eine der beiden Orders nach dem ersten Senden noch keine Ticketnummer hat, geht er in die if Bedingung und sendet die fehlende Order nach. Wenn am Ende beide ne Ordernummer haben also größer als 0 sind => TradeAction++. Ist das eine Herangehensweise die irgendwo Sinn macht oder ist das Blödsinn? Die Entscheidene Frage ist ja auch, muss ich zwangsläufig FehlerCodes abfragen? Nochmals vielen Dank das du so Geduldig bist!! MfG Lampe Edit: wenn irgendwo ne Klammer fehlt oder Zuviel ist liegt es am Kopieren. Zumindest lässt sich nach wie vor alles Compilieren. |
Lesezeichen |
Stichworte |
hilfe, lernen, mql4, mql4 aufbau, mql4 hilfe, mql4 lernen, programmierung, programmierung metatrader, programmierung mql4, starthilfe |
|
|