Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools

Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools (http://www.expert-advisor.com/forum/index.php)
-   Programmierung MQL4 (http://www.expert-advisor.com/forum/forumdisplay.php?f=220)
-   -   Mehrere Orders eröffnen nach Signal (http://www.expert-advisor.com/forum/showthread.php?t=6746)

Michael_ 13.08.20 10:49

Mehrere Orders eröffnen nach Signal
 
Hallo zusammen,

ich habe eine Frage zur EA-Programmierung. Und zwar hab ich einen EA, der bei gültigem Signal 2 Orders eröffnet (z.B. bei einem Long-Signal: "LongOrder1" und "LongOrder2"). Diese beiden Orders haben zusammen ein definiertes Risiko, z.B. 1%, und werden danach aufgeteilt (z.B. 70% zu 30%).

Nun zur Frage: Falls diese beiden Orders noch offen sind, und es ergibt sich ein weiteres Long-Signal, will ich eine "LongOrder3" und "LongOrder4" eröffnen. Ich bin sicher, dass das geht, allerdings weiß ich nicht, wie ich das angehen soll. Für "LongOrder1" und "LongOrder2" werden nach Eröffnung SL und TP speziell für deren Name gesetzt, ebenfalls danach ein Trailing Stop.

Geht das irgendwie mit IntegerToString, wo mit einer for-Schleife raufgezählt wird? Oder würde das unkomplizierter funktionieren?

Danke gleich für eure Antworten!

Lieben Gruß,
Michael

Max2018 13.08.20 11:31

Hi,
das sind mir ein wenig Infos.... eröffnet der EA zwei Posotionen mit einem Signal oder beim ersten Signal eine und dann noch eine nach dem zweiten Signal wieder eine.....
Irgendwo im Code müsste das ja geregelt sein.... :o Gut wäre wenn Du den Teil des Codes hier mal zeigen könntest, dann kann man mehr dazu sagen.....

TraumExpert 14.08.20 08:29

Hallo Michael,

Die Frage ist in erster LInie mal ob Du damit nicht Dein Risikomanagment austrickst? Das ist aber eher eine Frage des Tradings.

Schick ein ein Stück Code.

Gruß

Michael_ 14.08.20 09:49

Hallo zusammen,

es ist so, dass bei einem Signal (machen wir als Beispiel Long) immer 2 Positionen eröffnet werden. Also "LongOrder1" und "LongOrder2". Da wird zusammen 1% riskiert (also z.B. 0,7% für LongOrder1 und 0,3% für LongOrder2).

Es ist aber auch möglich, dass sich ein weiteres Long-Signal nach z.B. 5 Stunden ergibt. Dann soll der EA weitere 2 Long-Orders setzen (wieder mit 1% Risiko), allerdings mit anderem SL (klar, da der Kaufkurs auch ein anderer ist).

Beispiel-Code ist folgender:

Code:

if(LongSignal == true)
  {
        //Positionsgröße berechnen
        double SL_Euro = AccountBalance()*SL_Prozent/100;                                 

        //SL in Punkten und als Absolutwert definieren:
        double SL_Long_Punkte = 50;            //Beispiel 50 Punkte als SL im DAX30
        double SL_Long = MarketInfo(Symbol(),MODE_ASK) - SL_Long_Punkte;

        //Positionsgröße berechnen (Lot-Size) + Aufteilung Lot-Size auf 2 Positionen:
        double LotSize_Long = MathFloor(SL_Euro/SL_Long_Punkte);
        double LotSize_Long1 = MathRound(LotSize_Long*Position1_Prozent/100);        //Lot-Size Position1 für Long-Position; bei z.B. 0.3 Lots = 0.2 Lots
        double LotSize_Long2 = MathRound(LotSize_Long - LotSize_Long1);            //Lot-Size Position2 für Long-Position; bei z.B. 0.3 Lots = 0.1 Lots

        //Take-Profit in Punkten berechnen (2 Positionen):     
        double TP_Long1_Punkte = MathRound(SL_Long_Punkte * TP_Prozent1);
        double TP_Long2_Punkte = MathRound(SL_Long_Punkte * TP_Prozent2);         
        double TP_Long1 = TP_Long1_Punkte + MarketInfo(Symbol(),MODE_BID) + MarketInfo(Symbol(),MODE_SPREAD)*Point;                          //Absoluter TP für Long-Order 1
        double TP_Long2 = TP_Long2_Punkte + MarketInfo(Symbol(),MODE_BID) + MarketInfo(Symbol(),MODE_SPREAD)*Point;                          //Absoluter TP für Long-Order 2


        //Long-Order1 eröffnen
        while(LongOrder1<=0)               
            {
              LongOrder1 = OrderSend(Symbol(),OP_BUY,LotSize_Long1,Ask,10,0,0,"LONG Position 1",MagicNummer,0,Green);
              if(LongOrder1<0)
                  {
                    Print("OrderSend LongOrder1 failed with error #",GetLastError());
                  }
              else
                  Print("OrderSend LongOrder1 placed successfully");
            }

          //Long-Order2 eröffnen
          while(LongOrder2<=0)               
            {
              LongOrder2 = OrderSend(Symbol(),OP_BUY,LotSize_Long2,Ask,10,0,0,"LONG Position 2",MagicNummer,0,Green);
              if(LongOrder2<0)
                  {
                    Print("OrderSend LongOrder2 failed with error #",GetLastError());
                  }
              else
                  Print("OrderSend LongOrder2 placed successfully");
            }

//SL Long Positionen setzen
if(OrderSelect(LongOrder1,SELECT_BY_TICKET)==true)                     
      {
        if(OrderCloseTime()==0 && OrderStopLoss()==0)                   
            {
              bool OrderAngepasst = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(SL_Long,Digits()),OrderTakeProfit(),0,Yellow);
            }
      }
 
  if(OrderSelect(LongOrder2,SELECT_BY_TICKET)==true)                     
      {
        if(OrderCloseTime()==0 && OrderStopLoss()==0)                   
            {
              bool OrderAngepasst = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(SL_Long,Digits()),OrderTakeProfit(),0,Yellow);
            }
      }


//TP Long Positionen setzen
  if(OrderSelect(LongOrder1,SELECT_BY_TICKET)==true)                     
      {
        if(OrderCloseTime()==0 && OrderTakeProfit()==0)                 
            {
              bool OrderAngepasst = OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),TP_Long1,0,Orange);
            }
      }
 
  if(OrderSelect(LongOrder2,SELECT_BY_TICKET)==true)                     
      {
        if(OrderCloseTime()==0 && OrderTakeProfit()==0)
            {
              bool OrderAngepasst = OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),TP_Long2,0,Orange);
            }
      }
}

