MT5 und Geschwindigkeit in Aktion - Seite 48

 
fxsaber:

Drucken und Alert sind nicht asynchron?

Ich wollte diese Funktionen asynchron machen. Versucht eine Implementierung durch ChartEvent - es funktioniert. Aber es ist sehr langsam. Ich hatte das hier ausgegraben.

#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

void OnTick()
{
  _B(EventChartCustom(ChartFirst(), 123, 0, 0, NULL), 1);
}


2020.10.07 12:38:04.579 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 100 mсs.
2020.10.07 12:38:06.842 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 170 mсs.
2020.10.07 12:38:07.924 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 765 mсs.
2020.10.07 12:38:08.359 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 377 mсs.
2020.10.07 12:38:09.246 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 66 mсs.
2020.10.07 12:38:14.645 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 692 mсs.
2020.10.07 12:38:14.729 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 6427 mсs.
2020.10.07 12:38:15.140 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 479 mсs.
2020.10.07 12:38:15.222 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 125 mсs.
2020.10.07 12:38:15.373 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 606 mсs.


Auf eine so teure Funktion an kritischen Stellen wurde verzichtet.


Zum Thema "Alert".

Bisher können wir mit Sicherheit sagen, dass Alert an kritischen Stellen nicht möglich ist. Asynchronität ist erforderlich.

 

Reproduziert die SymbolInfoTick-Bremsen. Und kein Stresstest. Die praktische Notwendigkeit zwingt Sie, es so zu schreiben.

#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

// Возвращает время Обзора рынка в миллисекундах.
long TimeCurrentMsc()
{
  long Res = 0;
  
  MqlTick Tick;
  
  for (int i = SymbolsTotal(true); i >= 0; i--) 
  {
    const string Symb = SymbolName(i, true);
    
    if (_B(SymbolInfoTick(Symb, Tick), 10) && (Tick.time_msc > Res))
      Res = Tick.time_msc;
  }

  return(Res);
}

void OnTick()
{ 
  TimeCurrentMsc();
}


Folgen Sie dieser Anleitung für eine schnelle Wiedergabe.

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Synchroner OrderSend meldet erfolgreiche Ausführung schneller als Ping zum Handelsserver

fxsaber, 2020.09.30 20:36

  1. Eröffnen Sie ein Demokonto auf demRannForex-Server.
  2. Öffnen Sie die Forex-Symbole in der Marktübersicht und erlauben Sie den Autotrading.
  3. Starten Sie diesen EA in einem einzelnen Chart.
  4. Setzen Sie dieses Skript auf demselben Chart ein - es wird den EA auf andere Symbole klonen. Führen Sie es mit inAmount = 15 aus.
  5. Warten Sie auf solche Meldungen und beobachten Sie das Protokoll.


Auf einem schnellen Rechner wird das Ergebnis mit 30 Zeichen in Market Watch angezeigt.

