MT5 und Geschwindigkeit in Aktion - Seite 19

 
Roman:

C-Programmierer.

Das Beispiel ist in diesem Fall sehr einfach. Die Berechnung derGesamtlebensdauer aller geschlossenen Positionen ist eine viel schwierigere Aufgabe für eine schnelle Leistung.

 
fxsaber:

Ein Beispiel ist in diesem Fall sehr einfach. Die Berechnung derGesamtlebensdauer aller geschlossenen Positionen ist eine viel schwierigere Aufgabe für eine schnelle Leistung.

Ich habe Ihnen vorhin den Grund erklärt, aber Sie haben ihn nicht beachtet.

 
Roman:

Ich habe Ihnen vorhin den Grund dafür erklärt, aber Sie haben ihn nicht beachtet.

Offenbar muss ich im Forum nach Ihrer Erklärung suchen.

 
fxsaber:

Offenbar muss ich im Forum nach Ihrer Erklärung suchen.

Beim letzten Mal hatten Sie ein ähnliches Problem, bei dem der übergebene Parameter nicht zwischengespeichert, sondern direkt in den Code übernommen wurde.
Und nachdem Sie sie zwischengespeichert hatten, stieg die Geschwindigkeit. Weisen Sie einer Variable immer Speicher zu und verwenden Sie sie erst später.
Hier ist es dasselbe, Sie deklarieren eine Variable, der Speicher ist bereits zugewiesen und die weitere Arbeit mit der Variable wird schneller sein, da keine Kosten für die Speicherzuweisung an fallen.

Dies gilt auch für das Abrufen von Werten aus mql-Funktionen.
Sogar die Entwickler hier im Forum empfehlen, zuerst einen Wert aus einer Funktion in eine Variable zu übertragen und diese Variable dann in einer if()-Bedingung zu verwenden

 
fxsaber:

Die Berechnung der kumulativenLebensdauer aller geschlossenen Positionen ist eine viel schwierigere Aufgabe für eine schnelle Leistung.

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Bibliotheken: MT4Orders

fxsaber, 2020.08.29 04:17

#include <Generic\HashMap.mqh>

// Возвращает общую длительность всех закрытых позиций.
int SumPositionsLengthMQL5( void )
{
  int Res = 0;
  
  if (HistorySelect(0, INT_MAX))
  {
    CHashMap<ulong, ulong> DealsIn;  // По PositionID возвращает DealIn.
    const int TotalDeals = HistoryDealsTotal();
    
    for (int i = 0; i < TotalDeals; i++)
    {
      const ulong TicketDeal = HistoryDealGetTicket(i);
      
      if (HistoryDealGetInteger(TicketDeal, DEAL_ENTRY) == DEAL_ENTRY_IN)
        DealsIn.Add(HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID), TicketDeal);
      else if (HistoryDealGetInteger(TicketDeal, DEAL_TYPE) <= DEAL_TYPE_SELL)
      {
        ulong TicketDealIn;
        
        if (DealsIn.TryGetValue(HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID), TicketDealIn))
          Res += (int)(HistoryDealGetInteger(TicketDeal, DEAL_TIME) - HistoryDealGetInteger(TicketDealIn, DEAL_TIME));        
      }        
    }
  }
      
  return(Res);
}

Vielleicht gibt es eine schnellere Möglichkeit. Aber ein Schritt nach links in der Bedingung dessen, was berechnet werden muss, und die Logik muss sich möglicherweise erheblich ändern. Im Allgemeinen nicht einfach.

 
fxsaber:

Vielleicht gibt es eine schnellere Möglichkeit. Aber ein Schritt nach links in der Bedingung, was gezählt werden muss, und die Logik muss sich möglicherweise erheblich ändern. Im Allgemeinen nicht einfach.

Es geht nicht um die Bedingung, sondern um das Schreiben des Codes.
Auch wenn Sie die Bedingung durch einen Schalter ersetzen können, wird er schneller funktionieren als alle anderen.
Probieren Sie diesen Code aus, wird er schneller oder nicht? Wenn nicht, versuchen Sie, if else durch einen Schalter zu ersetzen.
Ich hoffe, Sie haben jetzt verstanden, dass alle Variablendeklarationen aus der Schleife herausgenommen werden sollten und nicht 100500 Mal neu ausgeführt werden sollten.
Außerdem ist für jeden zurückgegebenen Wert Speicher in Form einer Variablen zuzuweisen.

#include <Generic\HashMap.mqh>

