Mein EA macht einen doppelten Eintrag - Seite 7

 

wenn ich Schlaf benutze, verliere ich Zecken?

Was werden die Folgen sein? können mit mir teilen?

Documentation on MQL5: Common Functions / Sleep
Documentation on MQL5: Common Functions / Sleep
  • www.mql5.com
Common Functions / Sleep - Documentation on MQL5
 
doshur:

wenn ich Schlaf benutze, verliere ich Zecken?

Was sind die Folgen? Können Sie mir das mitteilen?

Das hängt von Ihrer Strategie ab. Da das Problem der "doppelten Trades" nur auftreten kann, wenn Ihr Handelscode bei jedem Tick ausgeführt wird, haben Sie wahrscheinlich eine Strategie, die vom Tick abhängt. Es liegt also an Ihnen zu bewerten, welche Folgen es haben kann, wenn Sie die Ticks verlieren, die während Ihrer Verzögerung (Schlaf) eintreffen.

 
angevoyageur:

Das hängt von Ihrer Strategie ab. Da das Problem der "doppelten Trades" nur auftreten kann, wenn Ihr Handelscode bei jedem Tick ausgeführt wird, haben Sie wahrscheinlich eine Strategie, die vom Tick abhängt. Es liegt also an Ihnen zu beurteilen, welche Folgen es haben kann, wenn Sie die Ticks verlieren, die während Ihrer Verzögerung (Schlaf) eintreffen.

Wenn ich also 800 Sekunden lang schlafe

bedeutet das, dass ich Ticks für die nächsten 800ms verliere? Nachdem ich meinen Handel eingeben, mein EA tut nichts, nur sitzt dort bis TP oder SL oder warten auf Zeit zu beenden.

Also meine Strategie ist in Ordnung, wenn ich Schlaf verwenden?

Ruft refreshrates() erhalten die Ticks zurück?

Documentation on MQL5: Common Functions / Sleep
Documentation on MQL5: Common Functions / Sleep
  • www.mql5.com
Common Functions / Sleep - Documentation on MQL5
 
doshur:

Wenn ich also 800 Sekunden lang schlafe

bedeutet, ich verliere Ticks für die nächsten 800ms? Nachdem ich meinen Handel eingeben, meine EA tut nichts, nur sitzt es bis TP oder SL oder warten auf Zeit zu beenden.

Also meine Strategie ist in Ordnung, wenn ich Schlaf verwenden?

Ruft refreshrates() erhalten die Ticks zurück?

Doshur, Ticks, dieSie verlieren, verlieren Sie, es gibt keine Wayback-Maschine.

Bezüglich der Dokumentation aufhttps://www.mql5.com/en/docs/common/sleepunterbricht die Funktiondie Ausführung des aktuellen Expert Advisors oder Skripts innerhalb eines bestimmten Intervalls.

Also werden auch OnTimer-Ereignisse unterbrochen, wahrscheinlich weil der EA nur einen Thread verwendet.

Also, verwenden Sie einen festen Sleep ist keine endgültige Lösung, ist nur "Numerologie", d.h., ein Workaround, wenn die Verzögerung niedriger als Ihr Wert ist.

Und deshalb schlage ich eine Schleife vor, die PositionSelect nach dem Öffnen des Handels testet, um die Ausführung von PositionOpen und die Rückkehr als bessere Lösung als nur Sleep() zu überprüfen, und die auch die Ursache des Problems (nachangevoyageur Tests) komprove.

Documentation on MQL5: Common Functions / Sleep
Documentation on MQL5: Common Functions / Sleep
  • www.mql5.com
Common Functions / Sleep - Documentation on MQL5
 

Das ist es, was ich jetzt benutze. Wo sollte ich die von figurelli angebotene Umgehung auf elegantere Weise codieren?