2020.10.07 13:28:01.931 Test9 (NZDCHF,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 65 mсs.
2020.10.07 13:28:02.344 Test9 (EURAUD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 11 mсs.
2020.10.07 13:28:02.730 Test9 (EURAUD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 15 mсs.
2020.10.07 13:28:02.800 Test9 (AUDCHF,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 11 mсs.
2020.10.07 13:28:05.471 Test9 (GBPAUD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 30 mсs.
2020.10.07 13:28:08.675 Test9 (NZDCHF,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 28 mсs.
2020.10.07 13:28:08.675 Test9 (GBPAUD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 120 mсs.
2020.10.07 13:28:09.697 Test9 (CADCHF,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 13 mсs.
2020.10.07 13:28:10.063 Test9 (EURCAD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 29 mсs.
2020.10.07 13:28:11.741 Test9 (CADJPY,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 32 mсs.
2020.10.07 13:28:12.597 Test9 (EURCAD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 33 mсs.


Ich hoffe, ich bin nicht der Einzige, der sich fortpflanzt. Natürlich ist die Verzögerung nicht so groß wie zuvor gezeigt. Aber hier wird es möglich sein, den Ursachen viel schneller auf den Grund zu gehen.


ZZY TimeCurrentMsc wird in MQL5 aus irgendeinem Grund nicht eingegeben, trotz wiederholter Anfragen.

 
fxsaber:

Eine so teure Funktion wurde an kritischen Stellen aufgegeben.

Dies ist ein erheblicher Nachteil. Denn das MQL-Ereignismodell ist unvollständig - es gibt kein Null-Ereignis, d. h. das Ereignis, das aufgerufen wird, wenn keine anderen Ereignisse in der Warteschlange vorhanden sind. Es kann durch ein benutzerdefiniertes Ereignis emuliert werden. Aber unter Berücksichtigung dieses Nachteils ist das Ereignismodell für diejenigen, die an Geschwindigkeit interessiert sind, bedeutungslos

 
fxsaber:

EventChartCustom ist teuer.

Wie sieht es ohneChartFirst() aus?

 
Andrey Khatimlianskii:

Wie wäre es ohne ChartFirst()?

#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

long GetAnotherChart()
{
  long Chart = ::ChartFirst();
  
  while (Chart == ChartID())
    Chart = ChartNext(Chart);
 
  return(Chart);     
}


void OnTick()
{  
  const long Chart = GetAnotherChart();
  
  if (Chart)
    _B(EventChartCustom(Chart, 123, 0, 0, NULL), 1);
  
  _B(EventChartCustom(0, 123, 0, 0, NULL), 1);
}


2020.10.07 14:49:09.786 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 349 mсs.
2020.10.07 14:49:09.786 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 81 mсs.
2020.10.07 14:49:09.866 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 248 mсs.
2020.10.07 14:49:09.866 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 24 mсs.
2020.10.07 14:49:10.095 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 163 mсs.
2020.10.07 14:49:10.095 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 116 mсs.
2020.10.07 14:49:10.810 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 600 mсs.
2020.10.07 14:49:10.811 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 53 mсs.
2020.10.07 14:49:10.870 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 137 mсs.
2020.10.07 14:49:10.870 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 54 mсs.

Es ist teurer, an die Karte eines anderen Unternehmens zu senden als an die eigene.

 
A100:

Dies ist ein erheblicher Mangel. Denn das MQL-Ereignismodell ist unvollständig - es gibt kein Null-Ereignis, d. h. ein Ereignis, das aufgerufen wird, wenn keine anderen Ereignisse in der Warteschlange vorhanden sind. Es kann durch ein benutzerdefiniertes Ereignis emuliert werden. Aber angesichts dieses Nachteils ist das ereignisbasierte Modell für diejenigen, die an Geschwindigkeit interessiert sind, bedeutungslos

Mit OnTimer können Sie Hintergrundgespräche mit einer Dauer von bis zu 16 ms führen.
 
Renat Fatkhullin:
Mit OnTimer können Sie Hintergrundgespräche mit einer Frequenz von bis zu 16 ms führen.

Richtig, d.h. wir verlieren mindestens16ms bis zum Nichts (wir können frühestens zurückkommen).Und wir konnten sie nicht verlieren, wenn es ein kostenloses Null-Ereignis oder kostenlose benutzerdefinierte Ereignisse gab. Und nun funktioniert das Ereignismodell im folgenden Fall nur begrenzt:

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

MT5 und Geschwindigkeit in Aktion

fxsaber, 2020.10.06 01:27

Sie sind nicht auf dem Laufenden. Nehmen wir an, Sie müssen zwei Positionen in OnTick eröffnen. Der erste OrderSend dauert einige Millisekunden. Danach müssen Sie einen Schnappschuss machen. Und dann sollte der zweite OrderSend aufgerufen werden.

Nur OnTick kann Hunderte von Millisekunden lang ausgeführt werden. Und Sie schlagen vor, ein paar OnTimer zu knipsen.

Und OnTimer ist für andere Zwecke frei geworden
 
Außerdem können wir mit OnTimer nicht sicher sein, dass wir ein Null-Ereignis erhalten haben, da es eine höhere Priorität als andere Handler zu haben scheint, was wahrscheinlich das Hauptgegenargument ist.
 
fxsaber:

Zum Thema "Alert".

Im Moment kann man mit Sicherheit sagen, dass Alert nicht an kritischen Stellen eingesetzt werden kann. Asynchronität ist erforderlich.

Warnung mit einem Druck, können Sie versuchen, es mit einem schnellen Schreiben irgendwo zu ersetzen.
Native Sql im Speicher kommt mir in den Sinn

 
Renat Fatkhullin:
Ich habe keinen Schnappschuss vorgeschlagen, sondern auf eine direkte Frage zum Millisekunden-Timer geantwortet.

Sie ist vorhanden, obwohl sie im aktuellen Tester noch mit einer Frequenz von 1 Sekunde ausgelöst wird. In dem neuen Tester, den wir gerade schreiben, werden wir versuchen, dies zu ändern.

Ich nutze oft die Tatsache, dass der Tester genau einen Millisekunden-Timer und keinen Sekunden-Timer hat. Der Beweis.

// Демонстрация корректной работы миллисекундного таймера в Тестере.
#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006
#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnTick()
{
  static bool FirstRun = true;
  
  if (FirstRun)
  {
    MqlTick Tick;
    
    if (SymbolInfoTick(_Symbol, Tick) && Tick.bid && Tick.ask)
      FirstRun = !EventSetMillisecondTimer(29); // 29 мс таймер.
  }
}

void OnTimer()
{
  static int Count = 0;
  
  if (Count < 10)
  {
    if ((bool)((++Count) & 1)) // Попеременно
      OrderSend(_Symbol, OP_BUY, 0.1, Ask, 0, 0, 0); // Открываем позицию
    else if (OrderSelect(0, SELECT_BY_POS))
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0); // Закрываем позицию
  }
}

void OnDeinit( const int )
{
  // Распечатали историю в конце бэктеста.
  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
      OrderPrint();
}


Ergebnis.

2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #11 2020.10.06 00:00:00.320 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.349 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #9 2020.10.06 00:00:00.262 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.291 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #7 2020.10.06 00:00:00.204 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.233 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #5 2020.10.06 00:00:00.146 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.175 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #3 2020.10.06 00:00:00.088 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.117 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #1 2020.10.06 00:00:00.000 balance 0.00 0.00000 0.00000 0.00000 2020.10.06 00:00:00.000 0.00000 0.00 0.00 100000000.00 0

Zwischen Öffnungs- und Schließzeit der Position liegen genau 29 ms.