// Возвращает общую длительность всех закрытых позиций.
int SumPositionsLengthMQL5( void )
{
   int  Res     = 0;
   bool HSelect = false;
  
   HSelect = HistorySelect(0, INT_MAX);
  
   if(HSelect)
   {
      CHashMap<ulong, ulong> DealsIn;  // По PositionID возвращает DealIn.
    
      int   TotalDeals   = 0;
      ulong TicketDeal   = 0;
      bool  condition1   = false;
      bool  condition2   = false; 
      bool  condition3   = false;       
      long  PositionID   = 0;
      ulong TicketDealIn = 0;
      int   DealTime     = 0;
    
      TotalDeals = HistoryDealsTotal();
    
      for(int i=0; i < TotalDeals; i++)
      {
         TicketDeal =  HistoryDealGetTicket(i);      
         condition1 = (HistoryDealGetInteger(TicketDeal, DEAL_ENTRY) == DEAL_ENTRY_IN);
         condition2 = (HistoryDealGetInteger(TicketDeal, DEAL_TYPE) <= DEAL_TYPE_SELL);
      
         if(condition1)
         {
            PositionID = HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID);
            DealsIn.Add(PositionID, TicketDeal);          
         }
         else if(condition2)
         {       
            PositionID = HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID);
            condition3 = DealsIn.TryGetValue(PositionID, TicketDealIn);
         
            if(condition3) 
            {
               DealTime = (int)(HistoryDealGetInteger(TicketDeal, DEAL_TIME) - HistoryDealGetInteger(TicketDealIn, DEAL_TIME));
               Res += DealTime; 
            }   
         }        
      }
   }
     
   return(Res);
}
 

Dies ist eine weitere Variante des Codes, so dass wir die Geschichte nicht für die zweite Bedingung umschreiben müssen.
Sie können auch überlegen, welche Bedingung häufiger erfüllt wird, sie an die erste Stelle in der Schleife setzen und mit der Iteration fortfahren.

#include <Generic\HashMap.mqh>

// Возвращает общую длительность всех закрытых позиций.
int SumPositionsLengthMQL5( void )
{
   int  Res     = 0;
   bool HSelect = false;
  
   HSelect = HistorySelect(0, INT_MAX);
  
   if(HSelect)
   {
      CHashMap<ulong, ulong> DealsIn;  // По PositionID возвращает DealIn.
    
      int   TotalDeals   = 0;
      ulong TicketDeal   = 0;
      bool  condition1   = false;
      bool  condition2   = false; 
      bool  condition3   = false;       
      long  PositionID   = 0;
      ulong TicketDealIn = 0;
      int   DealTime     = 0;
    
      TotalDeals = HistoryDealsTotal();
    
      for(int i=0; i < TotalDeals; i++)
      {
         TicketDeal =  HistoryDealGetTicket(i);      
         condition1 = (HistoryDealGetInteger(TicketDeal, DEAL_ENTRY) == DEAL_ENTRY_IN);         
      
         if(condition1)
         {
            PositionID = HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID);
            DealsIn.Add(PositionID, TicketDeal);
            continue;                      
         }                  
         
         condition2 = (HistoryDealGetInteger(TicketDeal, DEAL_TYPE) <= DEAL_TYPE_SELL);
         
         if(condition2)
         {       
            PositionID = HistoryDealGetInteger(TicketDeal, DEAL_POSITION_ID);
            condition3 = DealsIn.TryGetValue(PositionID, TicketDealIn);
         
            if(condition3) 
            {
               DealTime = (int)(HistoryDealGetInteger(TicketDeal, DEAL_TIME) - HistoryDealGetInteger(TicketDealIn, DEAL_TIME));
               Res += DealTime; 
            }   
         }        
      }
   }
     
   return(Res);
}
 
Roman:

Eine andere Variante des Codes, um die Geschichte für die zweite Bedingung nicht unnötig zu ruckeln.

        3132754100
        Time[Bench(SumPositionsLengthMQL5)] = 105779
        3132754100
        Time[Bench(SumPositionsLengthMQL5_Roman)] = 106270

Von hier an liegt es an Ihnen.

 
Renat Fatkhullin:

In MT4 funktioniert es genauso, nur die Cache-Erstellung ist ausgeblendet. Bei jedem OnTick/OnStart von MT4 erstellt das Terminal automatisch und sparsam eine Momentaufnahme des Marktumfelds für jeden EA.

Daher können Sie die tatsächliche Latenzzeit der Datenaufbereitung nicht anhand des MQL4-Codes beurteilen. Zum Glück sind die Daten im MT4 klein und einfach.

Falls Sie sich das fragen.

geschlossener Positionen mehr als viermal so schnell wie MT5x64.

 
fxsaber:

Sie können es von hier aus übernehmen.

Wenn man es selbst macht, dann macht man es selbst.
Aber es ist seltsam, warum dies das Ergebnis ist, das ist eine Frage für Renate.
Mein Verdacht ist die Hashmap-Prüfung DealsIn.TryGetValue
Schauen Sie unter dem Profiler.