//
         {
            Price = SymbolInfoDouble(Symbol(), SYMBOL_ASK);

            if(m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0))
            {
               Sleep(800);

               if(m_Trade.ResultRetcode() == 10009)
               {
                  Print("Position opened in ", Symbol());

                  return;
               }
               else
               {
                  Print("Error opening position in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
               }
            }
            else
            {
               Print("Error with PositionOpen in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
            }
         }
 
doshur:

Das ist es, was ich jetzt verwende. Wo sollte ich die von figurelli angebotene Umgehung auf elegantere Weise codieren?

Hallo doshur, ich hatte auch Probleme mit doppelten Einträgen in einem meiner EAs. Eigentlich traten diese Probleme nur auf, wenn ich mit hochliquiden Assets gehandelt habe. Selbst nach der Einstellung, dass Orders im asynchronen Modus gesendet werden, wartete der EA "anscheinend" zu lange auf eine Serverantwort, um PositionsTotal() zu aktualisieren... in der Zwischenzeit lösten andere eingehende Ticks die Bedingungen zum Senden einer zweiten Order aus... im portugiesischen Forum habe ich einen Workaround gepostet, den ich hier gerne teilen möchte.

Die Idee ist einfach:

//--- global variables
CTrade trade;
bool position_opened=false;

//--- inside OnTick()
if( conditions to open && position_opened==false )
  {
   //--- set the global variable to true to avoid duplicate orders
   position_opened=true;
   trade.PositionOpen(_Symbol,order_type,lot,price,sl,tp,"comment");
  }

Das einzige Problem bei diesem Code ist der Fall, dass die Bestellung vom Server nicht angenommen wird, so dass Sie die globale Variable "zurücksetzen" müssen... Sie könnten dies verwenden:

MqlTradeResult mresult;

//--- 
if(mresult.retcode==10009 || mresult.retcode==10008)
  {Print("Success!");}
else 
  {
   Print("Error = ",GetLastError());
   ResetLastError();
   //--- Sets the global variable to false
   position_opened=false;
   return;
  }

Wenn der erste gesendete Auftrag einen Fehler zurückgibt, wird die globale Variable auf false gesetzt, damit der EA einen weiteren Auftrag senden kann. Allerdings muss ich sagen, dass ich diesen Code nur in Aktien und Futures getestet habe, aber nicht im Forex-Markt... :-(

 
Malacarne:

Hallo doshur, ich hatte auch Probleme mit doppelten Einträgen in einem meiner EAs. Eigentlich traten diese Probleme nur auf, wenn ich mit hochliquiden Assets handelte. Selbst nach der Einstellung, dass Orders im asynchronen Modus gesendet werden, wartete der EA "anscheinend" zu lange auf eine Serverantwort, um PositionsTotal() zu aktualisieren... in der Zwischenzeit lösten andere eingehende Ticks die Bedingungen aus, um eine zweite Order zu senden... im portugiesischen Forum habe ich einen Workaround gepostet, den ich hier gerne teilen möchte.

Die Idee ist einfach:

Das einzige Problem bei diesem Code ist der Fall, dass die Bestellung vom Server nicht angenommen wird, so dass Sie die globale Variable "zurücksetzen" müssen... Sie könnten dies verwenden:

Wenn der erste gesendete Auftrag einen Fehler zurückgibt, wird die globale Variable auf false gesetzt, damit der EA einen weiteren Auftrag senden kann. Allerdings muss ich sagen, dass ich diesen Code nur in Aktien und Futures getestet habe, aber nicht im Forex-Markt... :-(

Das scheint machbar zu sein. Mal sehen, obfigurelli undangevoyageur irgendwelche Kommentare zu diesem Workaround haben...
 
doshur:
Das scheint machbar zu sein. Mal sehen, obfigurelli undangevoyageur irgendwelche Kommentare zu diesem Workaround haben...

Die von Malacarne vorgeschlagene Lösung (mit einigen Anpassungen, die ich vorschlagen werde) ist großartig, da es sich für mich nicht um einen Workaround handelt (wie Malacarne bescheiden sagt), sondern um einen eleganten und richtigen Weg, diese Frage anzugehen.

Meiner Meinung nach ist das ursprüngliche Problem der Doppeleingabe kein MT5-Fehler, sondern ein Programmierfehler, denn in der Hilfe steht:

"Dererfolgreiche Abschluss der Methode PositionOpen(...) bedeutet nicht immer die erfolgreiche Ausführung der Handelsoperation. Es ist notwendig, das Ergebnis der Handelsanfrage (Returncode des Handelsservers) mitResultRetcode() und dem vonResultDeal() zurückgegebenen Wert zu überprüfen."

Ich schlage also einige kleine Änderungen vor, um widerstandsfähiger gegen jede Marktbedingung zu sein:

1) Testen Sie die Rückgabe von PostionOpen() ebenfalls, zum Beispiel als den ursprünglichen Code:

if (trade.PositionOpen(_Symbol,order_type,lot,price,sl,tp,"comment")) position_opened=true;

2) Eine vollständigere Behandlung von ResultRetcode(), da man andere relevante Positionen öffnen lassen kann, wie z.B. 10010 -TRADE_RETCODE_DONE_PARTIAL - Nur ein Teil der Anfrage wurde abgeschlossen. Auch 10008 - TRADE_RETCODE_PLACED - Order placed ist für mich kein Erfolg, sondern nur 10009 -TRADE_RETCODE_DONE -Request completed, und das sind asynchrone Nachrichten, so dass der zweite Teil des Malacarne-Codes dies und/oder dasDeal-Ticket berücksichtigen könnte, nachdem der Deal ausgeführt wurde.

Wie dem auch sei, für mich sieht es so aus, als ob wir jetzt auf dem richtigen Weg und dem endgültigen Schnitt sind.

 
Malacarne:

Hallo doshur, ich hatte auch Probleme mit doppelten Einträgen in einem meiner EAs. Eigentlich traten diese Probleme nur auf, wenn ich mit hochliquiden Assets gehandelt habe. Selbst nach der Einstellung, dass Orders im asynchronen Modus gesendet werden, wartete der EA "anscheinend" zu lange auf eine Serverantwort, um PositionsTotal() zu aktualisieren... in der Zwischenzeit lösten andere eingehende Ticks die Bedingungen aus, um eine zweite Order zu senden... im portugiesischen Forum habe ich einen Workaround gepostet, den ich hier gerne teilen möchte.

Die Idee ist einfach:

Das einzige Problem bei diesem Code ist der Fall, dass die Bestellung vom Server nicht angenommen wird, so dass Sie die globale Variable "zurücksetzen" müssen... Sie könnten dies verwenden:

Wenn der erste gesendete Auftrag einen Fehler zurückgibt, wird die globale Variable auf false gesetzt, damit der EA einen weiteren Auftrag senden kann. Allerdings muss ich sagen, dass ich diesen Code nur in Aktien und Futures getestet habe, aber nicht im Forex-Markt... :-(

Das ist ein guter Ansatz, aber Sie müssen Ihre globale Variable position_opened auf false zurücksetzen, wenn Ihre Position geschlossen wird. Wo machen Sie das?

Zu Ihrer Implementierung, einige Details :

  1. Es besteht keine Notwendigkeit, position_opened auf true und dann auf false zu setzen, wenn ein Fehler auftritt.
  2. Sie verwenden ein Objekt der CTrade-Klasse, daher ist es nicht notwendig, eine neue MqlTradeResult-Struktur zu verwenden.
  3. Wie figurelli in seinem Beitrag erwähnt hat, müssen Sie den zurückgegebenen Wert von PositionOpen überprüfen.
  4. Der Name der Klasse ist CTrade, nicht Ctrade. mql5 unterscheidet zwischen Groß- und Kleinschreibung.
  5. position_opened ist ein bool, es muss nicht mit false verglichen werden. Wenn Sie das tun, müssen Sie '==' und nicht '=' verwenden.

Hier ist also der geänderte Code(kompiliert, aber nicht getestet):

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>

//--- global variables
CTrade trade;
bool position_opened=false;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   bool conditions_to_open;
   ENUM_ORDER_TYPE order_type;
   double lot;
   double price,sl,tp;

//---...set variables

//--- inside OnTick()
   if(conditions_to_open && !position_opened) //-- Or position_opened==false
     {
      if(trade.PositionOpen(_Symbol,order_type,lot,price,sl,tp,"comment")
         && 
         (trade.ResultRetcode()==10009 || trade.ResultRetcode()==10008)) //-- Or others condition according to your needs
        {
         //--- set the global variable to true to avoid duplicate orders
         position_opened=true;
         Print("Success!");
        }
      else
        {
         Print("Error = ",GetLastError(), "trade error = ", trade.ResultRetcode());
         //--- Sets the global variable to false
         // position_opened=false;                                         //-- Not needed as position_opened is already false
         return;
        }

     }
//--- 
  }
//+------------------------------------------------------------------+
 
figurelli:

...

Meiner Meinung nach ist das ursprüngliche Problem der Doppeleingabe kein MT5-Fehler, sondern ein Kodierungsfehler, da in der Hilfe steht:

"Dererfolgreiche Abschluss der Methode PositionOpen(...) bedeutet nicht immer die erfolgreiche Ausführung der Handelsoperation. Es ist notwendig, das Ergebnis der Handelsanfrage (Returncode des Handelsservers) mitResultRetcode() und dem vonResultDeal() zurückgegebenen Wert zu überprüfen."

Ich glaube nicht, dass dies mit dem Problem dieses Themas zusammenhängt. Das Problem tritt auf, wenn eine Anfrage erfolgreich ausgefüllt wurde und eine Position eröffnet wurde. Aber diese Position wird auf dem Handelsserver geöffnet, das Problem, das wir angetroffen haben, ist, dass es eine größere Verzögerung als üblich gibt und das MT5-Terminal über diese neue Position benachrichtigt wird, NACHDEM ein neuer Tick bereits verarbeitet wurde.

Es ist kein Fehler, da es auf diese Weise konzipiert ist. ABER meiner Meinung nach ist es ein schlechtes Design für eine Plattform, die ausdrücklich synchrone und asynchrone Handelsanfragen erlaubt. Wir sprechen hier von einer Anfrage, die eigentlich synchron sein sollte, aber in Wirklichkeit ist sie nicht wirklich synchron, da wir, wenn wir die Antwort vom Server für die Anfrage erhalten (trade.ResultRetCode im obigen Code), immer noch darauf warten müssen, dass die MT5-Plattform über die Handelsergebnisse informiert und aktualisiert wird. (Ich habe das alles mit diesem Thread verstanden).

Daher schlage ich einige kleine Änderungen vor, um widerstandsfähiger gegen jede Marktbedingung zu sein:

1) Testen Sie auch die Rückgabe von PostionOpen(), wie zum Beispiel im ursprünglichen Code:

