MT5 und Geschwindigkeit in Aktion - Seite 2

 
fxsaber:

Bitte geben Sie einen rudimentären Diagramm-Code für diese Idee. Auf den ersten Blick scheint es sich um ein völliges Missverständnis zu handeln.

Während der Ausführung der Funktion OnMain gibt es keine Möglichkeit, den Status der aktuellen realen Warteschlange zu erfahren. Die einzige Abhilfe ist ein Spyware-Programm, wie im Link angegeben.

In seiner einfachsten Form:

OnXXX( параметры )
{
        запомнить параметры (поместить в очередь)
        OnMain();
}
On2XX( параметры )
{
/*вычисления*/
        поменять приоритет обработки событий (если нужно)
/*вычисления*/
        промежуточный return (если нужно) 
/*вычисления*/
}
void OnMain()
{
        прочитать приоритет обработки событий
        для каждой группы событий
                извлечь параметры из очереди
                OnTradeXXX( параметры )
                удалить событие из очереди
}

Sie müssen nur den Ansatz für die Berechnungen selbst ändern (so oft wie die Aufgabe es erfordert eine Zwischenrückkehr durchführen). Aber wenn es schwierig ist, bedenken Sie beim 1. Schritt, dass OnMain für Sie nicht existiert (Sie verschieben den Hauptcode nicht in OnMain, sondern in On2XX), bzw. in OnMain brauchen Sie nichts zu lernen

 
A100:

Die Krücken werden in die falsche Richtung gebaut:

Lassen Sie die OnXXX-Funktionen nur die Ereignisse (Parameter) in die Warteschlange kopieren und die Hauptfunktion OnMain aufrufen. Verschieben Sie ihren gesamten Code in doppelte On2XX-Funktionen. Und rufen Sie diese sich duplizierenden On2XX-Funktionen von OnMain aus in der von Ihnen benötigten Reihenfolge auf, wobei Sie ihnen wiederum die Daten aus den Warteschlangen als Parameter übergeben.

Führen Sie dann Messungen durch und zeigen Sie den Geschwindigkeitszuwachs, und dann können Sie vorschlagen, MMS mit geeigneten Funktionen zu ergänzen. Aber warum etwas hinzufügen, wenn man hier und jetzt schon alles selbst gemacht hat?

Das ist nicht das, worüber du schreibst.
Das Problem ist, dass die Funktionalität des Füllens von Feldern in Eingabevariablen der Funktion "OntaredeTransaction" nicht der Beschreibung in der Hilfe entspricht, zum Schlimmeren:
d.h. viele Felder werden in Aufrufen und sogar im letzten Aufruf von TRADE_TRANSACTION_HISTORY_ADD nicht gefüllt.
Folglich quälen sich alle Händler hier, diese fehlenden Parameter im Moment der Ankunft irgendwie zu bestimmen.
Es gab viele Diskussionen hier, suchen Sie einfach im Forum - schlechte "OntaredeTransaction"-Funktionalität verursacht zusätzliche Kosten sowohl in Zeit und "lädt" Händler mit zusätzlicher Zeit für die Entwicklung von angemessen funktionierenden Code (dh riesige Zeitverluste und kolossale Ineffektivität auf Gemeinschaftsebene).
Die aktuellen Antworten der Entwickler lauten: "Wenn Sie ein Marktausführungssymbol haben, hat es einen Preiswert von Null; es sollte so sein" (Link).(Link) - das ist wieder einmal UNNORMAL -
das Fehlen erschöpfender Werte im letzten Funktionsaufruf führt zu einer Menge zusätzlicher Arbeit.

Новая версия платформы MetaTrader 5 build 2450: Сервис "Подписки", улучшения в интерфейсе и удобные функции в MetaEditor
Новая версия платформы MetaTrader 5 build 2450: Сервис "Подписки", улучшения в интерфейсе и удобные функции в MetaEditor
  • 2020.05.18
  • www.mql5.com
В пятницу 22 мая 2020 года будет выпущена обновленная версия платформы MetaTrader 5...
 
fxsaber:

GeschichteAuswählen.


Dies ist eine wahnsinnig teure Funktion. Und leider kann keine noch so gute Zwischenspeicherung die Geschwindigkeit akzeptabel machen.


Bei EAs für Schlachtfelder ist es zum Beispiel wichtig, mit aktuellen Daten zu arbeiten. Insbesondere, dass die Ticks von Market Watch und CopyTicks möglichst nicht veraltet sind.

Dazu gibt es zwar nicht sehr gute, aber erzwungene Mechanismen zur Überprüfung der Relevanz aktueller Preisdaten. Ein Teil dieses Mechanismus besteht darin, Situationen zu erkennen, in denen ein Handel mit einem Symbol später als der letzte Tick stattgefunden hat. Das passiert nicht selten, daher ist es wichtig zu wissen, ob der aktuelle Tick noch aktuell ist oder nicht.


