Der große und schreckliche MT4 für immer (oder wie man einen Übergang strategisch plant) - Seite 13

 
JRandomTrader:

Hier ein Auszug aus der Dokumentation:

"DieReihenfolge, in der diese Transaktionen im Terminal eintreffen, ist nicht garantiert, so dass Sie Ihren Handelsalgorithmus nicht darauf aufbauen können, dass einige Transaktionen erst nach anderen eintreffen. " https://www.mql5.com/ru/docs/event_handlers/ontradetransaction

Und erfahrungsgemäß können die Transaktionen TRADE_TRANSACTION_ORDER_DELETE, TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_HISTORY_ADD in beliebiger Reihenfolge eintreffen.

Daher gibt es Situationen, in denen es noch keinen Deal oder keine Ordnung in der Geschichte gibt, die Ordnung aber bereits existiert. Oder umgekehrt: Der Auftrag ist noch da, aber das Geschäft wurde bereits ausgeführt. Aber die Situation, dass der Auftrag sowohl im Aktiven als auch in der Geschichte präsent ist, ist kaum möglich.

Ich halte die Ereignisse nicht fest, sondern betrachte das Gesamtbild auf einem neuen Tick.


JRandomTrader:

Das ist auch der Grund, warum ich mich geweigert habe, die CTrade-Klasse zu verwenden - sie tritt auf all diese Fallstricke.

Ich habe eine Lösung: Jeder EA führt eine Liste seiner Aufträge und überwacht deren Status. Dazu gehören "Nicht-Standard"-Status - "Auftrag gesendet, aber noch nicht in den aktiven Aufträgen vorhanden" (hier könnte es zu Doppelungen kommen), "Auftrag gelöscht, aber nicht in der Historie vorhanden". Das hilft auch bei der gleichzeitigen Arbeit am gleichen Symbol beim Netting.

Bis vor kurzem habe ich eine universelle Krücke benutzt, die auf fehlende Bestellungen geprüft hat. Aber irgendwann begann es zu versagen.

Ich habe dem Expert Advisor eine weitere persönliche Stütze hinzugefügt, die nun ihre eigenen Aufträge separat überwacht.

Das sind eine Menge Krücken...

 
Andrey Khatimlianskii:

Das sind eine Menge Krücken...

Untersuchung des Themas. Ich stoße sogar auf Folgendes: OrderSend market order true, dann PositionsTotal= 0, OrdersTotal = 0, historische Tabellen unverändert.

Es scheint gelungen zu sein, IsSynchronized() zu schreiben. Der Code ist ein wenig schwerfällig. Ich habe noch nicht entschieden, in welcher Form ich es veröffentlichen werde.

 
// Демонстрация открытия дубля позиции в MT5.

#include <Trade\Trade.mqh>

void OnStart()
{
  CTrade Trade;
  
  while (!IsStopped() && (PositionsTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (PositionsTotal() == 1)
      Trade.PositionClose(PositionGetTicket(0)); // Если есть позиция - закрываем.
    else if (!OrdersTotal())
      Trade.Buy(0.01); // Если нет позиции и ордера - открываем позицию.
}

Führen Sie diesen Code auf einem leeren Demokonto aus und sehen Sie, ob nach einigen Sekunden zwei Positionen eröffnet werden.


Die gleiche Logik auf MT4 sieht wie folgt aus.

void OnStart()
{
  while (!IsStopped() && (OrdersTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (OrderSelect(0, SELECT_BY_POS))
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0) // Если есть позиция - закрываем.
    else
      OrderSend(_Symbol, OP_BUY, 0.01, Ask, 0, 0, 0) // Если нет позиции и ордера - открываем позицию.
}

Es ist klar, dass ein solcher Code auf MT4 keine Positionsumkehr verursacht. Aber nicht auf MT5.

 
fxsaber:

Führen Sie diesen Code auf einem leeren Demokonto aus und sehen Sie, ob nach einigen Sekunden zwei Positionen eröffnet werden.


Die gleiche Logik auf MT4 sieht wie folgt aus.

Es ist klar, dass ein solcher Code auf MT4 keine Positionsumkehr verursacht. Aber nicht auf MT5.

Schließlich haben Sie es gerade erst entdeckt? Dieses Problem ist so alt wie das Terminal selbst. Aber schließlich haben es die Terminalnutzer bemerkt... nach einem Jahrzehnt.

Wenn Sie Handelsaktionen selbst durchführen, kann das Problem auf einfache Weise gelöst werden - durch Einfügen von Sleep() für eine Sekunde, nachdem die Aktion durchgeführt wurde. Aber wenn der EA Stoploss/Stockprofit und Marktschluss verwendet, besteht die Gefahr, dass dieses Problem auftritt, und in diesem Fall gibt es keine Lösung.

 
Dmitry Fedoseev:

Endlich! Haben Sie das gerade entdeckt? Dieses Problem ist so alt wie das Terminal selbst. Aber die Terminalnutzer haben es endlich bemerkt... nach einem Jahrzehnt.

Das Problem wird schon seit langem diskutiert. Fast jeder hat sie schon einmal erlebt. Es ist das erste Mal, dass ein stabiler Code dies reproduziert hat.

Wenn Sie selbst eine Handelsaktion durchführen, können Sie das Problem auf einfache Weise lösen - fügen Sie Sleep() für eine Sekunde ein, nachdem die Aktion durchgeführt wurde. Aber wenn Stop Loss/StackProfit und Marktschluss in einem EA verwendet werden, besteht die Gefahr, dass das Problem auftritt, und es gibt keine Lösung für diesen Fall.

Die Lösung ist gefunden.

 
fxsaber:

Führen Sie diesen Code auf einem leeren Demokonto aus und sehen Sie, ob nach einigen Sekunden zwei Positionen eröffnet werden.

Seltsam. Sie reproduziert sich nicht. Überprüft auf Demo von MQ, Build 2900, EURUSD, Null Spread. Ich habe etwa fünf Minuten gewartet.

Vielleicht muss ich einen bestimmten Server eines echten DC/Brokers verwenden und nicht den MQ-Server?

 
Ihor Herasko:

Seltsam. Sie reproduziert sich nicht. Überprüft auf Demo von MQ, Build 2900, EURUSD, Null Spread. Ich habe etwa fünf Minuten gewartet.

Vielleicht muss ich einen bestimmten Server eines echten DC/Brokers verwenden und nicht den MQ-Server?

ForexTimeFXTM-Demo01

 
fxsaber:

ForexTimeFXTM-Demo01

Ja, jetzt hält das Skript an. Aber es ist noch eine Stelle frei. Ich schätze, der zweite hat Zeit, sich zu schließen?

 
Ihor Herasko:

Ja, jetzt hält das Skript an. Aber es ist noch eine Stelle frei. Der zweite muss Zeit haben, sich zu schließen?

Ich habe immer zwei übrig. Wenn einer übrig bleibt, ist das ein noch größerer Fehler:

  1. PositionsTotal = 1 - sendet einen Auftrag zum Schließen.
  2. Dann ist PositionsTotal = 2 und der Auftrag von Punkt 1 ist abgeschlossen.
 
fxsaber:

Ich habe immer zwei übrig. Wenn einer übrig bleibt, ist das ein noch größerer Fehler:

  1. PositionsTotal = 1 - sendet einen Auftrag zum Schließen.
  2. Dann ist PositionsTotal = 2 und der Auftrag von Punkt 1 ist abgeschlossen.

Ja, das ist es, was ich meine. Es stellt sich heraus, dass es dem Skript gelingt, eine der Positionen zu schließen, obwohl es eigentlich zwei sind, aber PositionsTotal() gibt 1 zurück. Und dann, nach dem Schließen, ist die Bedingung des Schleifenabbruchs erfüllt, d.h. PositionsTotal() gibt 2 zurück.