Bibliotheken: MT4Orders - Seite 82

 

Ich kann nicht verstehen, ob es möglich ist, dieses Problem mit Testgeschwindigkeit zu lösen, ohne MT5 Sprachfunktionen zu verwenden. Das Problem erschien vor langer Zeit, aber meine Hände bekam es nur jetzt.

Build 3802, __MT4ORDERS__ "2022.07.20"

Bedingte Funktion, die im Expert Advisor bei jedem Tick aufgerufen wird. Test im mt5 Strategie-Tester.

	 datetime get_last_order_close_time () {
                datetime last_close_time=0;

                for ( int i = OrdersHistoryTotal() - 1; i >= 0; i-- ) {
                        if ( !OrderSelect ( i, SELECT_BY_POS, MODE_HISTORY )) {
                                continue;
                        }
         		 last_close_time=OrderCloseTime();
		        return last_close_time;
                }

                return last_close_time;
        }

DieAnzahl der Geschäfte ist etwa 26 Tausend. Die Testzeit beträgt etwa 1 Stunde 10 Minuten.

Entfernen wir die Funktion aus dem Code, beträgt die Testzeit etwa 17 Minuten.

Ich schreibe die gleiche Funktion mit der MT5-Funktionalität neu:

	 datetime get_last_order_close_timeMT5 () {
                datetime last_close_time=0;
                HistorySelect(0,TimeCurrent()); 

                for ( int i = HistoryDealsTotal() - 1; i >= 0; i-- ) {
                        
                        ulong ticket=HistoryDealGetTicket(i);
                        
                        if((ENUM_DEAL_ENTRY)HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT)
                        {
                           last_close_time=(datetime)HistoryDealGetInteger(ticket,DEAL_TIME);
                           return last_close_time;
                        }                       
                }

                return last_close_time;
        }

Die Testzeit beträgt etwa 18 Minuten.

Ich setze die Bibliothek auf __MT4ORDERS__ Version "2020.01.12" zurück und kompiliere den Expert Advisor in Build 2980.

Die Zeit des Expert Advisors mit der Funktion get_last_order_close_time beträgt etwa 20 Minuten.

 
elavr #:

Ich kann nicht erkennen, ob dieses Problem der Testgeschwindigkeit ohne die Verwendung der MT5-Sprachfunktionen gelöst werden kann.

In allen drei Fällen ist das Endergebnis das gleiche?
 
fxsaber #:
Ist das Endergebnis in allen drei Fällen das gleiche?

Ja, natürlich.

Das Problem trat nach einem weiteren Terminal-Update auf. Ich habe Ihre Bibliothek nicht geändert und den Bot im alten Terminal kompiliert, damit er wie zuvor funktioniert.

 
elavr #:

Das Problem trat nach einem weiteren Update des Terminals auf. Ich habe Ihre Bibliothek nicht geändert und den Bot im alten Terminal kompiliert, damit er wie zuvor funktioniert.

Ich habe einige Nachforschungen angestellt.


Expert Advisor.

#include <MT4Orders.mqh> // https://www.mql5.com/de/code/16006

#define  VIRTUAL_SNAPSHOT_REFRESHTIME 1000
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/de/code/22577

input int inMod = 5;
input int inRange = 0;
input bool inVirtual = false;

const bool Init = inVirtual ? VIRTUAL::SelectByHandle(VIRTUAL::Create()) : false;;

#define  Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

ulong lOnTester = 0;

void OnTick()
{  
  static int i = 0;
  
  VIRTUAL::NewTick();
  
  if (!(i++ % inMod))
    OrderClose(OrderSend(_Symbol, OP_BUY, 0.1, Ask, 0, 0, 0), 0.1, Bid, 0);
    
// VIRTUAL::Snapshot(); 
  lOnTester += LastCloseTimeMQL4() % 100;
  
// lOnTester += LastCloseTimeMQL5() % 100;
}

double OnTester()
{
  if (HistorySelect(0, INT_MAX))
    Print(HistoryDealsTotal());
  
  return((double)lOnTester);
}

Bei jedem inMod-Tick wird eine Position geöffnet und geschlossen. Und bei jedem Tick wird die OrderCloseTime berechnet.

OnTester dient als Kriterium zur Überprüfung der Identität der Ergebnisse bei verschiedenen Konfigurationen.


Entsprechende Funktionen der Arbeit mit der Historie.

datetime LastCloseTimeMQL4()
{  
  datetime Res = 0;
  
  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      Res = OrderCloseTime();
      
      break;
    }

  return(Res);
}

datetime LastCloseTimeMQL5()
{
  datetime Res = 0;
  
  if (HistorySelect(0, INT_MAX))
    for (int i = HistoryDealsTotal() - 1; i >= 0; i--)
    {
      const ulong Ticket = HistoryDealGetTicket(i);
      
      if (HistoryDealGetInteger(Ticket, DEAL_ENTRY) != DEAL_ENTRY_IN)
      {
        Res = (datetime)HistoryDealGetInteger(Ticket, DEAL_TIME);
        
        break;
      }
    }
    
  return(Res);
}

#define  MACROS(A, B)          \
  datetime A##_2()            \
  {                           \
    static datetime Res = 0;  \
    static int PrevTotal = 0; \
                              \
    const int Total = B;      \
                              \
    if (PrevTotal != Total)   \
    {                         \
      Res = A();              \
                              \
      PrevTotal = Total;      \
    }                         \
                              \
    return(Res);              \
  }

// LastCloseTimeMQL4_2
MACROS(LastCloseTimeMQL4, OrdersHistoryTotal())

// LastCloseTimeMQL5_2
MACROS(LastCloseTimeMQL5, HistorySelect(0, INT_MAX) ? HistoryDealsTotal() : 0)


Methodik.

