Problem bei der Eingabe mehrerer Aufträge für ein Live-Konto bei einem bestimmten Broker - Seite 2

 
Malacarne:

HalloBlindMist, es ist sinnvoll, Ihre lokale Datenbank zu überprüfen, um festzustellen, ob Ihr Konto mit dem Broker-Server synchronisiert ist.

Bitte schauen Sie sich den vorgeschlagenen Beitrag an, um dieses Problem zu lösen.

Ich bin gerade den vorgeschlagenen Beitrag durchgegangen und es wird nicht erwähnt, wie man verhindern kann, dass Aufträge mehrfach ausgeführt werden...

Wie lange müssen Sie trotz der Funktion Sleep() warten, um sicher zu sein, dass der Handel fehlgeschlagen ist?...

In meinem EA hatte ich einen Auftrag senden Anfrage Zeit nach 10 Sekunden vor dem Versuch wieder... aber manchmal die Bestellung wird ausgeführt, 15-20 Sekunden nach der ersten Anfrage; so, was in unerwünschten doppelten Handel.

 
BlindMist:

Ich bin gerade den vorgeschlagenen Beitrag durchgegangen und es wird nicht erwähnt, wie man verhindert, dass Aufträge mehrfach ausgeführt werden...

Auch mit Sleep() Funktion, wie lange müssen Sie warten, um sicher zu sein, dass der Handel fehlgeschlagen ist?...

In meinem EA habe ich eine Order-Sendeanforderung nach 10 Sekunden auslaufen lassen, bevor ich es erneut versucht habe... aber manchmal wird die Order 15-20 Sekunden nach der ersten Anforderung ausgeführt, was zu einem unerwünschten Doppelhandel führt.

HalloBlindMist, meine Idee zu diesem Thema, dass ich immer noch denke, ist der einzige Weg, um es zu überprüfen (anstelle von nur einem Test von PositionSelect oder nur ein Sleep), ist so etwas wie ein fataler Fehler nach wartet eine lange Zeit, oder springen, sobald Sie das Symbol Position (Code unten) haben.

Das einzig Gute an diesem Problem ist, dass wahrscheinlich PositionSelect, früher oder später, die aktualisierte Position vom Server erhalten wird. Was wir also tun müssen, ist eine maximale Zeit (unser Timeout) zu warten, um einen fatalen Fehler anzuzeigen und kleine Proben zu machen, um zu überprüfen, ob es OK ist (100 ms in meinem Beispiel).

bool fatalError=false; // atention: declare this as global

....

if (fatalError==false) {
  if (m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0)) {
    Print("Position opened in ", Symbol());
    int maxTimeout=0;
    while (!PositionSelect(Symbol())) {
       Sleep(100);
       maxTimeout++;
       if (maxTimeout>100) {
          Print("### PositionSelect fatal error!");
          fatalError=true;
          break;
       }
    }
    Print("--> PositionSelect delay=",maxTimeout*100);
    break;
  }
}

Eine andere Möglichkeit, das Ganze modularer zu gestalten, ist die Erstellung einer Funktion zur Steuerung des Timeouts:

bool PositionSelectTimeout(string symbol,int timeout) 
  { // timeout in seconds
   int maxTimeout=0;
   while(!PositionSelect(symbol)) 
     {
      Sleep(100);
      maxTimeout++;
      if(maxTimeout>(timeout*10)) return(false); // fatal error (timeout)
     }
   return(true); // position selected
  }

Die Hauptidee hier ist, dass meine PositionSelectTimeout() die ursprüngliche PositionSelect() ersetzt, natürlich als Workaround, da nur MQ eine wirklich gute und endgültige Lösung ansprechen kann.

Ein Beispiel:

if (PositionSelectTimeout(Symbol(),60)) { // 60 seconds timeout
 ...
}

// instead of ...

if (PositionSelect(Symbol())) {
 ...
}

Meiner Meinung nach mussFinanceEngineer dasselbe tun, um das Problem zu beheben, und diesen Test in seine Schleife einfügen, um doppelt zu prüfen, ob die Position OK ist, um eine Pause zu machen.

 
figurelli:

HalloBlindMist, meine Idee zu diesem Thema, dass ich immer noch denke, ist der einzige Weg, um es zu überprüfen (statt nur ein Test von PositionSelect oder nur ein Sleep), ist so etwas wie ein fataler Fehler nach wartet eine lange Zeit, oder springen, sobald Sie das Symbol Position (Code unten) haben.