Danach folgt noch ein Code für einen Trailing Stop, der mit folgender Funktion aufgerufen wird:

Code:

if(OrderSelect(LongOrder1,SELECT_BY_TICKET)==true && OrderCloseTime() == 0)
  {
...
  }


if(OrderSelect(LongOrder2,SELECT_BY_TICKET)==true && OrderCloseTime() == 0)
  {
...
  }


Wie ihr seht, definiere ich immer klar die "LongOrder1" und "LongOrder2" für alle Funktionen. Die obige SL und TP-Berechnung sollte global möglich sein, die OrderSend-Funktion müsste aber irgendwie angepasst werden (damit nicht wieder "LongOrder1" und "LongOrder2" definiert wird, sondern "LongOrder3" und "LongOrder4"), ebenfalls die Trailing Stop Funktion.

Das geht ganz sicher, ich weiß nur leider nicht wie es genau geht und dabei auch am effizientesten ist.

Danke gleich für eure Hilfe! :)

Lieben Gruß,
Michael

TraumExpert 14.08.20 10:22

OK Du fragst die Ticketnummer <0 ab um eine neue Order zu eröffnen.
Also liegt hier schon mal ein Problem. Was könntest Du denn statt dessen verwenden?

Michael_ 15.08.20 18:55

Hallo,

Zitat:

Zitat von TraumExpert (Beitrag 44245)
OK Du fragst die Ticketnummer <0 ab um eine neue Order zu eröffnen.
Also liegt hier schon mal ein Problem. Was könntest Du denn statt dessen verwenden?

Genau, das ist meine Absicht. Mein Wunsch wäre es (falls möglich), dass dann immer bei einem Long-Signal eine "LongOrder1" und "LongOrder2" eröffnet wird. Sofern es diese beiden Orders noch gibt, und es nochmal ein Long-Signal gibt, dann soll der EA weitere 2 Orders eröffnen, und zwar mit der Bezeichnung "LongOrder3" und "LongOrder4".

Was ich damit zu deinem Kommentar sagen will: Ich frag ja mit while(LongOrder1<=0) und while(LongOrder2<=0) ab, ob es eine solche Order gibt. Falls es diese Order schon gibt, soll er bei einem weiteren Long-Signal noch eine "LongOrder3" und "LongOrder4" eröffnen.

Geht das so oder muss ich den Code komplett umwerfen? Ich denke, es könnte einfach möglich sein (zumindest hoffe ich das).

Liebe Grüße,
Michael