Für diese Erkennung müssen Sie auf die Historie der letzten Geschäfte zugreifen können. Dies geschieht mit Hilfe von HistorySelect auf die folgende schematische Weise.


Leider dauert ein solcher Aufruf von HistorySelect 5-30 Millisekunden (ich habe es selbst in Release-EX5 gemessen). Wenn der Expert Advisor mehrere solcher Aktualisierungen in OnTick durchführt (dies sollte nach jeder Pause geschehen, z. B. nach jedem OrderSend), dann wird alles wahnsinnig teuer/langwierig. HistorySelect kann insgesamt mehrere Sekunden in einem einzigen OnTick verbrauchen.


Liebe Entwickler, warum ist es so teuer? Diese Funktion kann bei richtiger Implementierung sofort ausgeführt werden.

Haben Sie Beweise für "ein solcher Aufruf von HistorySelect dauert 5-30 Millisekunden"?

Wenn ich Ihre Idee richtig verstanden habe, dann sollte der Testcode wie folgt aussehen:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
   ulong start=GetMicrosecondCount();
   for(int i=0; i<100000; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;
   Print("100000 HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
  }

So funktionieren 100000 Abfragen:

100000 HistorySelect = 141.63 ms
 
Anton:

Haben Sie Beweise für "ein solcher Aufruf von HistorySelect dauert 5-30 Millisekunden"?

Wenn ich Sie richtig verstanden habe, dann sollte der Testcode so aussehen:

So funktionieren 100.000 Abfragen:

Und eine Anfrage? Es würde mich nicht wundern, wenn der Compiler bei der Optimierung genau das tut)))
 
Anton:

Haben Sie Beweise für "ein solcher Aufruf von HistorySelect dauert 5-30 Millisekunden"?

Wenn ich Sie richtig verstanden habe, dann sollte der Testcode so aussehen:

So funktionieren 100.000 Abfragen:

Ihr Skript ausführen.

        100000 HistorySelect = 19493.96 ms


Starten Sie ein anderes Skript.

#define  PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{
  if (HistorySelect(0, INT_MAX))
  {
    PRINT(HistoryDealsTotal());
    PRINT(HistoryOrdersTotal());
  }
}


HistoryDealsTotal() = 17828
HistoryOrdersTotal() = 22142


Normale Kampfanzahl. Nicht HFT.


Übrigens hat Ihr Skript gezeigt, dass HistorySelect alles jedes Mal neu berechnet. Und die Eingabeparameter haben sich nicht geändert, die History-Tabelle wurde nicht aktualisiert, andere HistorySelect-Funktionen wurden nicht aufgerufen.

 
fxsaber:

Ihr Skript ausführen.

Dann sind Details erforderlich.

Mein Test lief auf dem nicht gerade schnellsten "Intel Xeon E5-2630 v4 @ 2.20GHz" mit einer Menge anderer Prozesse im Hintergrund.

Die Historie meines Testkontos zeigt 31315 mehr oder weniger gleichmäßige Aufträge seit 2009, darunter 8 Aufträge für heute.

Vielleicht hatten Sie zur gleichen Zeit ein Skript oder einen Expert Advisor laufen, der die Terminal-Datenbanken drastisch belastet hat. Versuchen Sie es mit einem "sauberen" Terminal.