Das einzig Gute an diesem Problem ist, dass wahrscheinlich PositionSelect, früher oder später, die aktualisierte Position vom Server erhalten wird. Was wir also tun müssen, ist eine maximale Zeit zu warten (unser Timeout), um einen fatalen Fehler anzuzeigen und kleine Stichproben zu machen, um zu prüfen, ob es OK ist (100 ms in meinem Beispiel).

Eine andere Möglichkeit, das Ganze modularer zu gestalten, ist die Erstellung einer Funktion, die z. B. den Timeout kontrolliert:

Die Hauptidee hier ist, dass meine PositionSelectTimeout() die ursprüngliche PositionSelect() ersetzt, natürlich nur als Workaround, da nur MQ eine wirklich gute und endgültige Lösung ansprechen kann.

Zum Beispiel:

Meiner Meinung nach mussFinanceEngineer dasselbe tun, um das Problem zu beheben, und diesen Test in seine Schleife einfügen, um doppelt zu prüfen, ob die Position OK ist, um eine Pause zu machen.

Danke figurelli, sehr ausführliche Antwort. Ich werde es mal ausprobieren und sehen, ob es mein System verbessert.
 
BlindMist:
Danke figurelli, sehr ausführliche Antwort. Ich werde es ausprobieren und sehen, ob mein System dadurch besser wird.
Danke, gern geschehen.
 
BlindMist:

Ich bin gerade den vorgeschlagenen Beitrag durchgegangen und es wird nicht erwähnt, wie man verhindert, dass Aufträge mehrfach ausgeführt werden...

Auch mit Sleep() Funktion, wie lange müssen Sie warten, um sicher zu sein, dass der Handel fehlgeschlagen ist?...

In meinem EA hatte ich eine Bestellung senden Anfrage Zeit nach 10 Sekunden vor dem Versuch wieder... aber manchmal die Bestellung wird ausgeführt, 15-20 Sekunden nach der ersten Anfrage; so, was in unerwünschten doppelten Handel.

15 Sekunden für eine Auftragsausführung. Das ist wirklich schlecht. Das Problem hier ist, dass wir nichts vom Broker's Sever bekommen können (z.B. sogar ein einfaches Stück Code zur Statusüberprüfung, usw.)
 
FinanceEngineer:
15 Sekunden für eine Orderausführung. Das ist wirklich schlecht. Das Problem hier ist, dass wir nichts vom Broker's Sever bekommen können (z.B. sogar ein einfaches Stück Code zur Statusüberprüfung, etc)

HalloFinanceEngineer, Sie haben Recht, aber das erste, was zu verwalten ist, wählen Sie eine niedrige Latenz Broker, da die Märkte sind jedes Mal schneller, und es wird in der Regel solche Probleme sein.

Außerdem ist es immer gut, an den schlimmsten Fall zu denken, denn Sie können einen Broker mit niedriger Latenz haben, aber zu bestimmten Tageszeiten eine große Verzögerung, zum Beispiel wenn Sie wichtige Nachrichten haben.

Wie auch immer, OrderSend() in MT5 ist nicht so einfach zu handhaben wie MT4, da der von MT4 zurückgegebene Wert ein Ticket ist. Diese Änderung war bei MT5 notwendig, weil die asynchrone Kommunikation der Aktienmärkte, die in der MQL5-Architektur eingeführt wurde, die Kommunikation mit dem OMS-Protokoll des Brokers ermöglicht (wie z.B. FIX).

Aber ich denke, das ist die große Veränderung von OMS für die Auftragsverwaltung heute, da es sehr schwer ist, ein Echtzeit-Ticket zu bekommen, und MT5 ist auf dieses neue Szenario aktualisiert, vor allem, wenn wir Aktienmärkte verwenden, wo wir mehr Latenz haben.

In diesem Sinne ist das Wichtigste, was Sie nach einem OrderSend() bei MT5 tun, die Überprüfung von PositionSelect(), und ich empfehle dringend die Verwendung meines vorgeschlagenen Workarounds für PositionSelectTimeout(), aus allen oben genannten Gründen.

Die einzige Möglichkeit, die ich sehe, um über Worst Cases nachzudenken, ist die Verwaltung aller if { } else { } Bedingungen nach dem Senden einer Order an den Markt, so dass Sie jede Situation bewältigen können.

Ich würde auch gerne catch { } haben, aber wir können GetLastError() verwenden, um etwas Ähnliches zu tun.

Dies, weil Sie auch das Ticket benötigen, um eine Position zu bestätigen, und MT5 OrderSend() das Ticket nicht so synchron zurückgibt wie MT4 es tut.

 
BlindMist:

Ich bin gerade den vorgeschlagenen Beitrag durchgegangen und es wird nicht erwähnt, wie man verhindert, dass Aufträge mehrfach ausgeführt werden...

Auch mit Sleep() Funktion, wie lange müssen Sie warten, um sicher zu sein, dass der Handel fehlgeschlagen ist?...

In meinem EA hatte ich einen Auftrag senden Anfrage Zeit nach 10 Sekunden vor dem Versuch wieder... aber manchmal die Bestellung wird ausgeführt, 15-20 Sekunden nach der ersten Anfrage; so, was in unerwünschten doppelten Handel.

Dies ist mein Code, den ich derzeit verwende. Bis jetzt habe ich keine Probleme. Sie können diesen Code ausprobieren und sehen, ob er bei diesem Broker funktioniert.

      bool checkOrderSend = OrderSend(request, result);
     
      if(result.retcode==10009 || result.retcode==10008)
      {
          Print("OrderSend was successful. Code: ",result.retcode);

          
          break;
      }
      else
      {
          Print(ResultRetcodeDescription(result.retcode));
      }
     

 
FinanceEngineer:

Dies ist mein Code, den ich derzeit verwende. Bis jetzt habe ich keine Probleme. Sie können versuchen, diesen Code und wenn es funktioniert für diesen Makler.

      bool checkOrderSend = OrderSend(request, result);
     
      if(result.retcode==10009 || result.retcode==10008)
      {
          Print("OrderSend was successful. Code: ",result.retcode);

          
          break;
      }
      else
      {
          Print(ResultRetcodeDescription(result.retcode));
      }
     

Was machen Sie mit der checkOrderSend-Variable?

Wie verhindern Sie, dass mehrere Aufträge ausgeführt werden, ohne den Abschluss des Servergeschäfts zu überprüfen?

 
figurelli:

Was tun Sie mit der checkOrderSend-Variable?

Wie verhindern Sie, dass mehrere Aufträge ausgeführt werden, ohne den Abschluss des Servergeschäfts zu überprüfen?

Hallo figurelli

ich wollte damit sagen, dass man am Ende der OrderSend-Funktion sowohl den 10009- als auch den 10008-Code überprüfen sollte. Ich habe nämlich festgestellt, dass viele Leute nur einen der beiden Rückgabecodes (d.h. 10009 oder 10008) prüfen und viele Mehrfachaufträge erhalten, da sie normalerweise eine for-Schleife platzieren, um zu verhindern, dass keine Aufträge ausgeführt werden.

In meinem Fall wird meine for-Schleife 10 Mal versuchen, wenn ich keine Order mit diesem Broker erhalte. Wenn jemand also mehrere Orders erhält, sollte er prüfen, ob er seine Ordersending-Schleife stoppen kann, indem er sowohl 10009 als auch 10008 überprüft.

Ironischerweise ist es im Demokonto jedoch in Ordnung, nur einen Return Code zu überprüfen. Es wird Ihnen kein Problem mit Mehrfachbestellungen bereiten. Hier habe ich also festgestellt, dass sich Live-Konto und Demokonto leicht unterschiedlich verhalten.

Mit freundlichen Grüßen.

 
FinanceEngineer:

Hallo figurelli

ich wollte damit sagen, dass man am Ende der OrderSend-Funktion sowohl den 10009- als auch den 10008-Code prüfen sollte. Denn ich habe festgestellt, dass viele Leute nur einen der beiden Rückgabecodes (d.h. 10009 oder 10008) prüfen und viele Mehrfachaufträge erhalten, da sie normalerweise eine for-Schleife platzieren, um eine Situation ohne Auftrag zu vermeiden.

In meinem Fall wird meine for-Schleife 10 Mal versuchen, wenn ich keine Order bei diesem Broker erhalte. Wenn jemand also mehrere Orders erhält, sollte er prüfen, ob er seine Ordersending-Schleife stoppen kann, indem er sowohl 10009 als auch 10008 überprüft.

Ironischerweise ist es im Demokonto jedoch in Ordnung, nur einen Return Code zu überprüfen. Es wird Ihnen kein Problem mit Mehrfachbestellungen bereiten. Hier habe ich also festgestellt, dass sich Live-Konto und Demokonto leicht unterschiedlich verhalten.

Mit freundlichen Grüßen.

HalloFinanceEngineer, vielleicht wäre es besser, Ihren ursprünglichen Code zu überprüfen Mehrfachaufträge Problem, da, wenn wir dies tun, wahrscheinlich werden wir andere kritische Punkte hier zu adressieren und nicht den Fokus zu verlieren, was denken Sie darüber?