|
Programmierung MQL4 Hier gehts rund ums Programmieren in MQL4. |
|
Themen-Optionen | Thema durchsuchen | Ansicht |
|
|||||||||
Zitat:
In deiner 1-zeiligen Erwähnung hast du daneben ein Kommentar ("// nicht notwendig (next user)!!!") stehen. Mein, einige Posts zurückliegendes "nicht nötig" bezog sich auf deinen geposteten Beitrag HIER !!! Alles, was du DORT in der Funktion "CheckTakeProfit()" stehen hattest, war unnötig. Der Inhalt deiner Funktion "CheckTakeProfit()", wie du ihn jetzt aber wenige Posts zurück gepostet hast, war bei dem verlinkten Beitrag doch garnicht drinne. Deshalb sagte ich "unnötig"! === === === === === === === === === === === === Zitat:
Was ich sagte war, das deine beiden if-Abfragen sich nur um den Wert deiner Variablen "openOrders" unterscheidet. Diese Abfragen läufst du in ner Schleife durch. Bei einer Order ("openOrders" == 1) kommt der erste if-Block, soweit ok. Sobald es aber mindestens 2 Orders sind ("openOrders" == 2), bearbeitest du in der Schleife AUCH DIE ERSTE Order mit dem zweiten if-Block, ist das so gewollt (ich denke nicht)? === === === === === === === === === === === === Zitat:
IMMER Inhalt entsprechend dem Variablennamen zu erwarten. Und auch deine Kombination (Berechnung, Glättung) der beiden kenne ich nicht. Auch da kann ein "außenstehender" theoretisch alles erwarten, wenn ich an so manchen Code denke den ich schon gesehen habe... Daher meine allgemeine "Vermutung"! Außerdem habe ich nicht Zitat:
Zitat:
Zitat:
Was wird denn da an "OrderStopLoss()" "übergeben"? Zitat:
Und was meinst du mit "OrderStopLoss()" erkannt? Erfolgloser Aufruf? === === === === === === === === === === === === Zitat:
ich es richtig gesehen habe. === === === === === === === === === === === === Zitat:
Kommt etwas spät, aber die Print-Ausgaben siehst du im Terminal im Reiter "Experten". Ich persönlich setze immer eine MessageBox ein, die dann plötzlich aufplopt und ich sofort bescheid weiß. === === === === === === === === === === === === Kann sein, das ich dich da bei paar Punkten falsch verstanden habe, aber es ist gleich 6 und ich bin müde. Evtl. Fehler bei meinen Zeilen oben sind dann wohl auf den bereits aktiven "Sparmodus" meines Gehirns zurückzuführen... hehe. |
|
|||
Hallo, lieber next user,
Danke für Deine Zeit und Danke für Deine Hinweise. Ich hoffe Du konntest Dich zwischenzeitlich etwas erholen. Nun aber zu Deinem letzten Beitrag: "nötig oder unnötig" zu "ChechTakeProfit()", sollte nicht das Thema sein. === Bei "openOrders == 1" bzw. "openOrders == 2" wird es schon interessanter: Zitat:
Danke für den Hinweis. Somit hast Du natürlich recht; - beide Blöcke sollen eigentlich getrennt voneinander bearbeitet werden. "openOrders == 1" mit den dortigen Konditionen und "openOrders == 2" mit den Konditionen, die dann dort aufzuführen wären. (Lediglich zur Vereinfachung des Codes haben wir momentan die Konditionen für "openOrders == 1" bzw. "openOrders == 2" gleichgesetzt.) === "Trail_Target_2 + SMA7_ATR5_1" bzw. " *100 * Point", können wir uns wahrscheinlich "schenken". Nunmehr wissen wir beide, was gemeint war. (Unabhängig davon weiß ich nicht, wie ich "SMA7_ATR5_1" besser erklären soll. Zudem hat diese variierende Größe wenig Code-Relevanz.) === Nun aber zum "Trail_SL()" bzw. dem "updateSL()": Um wieder einheitliche Begriffe zu verwenden, ist es sicher sinnvoll, zu den Ursprüngen zurückzukehren. So sollte unter "void OnTick()" das (nachträgliche) Schließen der Position 1 erfolgen. Hier wurde der Begriff "updateSL" verwendet und der diesbezügliche Code als "Block 1" bezeichnet: Code:
void OnTick() { // ... int orderTicket1 = 0; int orderTicket2 = 0; if (orderTicket1) updateSL(orderTicket1); if (orderTicket2) updateSL(orderTicket2); if(orderTicket1 && orderTicket2) { if(OrderSelect(orderTicket2,SELECT_BY_TICKET,MODE_HISTORY)) { if(OrderSelect(orderTicket1,SELECT_BY_TICKET)) { if(OrderType() == OP_BUY) { if(!OrderClose(orderTicket1,OrderLots(),Bid,3)) Print("Order konnte nicht geschlossen werden, weil: ", GetLastError()); else Print("BIN ZU !!!"); } else if (OrderType() == OP_SELL) { if(!OrderClose(orderTicket1,OrderLots(),Ask,3)) Print("Order konnte nicht geschlossen werden, weil: ", GetLastError()); else Print("BIN ZU !!!"); } orderTicket1 = 0; orderTicket2 = 0; } } } // ... } Separat bzw. parallel dazu müssen natürlich erst einmal die Positionen 1 + 2 eröffnet werden. Dies sollte dann außerhalb der "void OnTick()" erfolgen ("Block 2") und "SO" aussehen: Code:
void TrailStopLoss(int ticket) { ResetLastError(); // könnte ggf. entfallen if(OrderSelect(ticket,SELECT_BY_TICKET)) { if(OrderType() == OP_BUY && (openOrders == 1 || openOrders == 2)) { if(Bid - OrderOpenPrice() > Trail_Target_1 *100 * Point) { if(OrderStopLoss() < Bid - TSL || OrderStopLoss() == 0) { if(!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TSL, OrderTakeProfit(), Blue)) return; Print("Error setting Buy trailing stop: ", GetLastError()); } } } else if(OrderType() == OP_SELL && (openOrders == 1 || openOrders == 2)) { if(OrderOpenPrice() - Ask > Trail_Target_1 *100 * Point) { if(OrderStopLoss() > Ask + TSL || OrderStopLoss() == 0) { if(!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + TSL, OrderTakeProfit(), Blue)) return; Print("Error setting Sell trailing stop: ", GetLastError()); } } } } } "Alle sprechen deutsch, doch keiner versteht mich !" - Oder vielleicht doch ? Ich wäre überaus dankbar, wenn dem so sein sollte !!! Wenn allerdings Korrekturen notwendig sind, würde ich mich über die entsprechenden Hinweise freuen. Anbei herzlichen Dank für Deine Anmerkungen zu den "Print-Ausgaben". Ansonsten hoffe ich, dass Du Dich ein wenig erholt hast und warte `mal wieder voller Spannung auf Dein nächstes Statement. Bis dahin mit LG. pt. |
|
||||
Wollte ich auch nicht zu einem Thema machen. In deinem (neuesten) Code hast du aber neben "CheckTakeProfit()" als
Kommentar "// nicht notwendig (next_user) !!!" stehen, was ich lediglich richtig stellen wollte... === === === === === === === === === === === === Nur so nebenbei gefragt, wenn "openOrders" nur zwischen 1 & 2 trennt, könntest du dort doch einfach auch die beiden Variablen "orderTicket1 / 2" nutzen. === === === === === === === === === === === === Zitat:
Zum zweiten Teil, du hast es ja ausreichend gut erklärt, das war ja nicht das Problem. Ich habe ja im vorherigen Post erklärt, warum ich es TROZDEM als mögliche Fehlerquelle angesprochen hatte, eben weil ich schon viele "gut benannte" Variablen anderer gesehen habe, die sich dann komplett anders herausstellten. === === === === === === === === === === === === Zitat:
=== === === === === === === === === === === === Zitat:
Zum zweiten Satz, auch hier war eine Übereinstimmung ja gegeben. Lediglich deine beiden Codeblöcke müsstest du "kommunizieren" lassen. In Block 1 nutzt du "updateSL()" in diesem, zweiten Block nennst du die Funktion "TrailStopLoss()" === === === === === === === === === === === === Zitat:
Schauen wir mal, wenn das nächste mal der Fehler auftaucht, welche deiner Print-Ausgaben dabei aktiv werden. So sollten wir dann schnell zur Ursache kommen... |
|
|||
Toll, Thanks !
Ich melde mich !!! LG. pt. |
|
|||
So, nun endlich meine Antwort:
Lieber next user, Zitat:
Und "Yes !" Inhaltlich völlig richtig und auch mein Ansinnen ! ... Vorschlag: Als erstes sollten wir uns vielleicht wieder auf einen einheitlichen Sprachgebrauch einigen und dabei die einzelnen Code-Bezeichnungen ggf. etwas eindeutiger formulieren: A) Block_A (ehemals "Block 1" = neue Benennung!) = der, welcher unter "void OnTick()" zugeordnet ist, welcher die Ticket-Abfrage bewerkstelligen und die openOrder == 1 (Pos.1) schließen soll. Code:
void OnTick() { // ... int orderTicket1 = 0; int orderTicket2 = 0; if (orderTicket1) updateSL(orderTicket1); if (orderTicket2) // usw. //...... Code:
void CheckForOpen() { // Formulierung entsprechend üblicher Codes //.... { res = OrderSend(Symbol(), OP_BUY, LotsOptimized(), Ask, 3, 0, 0, "", MagicNumber, 0, Green); return; } // analog für SELL //.... // hier müßte dann das Ticket_1 (updateSL = Ticket_1 ????) initiiert werden } Code:
void CheckHedgeOpen() { //... if (OrderType() == OP_BUY && openOrders == 2) { if (Close[0] < OrderOpenPrice() - HedgeTarget_1 * 100 * Point) { // 6 Pkt. lot = LotsOptimized(); Print("SELL", " ", AccountFreeMarginCheck(Symbol(), OP_SELL, lot)); if (AccountFreeMarginCheck(Symbol(), OP_SELL, lot) <= 0) return; res = OrderSend(Symbol(), OP_SELL, lot, Bid, 3, 0, 0, "", MagicNumber, 0, Red); // öffne Pos. 3 } return; } // analog für SELL //.... // hier müßte dann das Ticket_2 (updateSL = Ticket_2 ????) initiiert werden } Und wenn wir dieses "Ticket_2" tatsächlich nicht brauchen, könnte im "Block_A" ja auch die "Abfrage in der History" entfallen. Ob all diese Gedanken richtig sind, weiß ich nicht, - dennoch erscheinen sie mir logisch ! Eine zweite Idee (Deine Frage: Wo wird denn die Pos.1 eröffnet?) könnte darin bestehen, dass man genau diese EröffnungsOrder modifiziert, indem eine "OrderModify ..." ergänzt wird, die schon einen SL enthält. (Auslöser: openOrders == 2 oder fix, die Hedge-Grenze 1 Pkt. überschreitend) - In diesem Falle könnten wir sogar auf die gesamte "Ticket-Geschichte" verzichten ! Die Vorteile hier : 1.) Verlustbegrenzung = wird verbessert 2.) Die 3. Position (jetzt openOrder == 2 !!!) würde nicht mit 1.1 lot sondern wiederum mit 0.4 lot ausgelöst werden, was dann die Gesamt-Positionsgröße der Tradefolge reduziert und damit ggf. auch eine Pos.7 (wäre ja auch für kleinere Equity sinnvoll !) zulässt. Nur `mal so nebenbei ! In der Hoffnung, dass die o.a. Gedanken und Ideen zumindest nachvollziehbar und halbwegs richtig/umsetzbar sind, würde ich gern diese Änderungen/Optimierungen vornehmen. Wäre oder "IST" das der richtige Weg ? Und wieder einmal in Erwartung Deiner (hoffentlich baldigen) Antwort sowie mit dem üblichen DANKE und LG. pt. PS.: Wenn wir dann ggf. bis zu dieser Stelle Einigkeit hergestellt haben, müsste nur noch Ticket_1 (in "Block_B") initiiert, "Block_A" inhaltlich reduziert und die richtige Korrespodenz zwischen den Blöcken A und B hergestellt werden. So zur ersten neuen Idee. Ist das soweit richtig ? Zum zweiten Gedanken: "OrderModify ..." in der "void CheckForOpen()"- hier müsste eine korrekte Formulierung und Einfügung erfolgen. Wenn Dein "JA" vorliegt, sollte das "Dingeling" nun endlich, und wie gewünscht, funktionieren ! |
|
|||||
So, Wochenende um...
... auf in den Montag! Zitat:
Da es ursprünglich nur um die beiden Orders ging, habe ich die beiden Variablen eingeführt. Allerdings hatte ich auch erwartet, das du sie dann auch überall nutzt. Die Ticketnummern speicherst du bei "OrderSend()" aber anscheinend (erst) in einer Variablen "res". Warum nutzt du nicht die beiden Ticketvariablen? Auch sind die nicht als lokale Variablen in "OnTick()" vorgesehen, sondern wurden von mir ursprünglich global definiert... === === === === === === === === === === === === Zitat:
Trotzdem sollten auch unabhängig davon die Probleme ermittelt und beseitigt werden... === === === === === === === === === === === === Zitat:
Wenn du nicht mit den Tickets arbeiten willst, müsstest du die Orders ja anders ansprechen. Die Tickets sind da doch aber eine bequeme Methode... === === === === === === === === === === === === Zitat:
=== === === === === === === === === === === === Zitat:
|
|
|||
Liebe next user, Hallo !
Es ist einfach nur "große Klasse", dass Du Dich sogar am Montag Morgen, den eigenltlich keiner so gerne mag, meiner annimmst und akribisch jeden von mir geäußerten Gedanken "geraderückst". Toll ! - und Danke ! Dennoch bin ich mittlerweile zu einer Erkenntnis gelangt: 1. Ich selbst sollte nicht ständig neue Dinge ins Spiel bringen (weniger ist oft mehr!). Statt dessen ist es sicher wesentlich effektiver auf einen vormals recht weit entwickelten Code zurückzugreifen (den mit Ticket_1 und Ticket_2), hier die Ursache(n) für die Nicht-Ausführung zu finden und das "Ding" funktionsfähig zu machen. Grundvoraussetzung hierfür wäre, dass man wirklich Schritt für Schritt vorgeht und jeder einzelne Schritt auch von beiden Seiten exakt verstanden wird. Wenn dann alles laufen sollte, kann man ja immer noch darüber nachdenken, wie der Code/die Herangehensweise optimiert werden kann. Damit wäre mein anfängliches Ansinnen letztendlich umgesetzt. Und 2. Für den Fall (und wirklich nur für diesen Fall), dass sich innerhalb aller Disskusionen eine strategisch bessere und codetechnisch sinnvollere Variante ergibt, sollte auch diese zumindest erörtert werden. Das aber erst, wenn die obige Ausführung fertiggestellt ist. Würdest Du da mitgehen ? ================================================== ============== Beginnen wir also nochmals, wie unter 1. beschrieben: 1. Schritt: es werden "int Ticket_1 = 0" und "int Ticket_2 = 0" global (also im Code ganz oben) deklariert. 2. Unter "void OnTick()" wird dann das "updateSL()" aufgeführt, damit die weiter unten stehende Funktion "void updateSL()" auch per Tick erfolgen kann. 3. Ebenfalls unter "void On Tick()" müßte dann die Funktion "updateSL()" (= Block_A) ausgeführt und die Pos.1 nachträglich geschlossen werden. 4. NICHT unter "void OnTick()" stehend !!!, also eher im unteren Teil des Codes, wird dann die Funktion "void updateSL()" aufgeführt, welche den Trail_SL immer wieder aktuell modifiziert (= Block_B). Gleichzeitig sollte dieser Block dann auch für das ticket-update zuständig sein. So ! Jetzt nochmals zu Deinen letzten Hinweisen: vorheriges Zitat: Zitat:
... Und weiter - Zitat: Zitat:
Letztes Zitat: Zitat:
---> Den ersten Teil des Zitates verstehe ich allerdings nicht. Die Verwendung der Tickets = ok. und verstanden. NICHT verstanden Deine Erwartung, dass ich die Tickets auch überall verwenden soll und die Ticketnummern bei "OrderSend()" zu speichern sind. Wo sollten die Tickets denn noch genutzt werden ? Und was hat es mit der "OderSend()" und einer Speicherung der Ticketnummern auf sich. Beides wurde bisher gar nicht erwähnt. Oder ? ... Im Resultat sieht die Gesamt-Struktur des EA, einschließlich "UNSERER" Deklarationen und Blöcke jetzt "SO" aus: CODE: Code:
/*--- EA_Gesamt-Struktur: //--- globale Deklarationen (extern bzw. intern) --------------------+ int orderTicket1 = 0; // jetzt wieder global int orderTicket2 = 0; // jetzt wieder global double TSL_1 = Trail_SL_1 *100 *Point; // for Pos.1 double TSL_2 = Trail_SL_2 *100 *Point; // for Pos.2 //===================================================================+ int OnInit() { view graphic and calculat "AccountFreeMargin" } //===================================================================+ void OnDeinit() { Funktion hatte in der Form noch gefehlt ! } //===================================================================+ void OnTick() { //--- function for "AccountFreeMargin" //--- Add. Conditions for TradeZoneTimer //--- calculate open orders by current symbol --> and close by TP if (CalculateCurrentOrders(Symbol()) == 0) CheckForOpen(); //--- calculate open orders --> and opening a hedging position if (CalculateCurrentOrders(Symbol()) != 0) CheckHedgeOpen(); CheckForUpdateSL(); // <=========== NEU (für Block_B) // notwendig für späteren Aufruf dieser Funktion //======================================== //--- CheckCloseFirstPos <=============== NEU (Block_A) //======================================== nachträgliches Close Pos.1 if(orderTicket1) updateSL(orderTicket1); // updateSL (Kommunikat.) if(orderTicket2) updateSL(orderTicket2); // updateSL (Kommunikat.) if(orderTicket1 && orderTicket2) { if(OrderSelect(orderTicket2,SELECT_BY_TICKET,MODE_HISTORY)) { if(OrderSelect(orderTicket1,SELECT_BY_TICKET,MODE_TRADES)) { // MODE_TRADES hinzugefügt if(OrderType() == OP_BUY) { if(!OrderClose(orderTicket1,OrderLots(),Bid,3)) Print("Order konnte nicht ..., weil: ", GetLastError()); else Print("BIN ZU !!!"); } else if (OrderType() == OP_SELL) { if(!OrderClose(orderTicket1,OrderLots(),Ask,3)) Print("Order konnte nicht ..., weil: ", GetLastError()); else Print("BIN ZU !!!"); } orderTicket1 = 0; orderTicket2 = 0; } } } //--- } // end "void OnTick()" //===================================================================+ int CalculateCurrentOrders(string symbol) { Calculate open positions } //===================================================================+ void CheckForOpen() { Check for openOrder Conditions } // Pos.-Opening (by strategy) der Pos.1 //===================================================================+ double LotsOptimized() { MoneyManagement - Calculate lot size } //===================================================================+ void CheckTakeProfit() { Check for TakeProfit Conditions } // Close for all Pos. //===================================================================+ //--- UpdateSL() Pos.1 + Pos.2 <======= (Block_B) NEU //===================================================================+ void CheckForUpdateSL()(int ticket) { ResetLastError(); // könnte ev. entfallen ! //--- Pos. 1 if(OrderSelect(ticket,SELECT_BY_TICKET)) { if(OrderType() == OP_BUY && openOrders == 1) { if(Bid - OrderOpenPrice() > Trail_Target_1 *100 * Point) { if(OrderStopLoss() < Bid - TSL_1 || OrderStopLoss() == 0) { if(!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TSL_1, OrderTakeProfit(), Blue)) Print("Error setting Buy trailing stop: ", GetLastError()); } } } else if(OrderType() == OP_SELL && openOrders == 1) { if(OrderOpenPrice() - Ask > Trail_Target_1 *100 * Point) { if(OrderStopLoss() > Ask + TSL_1 || OrderStopLoss() == 0) { if(!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + TSL_1, OrderTakeProfit(), Blue)) Print("Error setting Sell trailing stop: ", GetLastError()); } } } //--- Pos.2 if(OrderType() == OP_BUY && openOrders == 2) { if(Bid - OrderOpenPrice() > Trail_Target_2 *100 * Point) { if(OrderStopLoss() < Bid - TSL_2 || OrderStopLoss() == 0) { if(!OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TSL_2, OrderTakeProfit(), Blue)) Print("Error setting Buy trailing stop: ", GetLastError()); } } } else if(OrderType() == OP_SELL && openOrders == 2) { if(OrderOpenPrice() - Ask > Trail_Target_2 *100 * Point) { if(OrderStopLoss() > Ask + TSL_2 || OrderStopLoss() == 0) { if(!OrderModify(OrderTicket(), OrderOpenPrice(), Ask + TSL_2, OrderTakeProfit(), Blue)) Print("Error setting Sell trailing stop: ", GetLastError()); } } } //--- } } //===================================================================+ void CheckHedgeOpen() { Check for HedgeOrder Conditions } // Pos.-Opening Pos.2 - Pos.6 //===================================================================+ void CloseAllOrders() { AllOrders closed } // Anwendg. by TakeProfit / Pos.1, Pos. 3 - 6 /not for Pos.2 //===================================================================+ //--- End -----------------------------------------------------------+ // mit welcher Code-Formulierung und an welcher Stelle "OrderSend" ??? ANMERKUNG: Jede einzelne Formulierung (Wortwahl) wurde nochmals überprüft und teilweise korrigiert, um zukünftige Missverständnisse auszuschließen. Obwohl mich noch viele Fragen quälen; - im Sinne von "Konzentration auf eine Sache" halte ich mich jedoch zurück, warte natürlich wieder geduldig und verbleibe vorerst mit ganz LG. pt. |
|
|||
Werde ich nachher in Ruhe durchgehen.
|
|
|||
Aber nur bei einer ganz großen Kanne Tee.
traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
|||
Hallo, traderdaoc,
ein ganz herzliches "Willkommen" in diesem Beitrag ! Große Kanne Tee? - kein Thema ! Wenn Du es wünscht, auch eine ganze Plantage !!! Ich freue mich riesig, dass es nunmehr ggf. einen "Einklang" im "Dreiklang" geben könnte. (next user, traderdoc und meine Wenigkeit -piptrade) Deine Hinweise könnten diesen Forenbeitrag imens bereichern und uns ggf. schneller/optimaler ans Ziel führen. Für alle anderen zur Info: traderdoc hat mir schon 2 x zum Code-Erfolg verholfen; - und das in einfach fairer Form ! Somit meine Empfehlung: "Daumen hoch !" In angespannter Haltung und voller Ungeduld, Euer einfach nur dankbarer (und natürlich wartender) piptrade |
Lesezeichen |
Stichworte |
alle order schließen, closeallorders, mql4, programmierung, programmierung metatrader, programmierung mql4, trailingstop |
|
|