2) Eine vollständigere Behandlung von ResultRetcode(), da man andere relevante Positionen öffnen lassen kann, wie z.B. 10010 -TRADE_RETCODE_DONE_PARTIAL - Nur ein Teil der Anfrage wurde abgeschlossen. Auch 10008 - TRADE_RETCODE_PLACED - Order placed ist für mich kein Erfolg, sondern nur 10009 -TRADE_RETCODE_DONE -Request completed, und das sindasynchrone Nachrichten, so dass der zweite Teil des Malacarne-Codes dies und/oder dasDeal-Ticketberücksichtigen könnte, nachdem der Deal ausgeführt wurde.

Wie auch immer, für mich sieht es so aus, als ob wir jetzt auf dem richtigen Weg sind und den endgültigen Schnitt machen.

Sie haben natürlich völlig Recht, dass man den zurückgegebenen Wert von PositionOpen UND den zurückgegebenen Code des Handelsergebnisses prüfen muss. Allerdings ist der ResultRetCode synchron, es ist die Aktualisierung der MT5-Datenbank über die Position (Deal und Order), die asynchron ist. Der Test, den ich mit Ihrem Vorschlag durchgeführt habe, hat dies gezeigt, da ich natürlich einen Code verwendet habe, der den zurückgegebenen Wert der Handelsanfrage überprüft hat.
Grund der Beschwerde: