Bibliotheken: MT4Orders - Seite 63

 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Bibliotheken: MT4Orders

fxsaber, 2021.06.02 10:09

Auf meine Bitte hin, hat die MetaQutoes das letzte Update der Bibliothek komplett ins Englische lokalisiert. Der neueste Build der Bibliothek ist nun auf der englischen Seite verfügbar, mit ins Englische übersetzten Kommentaren im Quellcode.


Dies unterscheidet sich von der vorherigen Version, die auf der englischsprachigen Seite verfügbar war.

// Liste der Änderungen:
// 02.11.2018
// Fix: Jetzt kann der MT4-Positions-Open-Preis nicht mehr Null sein, bevor er ausgelöst wird.
// Fix: Einige seltene Ausführungsaspekte von bestimmten Handelsservern wurden berücksichtigt.
// 26.11.2018
// Fix: Magie und Kommentar einer geschlossenen MT4-Position: Die Priorität der relevanten Felder von öffnenden Transaktionen ist höher als die von schließenden.
// Fix: Seltene Änderungen in MT5-OrdersTotal und MT5-PositionsTotal werden bei der Berechnung von MT4-OrdersTotal und MT4-OrderSelect berücksichtigt.
// Fix: Bibliothek berücksichtigt nicht die Aufträge, die eine Position eröffnet haben, aber noch nicht aus MT5 gelöscht wurden.
// 17.01.2019
// Fix: Ein unglücklicher Fehler bei der Auswahl schwebender Aufträge wurde behoben.
// 08.02.2019
// Hinzufügen: Kommentar einer Position wird bei teilweiser Schließung über OrderClose gespeichert.
// Wenn Sie den Kommentar zu einer offenen Position bei teilweiser Schließung ändern müssen, können Sie ihn in OrderClose angeben.
// 20.02.2019
// Fix: Falls kein MT5-Auftrag vorliegt, erwartet die Bibliothek die Synchronisierung der Historie von der bestehenden MT5-Transaktion. Im Falle eines Fehlers wird sie darüber informieren.
// 13.03.2019
// Add: OrderTicketID() hinzugefügt - PositionsID einer MT5-Transaktion oder MT5-Position und das Ticket einer ausstehenden MT4-Order.
// Hinzufügen: SELECT_BY_TICKET funktioniert für alle MT5-Tickets (und MT5-PositionID).
// 02.11.2019
// Fix: Lot, Kommission und Close-Preis für CloseBy-Positionen korrigiert.
// 12.01.2020
// Fix: OrderTicketID() für Balance Deals gibt jetzt einen korrekten Wert zurück.
// Fix: SELECT_BY_TICKET - Auswahl nach OrderTicketID() (MT5-PositionID) korrigiert.
// Korrektur: Der Name der internen Bibliotheksmethode wurde geändert, um die Kompatibilität mit Makros zu verbessern.
// 10.04.2020
// Fix: Teilweise ausgeführte Live-Pending-Order wurde nicht in OrdersTotal() aufgenommen.
// 09.06.2020
// Add: StopLoss/TakeProfit/ClosePriceRequest für geschlossene Positionen sind jetzt besser definiert.
// 10.06.2020
// Hinzufügen: Millisekunden hinzugefügt, Preis- und Auftragsrundung in OrderPrint() entfernt.
// 13.08.2020
// Hinzufügen: Es wurde die Möglichkeit hinzugefügt, die Leistung von Bibliotheksteilen über das Makro MT4ORDERS_BENCHMARK_MINTIME zu überprüfen.
// 20.08.2020
// Korrektur: Berücksichtigung der aufgedeckten Merkmale der Ausführung von Teilaufträgen.
// 29.08.2020
// Fix: Schnelleres Arbeiten mit der Historie von Trades implementiert.
// 24.09.2020
// Hinzufügen: Wenn Sie die Priorität eines MT5-Auftrags gegenüber einer MT5-Position bei der Auswahl eines Live-MT4-Auftrags durch SELECT_BY_TICKET (dieselben Tickets) erhöhen müssen,
// Dies kann durch eine negative Änderung der Ticketgröße erreicht werden: OrderSelect(-Ticket, SELECT_BY_TICKET).
// Hinzufügen: Wenn Sie bei der Änderung eines Live-MT4-Auftrags (dieselben Tickets) nur die Auswahl eines MT5-Auftrags angeben müssen,
// Dies kann durch eine negative Änderung der Ticketgröße geschehen: OrderModify(-Ticket, ...).
// Hinzufügen: OrderSelect(INT_MAX, SELECT_BY_POS) - Wechsel zu einer MT5-Position ohne Überprüfung der Existenz und Aktualisierung.
// OrderSelect(INT_MIN, SELECT_BY_POS) - Wechsel zu einer Live-MT5-Order ohne Überprüfung der Existenz und Aktualisierung.
// Fix: Schnelleres Arbeiten mit der Historie von Trades implementiert.
// 30.09.2020
// Fix: Schnelleres Arbeiten mit der Historie von Trades implementiert.
// 08.10.2020
// Fix: OrderSend einer Market Order konnte aufgrund eines Fehlers in einer frischen MT5-Geschäftssuche länger ausgeführt werden.
// 21.10.2020
// Hinzufügen: Um Kompatibilität für MT4 zu gewährleisten, wurde OrderTicketID() hinzugefügt - gibt OrderTicket() zurück.
// 11.11.2020
// Korrektur: OrderTicketID() und OrderTicketOpen() geben den in TICKET_TYPE angegebenen Werttyp zurück.
// 06.12.2020
// Fix: Die Fälle von falschen SL/TP-Ausführungsaufzeichnungen in der MT5-Handelshistorie werden nun berücksichtigt.
// Hinzufügen: Der Markt MT4ORDERS_TESTER_SELECT_BY_TICKET zwingt SELECT_BY_TICKET im Tester nur über OrderTicketID() zu funktionieren.
// 04.05.2021
// Fix: Die MT5-Aufträge, die Positionen eröffnen und nicht verschwinden, werden nicht mehr zur Liste der MT4-Aufträge hinzugefügt.
// Fix: CloseBy MT5 Aufträge erscheinen nicht mehr in der Liste der MT4 Aufträge.
// 12.05.2021
// Hinzufügen: Das Makro MT4ORDERS_BYPASS_MAXTIME ändert die ständig auftretenden Fälle von Desynchronisation der Handelsumgebung im MT5.
// 13.05.2021
// Fix: Fehler in OrderOpenReason() behoben.
// 14.05.2021
// Korrektur: Der BYPASS-Mechanismus wirkt sich nicht mehr auf OrderSelect(INT_MAX, SELECT_BY_POS) und OrderSelect(INT_MIN, SELECT_BY_POS) aus.
// 01.06.2021
// Fix: Kompatibilität mit dem Compiler-Build 2449 und höher.
// Fix: Verbesserte Synchronisation. ByPass.mqh muss auf dem neuesten Stand sein.
// Hinzufügen: OrderLots(true) - synchronisierte Größe der ausgewählten Position, wobei alle Aufträge berücksichtigt werden, die diese Position schließen.


Ich empfehle die Verwendung der neuesten Version zusammen mit dem Synchronisationsmechanismus. Dann werden alle Probleme, die keine andere Handelsbibliothek lösen kann, nicht mehr wahrnehmbar sein.

#define  MT4ORDERS_BYPASS_MAXTIME 1000000 // Maximale Zeit (in Mikrosekunden), die auf die Synchronisierung der Handelsumgebung gewartet wird
#include <MT4Orders.mqh> // https://www.mql5.com/en/code/16006

Damit dieser Mechanismus funktioniert, müssen Sie diese Bibliothek herunterladen. Alle komplexen und effektiven Prüfungen der Korrektheit der Handelsumgebung werden automatisch durchgeführt, ohne den Benutzer beim Schreiben der Handelslogik abzulenken.

 
MT4Orders (+ByPass) funktioniert nur mit HistorySelect(0, INT_MAX), so dass es nicht die aktuellen Probleme mit dem Hinzufügen von gerade gelöschten Aufträgen am Ende der History-Tabelle (+Synchronisation) verursacht .
 
fxsaber:
MT4Orders (+ByPass) funktioniert nur mit HistorySelect(0, INT_MAX), so dass es nicht die aktuellen Probleme mit dem Hinzufügen von gerade gelöschten Aufträgen am Ende der History-Tabelle (+sync) verursacht .

Kaputt! Ich empfehle nicht, MT5 zu aktualisieren. Wer es versteht, dem sei erklärt, dass das bisherige Verhalten von MT5 korrekt war. Jetzt ist es das nicht mehr.

 
fxsaber:

Kaputt! Ich empfehle nicht, MT5 zu aktualisieren. Wer es versteht, dem sei erklärt, dass das bisherige Verhalten von MT5 korrekt war. Jetzt ist es nicht.

Traurig.

Ich habe einen Code skizziert, wie man das Einfügen von Orders in die Historie verfolgen und in der Klasse TradesID nur bei "verschobener" Periode + nicht mehr als 100 Positionen in der Historie aktualisieren kann, d.h. mit wenig Blut.

Ich habe den Code NICHT getestet, und er ist natürlich suboptimal - nur eine Demonstration der Idee. (gelb - was wird gegenüber dem Original geändert)

//Beispiel für das Einfügen von Tracking-Aufträgen und den History-Cache
//!!!verfolgt keine Löschungen oder Änderungen von Ticketnummern
// basierend auf der Trades ID
#include "Classificator.mqh"
class TRADESID
  {
   CLASSIFICATOR<ulong, ulong> OrdersID;
   CLASSIFICATOR<ulong, ulong> DealsID;

   int               LastTotalOrders;
   int               LastTotalDeals;

   //an jeder hundertsten Stelle in der Geschichte eine Bestellung aufgeben
   ulong             OrderTickets[];


   void              RefreshOrders(void)
     {
      static ulong LastOrderTicket = -1;     //Ticket der Bestellung aus dem vorherigen Durchgang

      if(::HistorySelect(0, INT_MAX))
        {
         const int Total = ::HistoryOrdersTotal();

         if(this.LastTotalOrders > 0 && LastOrderTicket != ::HistoryOrderGetTicket(this.LastTotalOrders - 1))
           {
            int i;
            //jedes hundertste Ticket in umgekehrter Reihenfolge prüfen
            for(i = ArraySize(OrderTickets) - 1; i >= 0 && OrderTickets[i] !=::HistoryOrderGetTicket(i * 100) ; i--)
               ;
            if(i < 0)
               LastTotalOrders = 0;
            else
               {LastTotalOrders = i * 100 + 1; LastOrderTicket = OrderTickets[i];}
            ArrayResize(OrderTickets, i + 1);
           }

         while(this.LastTotalOrders < Total)
           {
            const ulong Ticket = LastOrderTicket = ::HistoryOrderGetTicket(this.LastTotalOrders); //(this.LastTotalOrders++)
            
            // für jede hundertste Position in der Historie ein Ticket zum Array hinzufügen
            if(LastTotalOrders++ % 100 == 0)
               OrderTickets[::ArrayResize(OrderTickets, ::ArraySize(OrderTickets) + 1) - 1] = Ticket;


            const ulong PositionID = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID);

            if(PositionID)
              {
               this.OrdersID.Add(PositionID, Ticket);

               const ulong PositionBy = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_BY_ID);

               if(PositionBy)
                  this.OrdersID.Add(PositionBy, Ticket);

              }
           }
        } 

      return;
     }
  };

Die Verfolgung von Auftragslöschungen/-änderungen ist viel schwieriger, aber auch das wird durch Ihre Bibel nicht gelöst.

Natürlich brauchen ByPASS und MT4HISTORY einen ausgefeilteren Algorithmus für eine solche Korrektur, aber nichts Kompliziertes, wie es scheint (ich habe sie noch nicht studiert).

 

Sie können auch TRADE_TRANSACTION_HISTORY_UPDATE und TRADE_TRANSACTION_HISTORY_DELETE Transaktionen verfolgen, wie Sie geschrieben haben:

https://www.mql5.com/ru/forum/366029/page2#comment_22442705

Wenn sie die Ticketnummer angeben und die Bestellungen in der Historie nach Ticket sortiert sind, kann die Position der Bestellung in der Historie leicht über das OrderTickets-Array verfolgt werden.


P.S. als letzter Ausweg können Sie auch HashMap hinzufügen...

Библиотеки: TradesID
Библиотеки: TradesID
  • 2021.05.13
  • www.mql5.com
Статьи и техническая библиотека по автоматическому трейдингу: Библиотеки: TradesID
 
mktr8591:

Es ist traurig.

Ich habe einen Code skizziert, wie man das Einfügen von Aufträgen in die Historie verfolgen und in der Klasse TradesID nur in der "verschobenen" Periode + nicht mehr als 100 Historienpositionen aktualisieren kann, d.h. mit wenig Blut.

Ich habe den Code NICHT getestet, und er ist natürlich suboptimal - nur eine Demonstration der Idee. (gelb - was ist geändert, um Ihre ursprüngliche)

Wenn ich die Idee richtig verstehe, suchen Sie nach dem Hunderter, in dem die Verschiebung stattgefunden hat. Aber ich habe nicht verstanden, wie das neue Ticket selbst danach in diesem Hunderter ist. Vor allem, wenn es mehrere davon gibt und sie in verschiedenen Hundertern liegen.

Die Verfolgung von Auftragslöschungen/-änderungen ist viel schwieriger, aber auch das hat deine Bibel nicht gelöst.

Ich verstehe das nicht. Was genau wird nicht nachverfolgt? Ich schlage vor, mit b2958 vorerst aufzuhören.

Wenn es darum geht, die Geschichte rückwirkend zu bearbeiten - das ist es nicht wert. Lösungen werden nicht um des Nerdseins willen erstellt, sondern um zu handeln.

Natürlich benötigen ByPASS und MT4HISTORY einen ausgefeilteren Algorithmus für eine solche Korrektur, aber es scheint nichts Kompliziertes zu sein (ich habe sie noch nicht studiert).

Das Problem ist, dass je mehr reguläre Funktionen bei jedem Durchlauf aufgerufen werden, desto höher ist die Wahrscheinlichkeit von Verzögerungen. Der EA beginnt zu hängen. Mehrere Expert Advisors - noch schlimmer. Wenn es mehrere Terminals gibt, ist es ganz schlimm. Sogar das Eintreffen von OnTradeTransaction verlangsamt sich - zum Beispiel beginnt OrderSend ein Vielfaches länger zu dauern als der Ping. Zusätzlich zu der Tatsache, dass die Krücke wildes Debugging impliziert, wird sie auch Verzögerungen verursachen. Stellen Sie sich vor, dass während der Aufzählung die Historie aktualisiert wird, usw. Es wird eine große Anzahl von Fehlern geben.


Die Hauptsache ist doch, dass alles perfekt funktioniert hat. Sie haben es nur an einer Stelle kaputt gemacht und kommentieren es in keiner Weise.


ZЫ Für mich ist es ein Rätsel, warum fast niemand versteht, worum es geht.

 
fxsaber:

ZЫ Es ist mir ein Rätsel, warum fast niemand versteht, worum es dabei geht.

Weil niemand versucht hat, die Arbeit mit Aufträgen im MT5 a) einfach, b) korrekt und c) schnell zu implementieren. Das schließt mich ein.

 
fxsaber:

Wenn ich die Idee richtig verstanden habe, suchen Sie nach dem Hunderter, in dem die Verschiebung stattgefunden hat. Aber ich verstehe nicht, wie das neue Ticket selbst in diesem Hunderter zu finden ist. Vor allem, wenn es mehrere davon gibt und sie in verschiedenen Hundertern liegen.


Wenn es nur Einfügungen ohne Löschungen gab, dann sucht die Schleife

for(i = ArraySize(OrderTickets) - 1; i >= 0 && OrderTickets[i] !=::HistoryOrderGetTicket(i * 100) ; i--)
               ;

Schleife den Anfang des frühesten Hunderters suchen, in dem die Einfügungen stattfanden. Man braucht nicht nach dem Ticket selbst zu suchen - man muss nur alle Aufträge ab diesem Hunderter und den nächsten (neueren) durchgehen und sie in die Hashmap einfügen. Dies geschieht wie üblich in einer Schleife while(this.LastTotalOrders < Total), wobei es sich fast immer um die letzten 1-2 Hunderter handeln wird.

Es kann besser sein, den Schritt zu reduzieren - nicht 100, sondern 40 oder 20.

Falls sich der Verlauf während for ändert - etwas wird VOR dem gefundenen Hunderter eingefügt - können Sie es in die Schleife einfügen:

 void              RefreshOrders(void)
     {
      static ulong LastOrderTicket = -1;     //Ticket der Bestellung aus dem vorherigen Durchgang

      if(::HistorySelect(0, INT_MAX))
        {
         // Wir müssen eine Prüfung für IsStopped und die maximale Ausführungszeit hinzufügen
         while(this.LastTotalOrders > 0 && LastOrderTicket != ::HistoryOrderGetTicket(this.LastTotalOrders - 1))
           {
            int i;
            //jedes hundertste Ticket in umgekehrter Reihenfolge prüfen
            for(i = ArraySize(OrderTickets) - 1; i >= 0 && OrderTickets[i] !=::HistoryOrderGetTicket(i * 100) ; i--)
               ;
            if(i < 0)
               LastTotalOrders = 0;
            else
              {LastTotalOrders = i * 100 + 1; LastOrderTicket = OrderTickets[i];}
            ArrayResize(OrderTickets, i + 1);
            ::HistorySelect(0, INT_MAX);
           }

         const int Total = ::HistoryOrdersTotal();

         while(this.LastTotalOrders < Total)
           {
            const ulong Ticket = LastOrderTicket = ::HistoryOrderGetTicket(this.LastTotalOrders);

            // für jede hundertste Position in der Historie ein Ticket zum Array hinzufügen
            if(LastTotalOrders++ % 100 == 0)
               OrderTickets[::ArrayResize(OrderTickets, ::ArraySize(OrderTickets) + 1) - 1] = Ticket;


            const ulong PositionID = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID);

            if(PositionID)
              {
               this.OrdersID.Add(PositionID, Ticket);

               const ulong PositionBy = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_BY_ID);

               if(PositionBy)
                  this.OrdersID.Add(PositionBy, Ticket);

              }
           }
        } 
      return;
     }

Aber das wird sehr selten sein.

 
mktr8591:

Wenn es nur Einfügungen ohne Löschungen gibt, dann ist der Zyklus

Schleife nach dem Anfang des frühesten Hunderters, in dem die Einfügungen stattfanden. Sie brauchen nicht nach dem Ticket selbst zu suchen - Sie müssen nur alle Bestellungen ab diesem Hunderter und den nächsten (neueren) Bestellungen durchgehen und sie der Hashmap hinzufügen. Dies geschieht wie üblich in der Schleife while(this.LastTotalOrders < Total), wobei es sich fast immer um die letzten 1-2 Hunderter handeln wird.

D.h., dass das wiederholte Hinzufügen desselben Tickets zur Hashmap die Hashmap nicht verändern wird?

Ich habe Aufträge, die das achte Hundert erreichen. Im aktiven Handel ist dies ein häufiges Phänomen bei neuen Builds. In diesem Fall müssen Sie mehrere hundert Aufträge hashmapen.

 
fxsaber:

D.h., dass das wiederholte Hinzufügen desselben Tickets zur Hashmap die Hashmap nicht verändern wird?


Ja, gerade ist mir aufgefallen - wenn man ein Ticket OrdersID.Add(PositionID, Ticket) wiederholt hinzufügt, dann wird in OrdersID.ValuesID[] dieses Ticket umgedreht. D.h. die Hashmap wird anschwellen.

Wir müssen irgendwie eine Prüfung durchführen. Oder ein HashSet anstelle einer Array-Struktur für VALUESID verwenden. Oder etwas ähnliches.