MT5 und Geschwindigkeit in Aktion - Seite 4

 
Ich verstehe, dass es auf die Ausrüstung ankommt.
 
Alexsandr San:
Ich verstehe, dass es von der Ausrüstung abhängt

Ganz und gar nicht!

2020.05.29 15:08:44.938 Terminal        Windows 7 Service Pack 1 build 7601, Intel Core i7-6850 K  @ 3.60 GHz, 23 / 31 Gb memory, 43 / 226 Gb disk, IE 11, UAC, Admin, GMT+3
 
Alexsandr San:
Ich denke, das hängt von der Hardware ab.

Das glaube ich nicht ))))

Und das nicht einmal von einem belegten Computer aus...

 
prostotrader:

Ganz und gar nicht!

ja! Ihr Gerät und das vorherige haben unterschiedliche Ergebnisse - also liege ich falsch, nicht der Strom bedeutet

 
Aleksey Mavrin:

Was ist onMain? Wie kann es mehr als ein Ereignis in der Warteschlange in onMain geben, wenn jedes Ereignis onMain aufruft, um die Warteschlange zu bearbeiten?

OnMain ist eine Funktion. Es handelt sich nicht um eigentlichen Code, sondern um einen Sonderfall - eine Antwort auf die Behauptung "Es gibt keine Möglichkeit, den Zustand der aktuellen Warteschlange zukennen, während die OnMain-Funktion ausgeführt wird".Es ist ein anderer Ansatz für die Berechnungen selbst

 
A100:

OnMain ist eine Funktion. Es handelt sich nicht um den eigentlichen Code, sondern um einen Sonderfall - eine Antwort auf die Behauptung "Es gibt keine Möglichkeit, den Zustand der aktuellen Warteschlange zukennen, während die OnMain-Funktion ausgeführt wird".Dies ist ein anderer Ansatz für die Berechnungen selbst

Also, nur für den Fall, OnMain...

:) ;)
 
fxsaber:


In Combat Advisors habe ich Funktionen überall an verdächtigen Stellen in _B(FuncName(...), AlertTime) verpackt. Hier ist ein kurzer Auszug aus dem Protokoll der letzten Einträge.

Die Zeitspalte zeigt an, wie oft das Einfrieren auftritt.

Sie tauschen Begriffe aus.

Hier ist Ihre ursprüngliche Aussage:

Leider dauert ein solcher HistorySelect-Aufruf 5-30 Millisekunden (habe ich selbst in Release-EX5 gemessen). Wenn der Expert Advisor mehrere solcher Aktualisierungen in OnTick vornimmt (in einer guten Art und Weise, sollte dies nach jeder Pause geschehen. Zum Beispiel nach jedem OrderSend.), dann wird alles wahnsinnig teuer/lang. HistorySelect kann bis zu mehreren Sekunden in einem einzigen OnTick addieren.

Selbst in Ihrem Terminal ist die durchschnittliche Zeit von 0,2 ms pro Aufruf messbar geringer als die in der ursprünglichen Anweisung angegebenen Werte.

Jetzt sagen Sie, dass die Laufzeit einer Funktion manchmal deutlich länger sein kann als der Durchschnitt. Dies ist eine andere Frage.

Jede HistorySelect()-Anforderung ist ein vollwertiger Aufruf an die Terminalbasen unter Synchronisatoren. Dies ist unvermeidlich. Ja, in Anbetracht des Vorhandenseins der Zugriffssynchronisierung können wir keine sehr kurze Ausführungszeit für diese Funktion garantieren.

Die vorgeschlagene Lösung durch Hinzufügen der Funktionen HistoryDealsSelect() und HistoryOrdersSelect() ändert in diesem Sinne absolut nichts.

Das Skript zur Überprüfung der maximalen und durchschnittlichen Zeit:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
//---
   ulong start,end,max_time=0,avr_time=0;
   int   count=100000;
   for(int i=0; i<count; i++)
     {
      start=GetMicrosecondCount();
      HistorySelect(Tick.time, INT_MAX);
      end=GetMicrosecondCount()-start;
      //--- >1 ms
      if(end>1000)
         Print(" > 1 ms for one HistorySelect: ",DoubleToString(end/1000.0,2)," ms");
      //---
      if(end>max_time)
         max_time=end;
      avr_time+=end;
     }
   Print("Last tick time. Selected orders: ",HistoryOrdersTotal(),"; max time: ",DoubleToString(max_time/1000.0,3)," ms; avr time: ",DoubleToString(avr_time/1000.0/count,3)," ms; ",count," iterations");