TraumExpert 17.08.20 08:19

Hmmm Michael, wenn es Deine Absicht ist immer einen Auftrag zu senden, wenn es noch keine Ticket (Order) gibt. Bei der Frage des Tickets ist es übrigens egal ob die Order ausgeführt oder noch schwebend ist. Aber egal in dem Fall ist Abfrage in Ordnung! So wie ich das verstanden habe willst Du aber immer einen Order aufgeben wenn es ein (neues!) Signal gibt. Dann darfst Du aber auch nicht auf eine vorhandene Order abfragen sondern muss auf das Signal abfragen. Darüber hinaus muss Du Dir überlegen, wie Du auf das neue Signal abfragst. Das heißt wie willst Du feststellen das es sich tatsächlich um ein neues Signal handelt.

Gruß

Michael_ 25.08.20 11:06

Hallo zusammen,

erst mal sorry für die späte Rückmeldung, ich war auf Urlaub :)
Zu deinem Kommentar:

Zitat:

Zitat von TraumExpert (Beitrag 44254)
Hmmm Michael, wenn es Deine Absicht ist immer einen Auftrag zu senden, wenn es noch keine Ticket (Order) gibt. Bei der Frage des Tickets ist es übrigens egal ob die Order ausgeführt oder noch schwebend ist. Aber egal in dem Fall ist Abfrage in Ordnung! So wie ich das verstanden habe willst Du aber immer einen Order aufgeben wenn es ein (neues!) Signal gibt. Dann darfst Du aber auch nicht auf eine vorhandene Order abfragen sondern muss auf das Signal abfragen. Darüber hinaus muss Du Dir überlegen, wie Du auf das neue Signal abfragst. Das heißt wie willst Du feststellen das es sich tatsächlich um ein neues Signal handelt.

Gruß

Genau, du sagst es: Ich will weitere 2 Orders aufgeben, wenn es ein neues Long-Signal gibt. Das Problem hab ich bereits gelöst, d.h. ich weiß, wann es neue Signale gibt. Die offene Frage ist nur noch, wie man die Orders dann auch umsetzt, wenn es bestehende Orders gibt.

Eventuell mit einem Counter, der die offenen Orders zählt, und nachfolgend einer for-Schleife (beginnend mit dem Counter+1) und dann einer Umwandlung des Integers der for-Schleife mit IntegerToString? Danach kann man ja 2 Strings kombinieren mit einem "+". Allerdings ist das dann ein String, und bei der OrderSend Funktion benötigt man einen Integer...

Leider schaff ich die richtige Programmierung derzeit nicht...

Lieben Gruß,
Michael

Michael_ 25.08.20 21:49

Hallo und guten Abend,

ich hatte etwas Zeit zum Programmieren. Ich hab das Problem gelöst, bin mir aber nicht sicher, ob das im Realbetrieb auch funktioniert. Deshalb zu folgender Frage:

Ich mach ja derzeit mit der while-Schleife (while(LongOrder1<=0) bzw. while(LongOrder2<=0)) die Long-Orders mit "OrderSend" auf. Ist das so notwendig oder genügt ein einfacher Befehl wie "int LongOrder = OrderSend(...)"? Gibt's da Probleme im Livebetrieb?

Danke gleich für eure Antworten!

Lieben Gruß,
Michael

Indikator-Trading 25.08.20 22:26

Die While-Schleife ist dafür gedacht, dass du so lange versuchst eine Order zu senden, bis es auch endlich mal gekappt hat.
Das Problem an einer While-Schleife ist allerdings, dass du ggf. für immer in ihr gefangen bist. Ich würde es so auf keinen Fall nutzen.

Folgendes Gedankenspiel:

Das Öffnen der ersten Order funktioniert wunderbar. SL und TP sind ja nicht gesetzt, also auch keine Risikoabsicherung vorhanden.
Jetzt willst du in der zweiten While-Schleife die zweite Order senden, aber die Lotgröße ist falsch gewählt, z.B. nicht erlaubt(DAX mit 0.001 Lot z.B.). Du hängst jetzt in dieser While-Schleife fest, da jedes mal ein ErrorCode (131 / "Invalid trade volume") gesendet wird, und dir die OrderSend-Funktion aber eine -1 zurück liefern wird.
Der erste Trade läuft mal so richtig gegen dich und du bist pleite...


Gruß Timo


Alle Zeitangaben in WEZ +2. Es ist jetzt 15:54 Uhr.

Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.6.1
Powered by vBCMS® 2.7.0 ©2002 - 2024 vbdesigns.de
Copyright ©2009 - 2023 by Expert-Advisor.com - Das Metatrader Forum