Informativerer Test:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
//---   
   ulong start=GetMicrosecondCount();
   int count=100000;
   for(int i=0; i<count; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;

   Print(count," HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
   Print("Selected = ",HistoryOrdersTotal());
//---   
   Tick.time=(Tick.time/86400)*86400;
   
   start=GetMicrosecondCount();
   count=1000;
   for(int i=0; i<count; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   end=GetMicrosecondCount()-start;

   Print(count," HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
   Print("Selected = ",HistoryOrdersTotal());
//---   
   HistorySelect(0, INT_MAX);
   Print("Selected = ",HistoryOrdersTotal());
  }

Drei Durchgänge:

2020.05.29 13:53:14.281 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 141.76 ms
2020.05.29 13:53:14.281 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:14.284 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.82 ms
2020.05.29 13:53:14.284 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:15.566 TestHistorySelect (EURUSD,H1)   Selected = 31315
2020.05.29 13:53:16.930 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 138.30 ms
2020.05.29 13:53:16.930 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:16.933 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.61 ms
2020.05.29 13:53:16.933 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:18.176 TestHistorySelect (EURUSD,H1)   Selected = 31315
2020.05.29 13:53:22.217 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 142.94 ms
2020.05.29 13:53:22.217 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:22.220 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.57 ms
2020.05.29 13:53:22.220 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:23.498 TestHistorySelect (EURUSD,H1)   Selected = 31315
 
Anton:

Dann sind Details erforderlich.

Mein Test lief auf dem nicht gerade schnellsten "Intel Xeon E5-2630 v4 @ 2.20GHz" mit vielen anderen Prozessen im Hintergrund.

Das Testkonto hatte seit 2009 mehr oder weniger gleichmäßig 31315 Aufträge, darunter 8 Aufträge für heute.

Vielleicht hatten Sie zur gleichen Zeit ein Skript oder einen Expert Advisor laufen, der die Terminal-Datenbanken drastisch belastet hat. Versuchen Sie es mit einem "sauberen" Terminal.

Leeren Sie das Terminal auf demselben Konto und Rechner.

        100000 HistorySelect = 19367.01 ms


Auf anderen Konten und Terminals das gleiche Bild. Konfiguration.

2020.05.29 13:53:44.766 Terminal        ICMarkets - MetaTrader 5 x64 build 2453 started for International Capital Markets Pty Ltd.
2020.05.29 13:53:44.766 Terminal        Windows 7 Service Pack 1 build 7601, Intel Core i7-2700 K  @ 3.50 GHz, 6 / 15 Gb memory, 4 / 29 Gb disk, IE 11, Admin, GMT+2


Ich bitte die Leser, ihre Ergebnisse zu diesem Skript mitzuteilen.

void OnStart()
{
  // https://www.mql5.com/ru/forum/342090/page2#comment_16607997
#define  PRINT(A) Print(#A + " = " + (string)(A))
  
  if (HistorySelect(0, INT_MAX))
  {
    PRINT(HistoryDealsTotal());
    PRINT(HistoryOrdersTotal());
  }

   // https://www.mql5.com/ru/forum/342090/page2#comment_16607922
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
   ulong start=GetMicrosecondCount();
   for(int i=0; i<100000; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;
   Print("100000 HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
}
 
Anton:

Ein informativerer Test:

Drei Anläufe:

        100000 HistorySelect = 18344.01 ms
        Selected = 0
        1000 HistorySelect = 602.77 ms
        Selected = 1169
        Selected = 22142
        100000 HistorySelect = 18331.15 ms
        Selected = 0
        1000 HistorySelect = 446.45 ms
        Selected = 1169
        Selected = 22142
        100000 HistorySelect = 18495.35 ms
        Selected = 0
        1000 HistorySelect = 549.40 ms
        Selected = 1169
        Selected = 22142

Leeres Terminal 2460.


ZS Run on empty account.

        100000 HistorySelect = 28.30 ms
        Selected = 0
        1000 HistorySelect = 0.28 ms
        Selected = 0
        Selected = 0


Die Geschwindigkeit scheint stark von der Anzahl der Trades und nicht von den Aufträgen beeinflusst zu werden.

 
fxsaber:

Leeren Sie das Terminal auf demselben Konto und Rechner.


Auf anderen Konten und Terminals das gleiche Muster. Konfiguration.


Ich bitte die Leser, ihre Ergebnisse zu diesem Skript zu nennen.

Das beweist zwar nichts, aber die Tatsache, dass sich die Zeit mit jedem neuen Durchlauf (auf einem anderen Symbol) erhöht, ist alarmierend...

2020.05.29 13:59:36.625 test1 (USDJPY,H1)       HistoryDealsTotal() = 1
2020.05.29 13:59:36.626 test1 (USDJPY,H1)       HistoryOrdersTotal() = 0
2020.05.29 13:59:36.642 test1 (USDJPY,H1)       100000 HistorySelect = 16.00 ms
2020.05.29 13:59:53.522 test1 (EURUSD,H1)       HistoryDealsTotal() = 1
2020.05.29 13:59:53.522 test1 (EURUSD,H1)       HistoryOrdersTotal() = 0
2020.05.29 13:59:53.546 test1 (EURUSD,H1)       100000 HistorySelect = 24.36 ms
2020.05.29 14:00:03.640 test1 (USDCHF,H1)       HistoryDealsTotal() = 1
2020.05.29 14:00:03.640 test1 (USDCHF,H1)       HistoryOrdersTotal() = 0
2020.05.29 14:00:03.669 test1 (USDCHF,H1)       100000 HistorySelect = 29.25 ms
2020.05.29 14:00:14.994 test1 (GBPUSD,H1)       HistoryDealsTotal() = 1
2020.05.29 14:00:14.994 test1 (GBPUSD,H1)       HistoryOrdersTotal() = 0
2020.05.29 14:00:15.026 test1 (GBPUSD,H1)       100000 HistorySelect = 31.76 ms
 
Сергей Таболин:

Sie müssen auf einem Konto mit einer langen Handelsgeschichte laufen.