//---
   Tick.time=(Tick.time/86400)*86400;
   max_time=0;
   for(int i=0; i<count; i++)
     {
      start=GetMicrosecondCount();
      HistorySelect(Tick.time, INT_MAX);
      end=GetMicrosecondCount()-start;
      //--- >1 ms
      if(end>1000)
         Print(" > 1 ms for one last day HistorySelect: ",DoubleToString(end/1000.0,2)," ms");
      //---
      if(end>max_time)
         max_time=end;
      avr_time+=end;
     }
   Print("Last day. Selected orders: ",HistoryOrdersTotal(),"; max time: ",DoubleToString(max_time/1000.0,3)," ms; avr time: ",DoubleToString(avr_time/1000.0/count,3)," ms; ",count," iterations");
//---
   HistorySelect(0, INT_MAX);
   Print("Orders total: ",HistoryOrdersTotal());
  }
2020.05.29 17:22:04.195 TestHistorySelect (EURJPY,H1)   Last tick time. Selected orders: 0; max time: 0.034 ms; avr time: 0.001 ms; 100000 iterations
2020.05.29 17:22:06.771 TestHistorySelect (EURJPY,H1)   Last day. Selected orders: 141; max time: 0.101 ms; avr time: 0.027 ms; 100000 iterations
2020.05.29 17:22:08.039 TestHistorySelect (EURJPY,H1)   Orders total: 31448
 
Anton:

Ein Skript zur Überprüfung der Höchst- und Durchschnittszeiten:

Ich werde mich nicht zu Ihrer Meinung äußern, bevor sie zitiert wurde. Hier ist das Ergebnis der Ausführung Ihres Skripts.

Genauer gesagt konnte ich nicht warten, bis es fertig war, also habe ich die Anzahl der Iterationen von 100K auf 1K geändert.

        Last tick time. Selected orders: 0; max time: 3.880 ms; avr time: 1.315 ms; 1000 iterations
        Last day. Selected orders: 2061; max time: 7.131 ms; avr time: 4.309 ms; 1000 iterations
        Orders total: 50113

Ist dies überhaupt eine befriedigende Note wert?

Sehen Sie sich die Absurdität der Situation an. Um dummerweise die Anzahl der Geschäfte herauszufinden, müssen wir HistorySelect aufrufen! Das ist, gelinde ausgedrückt, nicht rational.


Ich verbringe bestenfalls zehn Millisekunden pro Tick, nur wegen HistorySelect.

 
A100:

In seiner einfachsten Form:

Sie müssen nur Ihre Herangehensweise an die Berechnungen selbst ändern (so oft wie die Aufgabe es erfordert, eine Zwischenrückkehr durchführen). Aber wenn es kompliziert ist, bedenken Sie in der 1. Phase, dass OnMain für Sie nicht vorhanden ist (Sie setzen den Hauptcode nicht in OnMain, sondern in OnTrade2XX), daher brauchen Sie nichts in OnMain zu lernen

Danke, genau so habe ich es von Anfang an verstanden, und deshalb habe ich gesagt, dass ich es nicht ganz verstanden habe. Hier ist ein Beispiel für ein einfaches Szenario.


Sie führen einen OrderSend durch. Wenn eine bestimmte Position nicht direkt nach dem OrderSend geschlossen wurde, wird ein weiterer OrderSend ausgeführt. Dies ist alles Logik, die programmiert werden muss. Async wird nicht verwendet.


Nun zu der Situation, in der sich unser Roboter befand. Sie haben eine OrderSend gesendet, und während diese ausgeführt wird, hat der Limiter ausgelöst und der TP der oben genannten Position wurde ausgeführt.


Wie sieht die schematische Umsetzung des Roboters aus? Ich weiß nicht, wie es zu implementieren, ohne zu bremsen HistorySelect oder OnTradeTransaction-Spion Krücke, die Zugriff auf die gesamte Geschichte der Transaktionen in jedem Ort des Codes gibt. Wenn ein Mechanismus für den Zugriff auf die Ereigniswarteschlange implementiert wäre, wäre das obige Beispiel elementar gelöst.


Alle, die stark in MT5 sind, einschließlich der Entwickler, zeigen mir bitte, wie man diese( zwei Zeilenin Fettdruck oben) unkomplizierte (ich habe Angst, sogar komplexe) Handelslogik implementiert.

 
A100:

OnMain ist eine Funktion. Dies ist nicht der eigentliche Code, sondern ein Sonderfall - eine Antwort auf die Behauptung " Es gibt keine Möglichkeit, den Zustand der aktuellen realen Warteschlange während der Ausführung der OnMain-Funktion zu erfahren".Dies ist ein anderer Ansatz für die Berechnungen selbst

Das ist es doch, oder? Und genau darüber haben die Jungs gesprochen. Um sie zu implementieren, müssen Sie die Struktur der Ausführung von MQL-Programmen ändern, entweder a) mindestens in eine Zwei-Thread-Ausführung oder b) einen Mechanismus für den Zugriff auf und die Verwaltung von Warteschlangen hinzufügen.

Mit der derzeitigen Struktur ist das von Ihnen vorgeschlagene System nicht umsetzbar.