Ein einziger Lauf mit den Einstellungen wie in der Quelle (inMod = 5).

2023.07.06 23:59:59   28179
final balance 99996992.20 pips
OnTester result 2761115
EURUSD,M1: 274413 ticks, 70443 bars generated. Environment synchronized in 0:00:00.021. Test passed in 0:00:03.712 (including ticks preprocessing 0:00:00.031).

28K Transaktionen, fast vier Sekunden. Da wir die Leistung im Optimierungsmodus messen müssen, wurden alle folgenden Leistungsmessungen auf diese Weise durchgeführt.

shortest pass 0:00:02.875, longest pass 0:00:03.094, average pass 0:00:02.919

Mit obligatorischer Neukompilierung vor der Ausführung und nur einem aktivierten Agenten für die sequenzielle Ausführung von Durchläufen.


Leistung.

Leistungstabelle (Ausführungszeit in Millisekunden) für b3815 und b2958.

MT5 Ausführung LetzteSchlussZeitMQL4 LetzteSchlussZeitMQL5 LetzteSchlussZeitMQL4_2 LastCloseTimeMQL4+VIRTUAL::Snapshot LetzteSchlusszeitMQL4+VirtualTester
b3815 2875 113 708 732 45
b2958 2718 107 675 715 50

MT4Orders vom 20.07.2022 wurde überall verwendet.


Schlussfolgerungen.

  • OrderSelect ist langsam. Das liegt daran, dass OrderSelect absolut alle Daten der ausgewählten Order aus der History berechnet (OrderPrint ist frei). Dies ist eine großartige Kombination der Funktionen HistoryOrderGet* und HistoryDealGet*, die jede Komplexität von Marktsituationen und eine große Anzahl von Fallstricken bewältigt. Sehen Sie sich MT4ORDERS::GetHistoryPositionData() an. Dies ist eine einzige Funktion für das Terminal und für den Tester, aber sie ist speziell für den Tester beschleunigt, weil viele Terminal-Fallen im Tester nicht vorhanden sind. Beispiele für Konfigurationen: eins, zwei, drei.
  • Dementsprechend ist es notwendig, eine Reduzierung der OrderSelect-Aufrufe für historische Aufträge zu erreichen. Dies kann auf die in den drei rechten Spalten der Tabelle angegebenen Arten erreicht werden.
  • Am schnellsten geht es (noch vor reinem MQL5) mit dem Handel in einer virtuellen Umgebung. Ich würde empfehlen, in der virtuellen Umgebung zu optimieren, und einzelne Pässe - außerhalb davon.
  • Die Leistung von Tester b2958 und b3815 ist fast identisch.
  • Ich empfehle nicht, die Logik des TS für den Tester an die Handelshistorie zu binden und sich auf diese zu beziehen. Sie können zum Beispiel die OrderCloseTime Ihres TS kennen, ohne auf die Historie zu verweisen.
 
elavr #:

Die Testzeit beträgt etwa 1 Stunde und 10 Minuten.

Ich setze die Bibliothek auf __MT4ORDERS__ Version "2020.01.12" zurück und kompiliere den Expert Advisor in Build 2980.

Die Arbeitsdauer des Expert Advisors mit der Funktion get_last_order_close_time beträgt etwa 20 Minuten.

Testen Sie den obigen Code mit einer alten Version der Bibliothek (ich habe sie nicht).

Wenn es einen Unterschied in der Leistung, senden Sie es an PM.

 
Ich danke Ihnen vielmals! Ich werde es nächste Woche ausprobieren!
 

Ist es möglich, dass es ein Speicherleck oder eine mehr als notwendige Speichernutzung gibt? Vielleicht in this.tickets oder in this.amount (::ArrayResize) oder vielleicht irgendwo anders?

Die Größe der Arrays wird nur mit der Zeit erhöht. Ist das ein Muss? Ist es möglich, sie zu leeren oder vielleicht nicht alle vorherigen Trades zu laden?

 
pcdeni #:

Ist es möglich, dass es ein Speicherleck oder eine mehr als notwendige Speichernutzung gibt? Vielleicht in this.tickets oder in this.amount (::ArrayResize) oder vielleicht irgendwo anders?

Die Größe der Arrays wird nur mit der Zeit erhöht. Ist das ein Muss? Ist es möglich, sie zu leeren oder vielleicht nicht alle vorherigen Trades zu laden?

Die Bibliothek speichert die historischen Daten nicht vollständig im Cache. Eine Speicherknappheit ist nur theoretisch möglich, aber nicht in der Praxis.

Schreiben Sie ein Skript, das den gesamten Handelsverlauf mit Hilfe der Bibliothek durchsucht, und sehen Sie, wie viel Speicher verbraucht wird.

 
fxsaber #:

Die Bibliothek speichert die Verlaufsdaten nicht vollständig im Cache. Eine Speicherknappheit ist nur theoretisch möglich, aber nicht in der Praxis.

Schreiben Sie ein Skript, das den gesamten Handelsverlauf mithilfe der Bibliothek durchsucht, und sehen Sie, wie viel Speicher verbraucht wird.

Im Strategietest verbraucht die Ea 25 GB pro Kern.

Bearbeiten: es ist ein 1 Jahr Zeitrahmen Test, also nicht viel.
 
pcdeni #:

Bei den Strategietests verbraucht das Ea 25 GB pro Kern.

edit: es ist ein 1 Jahr Zeitrahmen Test, also nicht viel.

Die Bibliothek (MT4Orders.mqh) verbraucht nicht diese Menge an Speicher. Sie können zum Beispiel diesen EA ausführen, um sich selbst davon zu überzeugen.

Wahrscheinlich arbeiten Sie falsch mit Indikatoren: Sie erstellen neue Indikator-Handles, löschen aber nicht die alten.