MT5 und Geschwindigkeit in Aktion - Seite 64

 

Anton:

Ihr EA läuft auf Idle-CPU, RannForex-Server, 6 Charts mit verschiedenen Symbolen. Als ich zu meinem Computer zurückkam, sah ich eine Menge davon.

2020.10.30 13:50:21.852 Test9 (GBPUSD,H1)       SymbolInfoTick max bad time: 2.008 ms; avr bad time: 2.008 ms; bad iterations: 1 total iterations: 10000000
2020.10.30 13:50:22.142 Test9 (EURUSD,H1)       GetBid max bad time: 1.125 ms; avr bad time: 1.125 ms; bad iterations: 1 total iterations: 10000000
2020.10.30 13:50:23.072 Test9 (USDCHF,H1)       SymbolInfoTick max bad time: 2.245 ms; avr bad time: 2.245 ms; bad iterations: 1 total iterations: 10000000
2020.10.30 13:50:23.288 Test9 (USDCAD,H1)       GetBid max bad time: 1.298 ms; avr bad time: 1.182 ms; bad iterations: 2 total iterations: 10000000
2020.10.30 13:50:23.297 Test9 (AUDCAD,H1)       GetBid max bad time: 0.977 ms; avr bad time: 0 ms; bad iterations: 0 total iterations: 10000000
2020.10.30 13:50:24.393 Test9 (EURUSD,H1)       SymbolInfoTick max bad time: 3.400 ms; avr bad time: 2.862 ms; bad iterations: 2 total iterations: 10000000


Ich habe eine schlechte Zeitbedingung wie diese.

      if(end>1000)
        {
         avr_time+=end;
         counter++;
        }


SZZ Ich habe den Code beigefügt, um die Objektivität der Forumsmitglieder zu gewährleisten.

Dateien:
Test9.mq5  6 kb
 
fxsaber:

Ihr EA läuft auf Idle-CPU, RannForex-Server, 6 Charts mit verschiedenen Symbolen. Als ich zu meinem Computer zurückkam, sah ich eine Menge davon.

Wenn ich es richtig verstanden habe, laufen in diesem Test 6 EAs in einer Schleife auf 4 CPU-Kernen, und jeder versucht, einen Kern zu 100 % auszulasten. Das heißt, es handelt sich definitiv um einen Stresstest, der sehr weit von normalen Betriebsbedingungen entfernt ist.

Unter solchen Bedingungen sind 1 oder 2 Auswürfe von 1-2ms für 10 Millionen Abfragen ein hervorragendes Ergebnis.

Und noch einmal zur Erinnerung: Je größer die Belastung, desto mehr testen Sie die Effizienz des Task-Planers des Betriebssystems, nicht des Terminals. Lassen Sie sich nicht täuschen.

 
pivomoe:

Ich habe eine Frage zur Relevanz der von SymbolInfoTick angegebenen Ticks.

Situation:

1. Wir machen TimeCurretn(); wir erhalten die Zeit 18:00:00

2. SymbolInfoTick bei einem ungültigen Symbol ausführen. Wir erhalten ein Häkchen mit der Zeit 17:58:00.

3. schlafen(1)

4. Fügt einen SymbolInfoTick für das nicht linke Symbol hinzu. Wir erhalten ein Häkchen mit der Uhrzeit 17:59:00.


D.h. im vierten Element haben wir einen neuen Tick, der eine Minute anders ist als TimeCurretn().

Sehen Sie in dieser Situation ein Problem?

Wie kommt man seltener in diese Situation?

Test EA.

// Проверочный советник на корректность последовательного прихода тиков в MT5.

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

string Symbols[];
MqlTick LastTicks[]; // Последние тики из Обзора рынка.

const int Size2 = ArrayResize(Symbols, SymbolsTotal(true));

int OnInit()
{
  for (int i = 0; i < Size2; i++)
    Symbols[i] = SymbolName(i, true);
  
  GetMarketWatch(LastTicks);
    
  return(!EventSetMillisecondTimer(1));
}

// Получает тики из Обзора рынка.
void GetMarketWatch( MqlTick &Ticks[] )
{
  for (int i = ArrayResize(Ticks, Size2) - 1; i >= 0; i--)
    SymbolInfoTick(Symbols[i], Ticks[i]);
}

// Возвращает индекс самого свежего тика.
int GetLastTick( const MqlTick &Ticks[] )
{
  long LastTime = 0;
  int Pos = 0;
  
  for (int i = 0; i < Size2; i++)
    if (Ticks[i].time_msc > LastTime)
    {
      LastTime = Ticks[i].time_msc;
      
      Pos = i;
    }
  
  return(Pos);
}

// Возвращает индекс измененного тика с наименьшим временем.
int GetFirstFreshTick( const MqlTick &PrevTicks[], const MqlTick &NewTicks[] )
{
  long LastTime = LONG_MAX;
  int Pos = -1;
  
  for (int i = 0; i < Size2; i++)
    if ((_R(PrevTicks[i]) != NewTicks[i]) && (NewTicks[i].time_msc < LastTime))
    {
      LastTime = NewTicks[i].time_msc;
      
      Pos = i;
    }
  
  return(Pos);
}

// Распечатка тика.
void PrintTick( const string Str, const MqlTick &Ticks[], const int Pos )
{
  Print(Str + " " + Symbols[Pos] + ":");
  ArrayPrint(Ticks, 5, NULL, Pos, 1);
}

void OnTimer()
{  
  MqlTick NewTicks[];
  
  GetMarketWatch(NewTicks); // Получили все тики из Обзора рынка
  
  const int FirstFreshPos = GetFirstFreshTick(LastTicks, NewTicks); // Взяли самый ранний тик из вновь пришедших.
  
  if (FirstFreshPos != -1) // Если пришедшие тики были.
  {
    const int LastPos = GetLastTick(LastTicks); // Взяли самый свежий тик с предыдущего запроса Обзора рынка.
    
    if (NewTicks[FirstFreshPos].time_msc < LastTicks[LastPos].time_msc) // Если нарушена временная последовательность.
    {
      Alert("BUG?"); // Сообщаем об этом.
      
      PrintTick("PrevTick", LastTicks, LastPos);
      PrintTick("NewTick", NewTicks, FirstFreshPos);
    }
     
    ArraySwap(LastTicks, NewTicks); // Запоминаем последний опрос Обзора рынка.
  }  
}


Ich habe kein Alertite. Ergebnis (bei sechs Karten).

2020.10.30 16:08:51.130 Test9 (GBPUSD,H1)       Alert: BUG?
2020.10.30 16:08:51.130 Test9 (GBPUSD,H1)       PrevTick EURAUD:
2020.10.30 16:08:51.130 Test9 (GBPUSD,H1)                        [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:08:51.130 Test9 (GBPUSD,H1)       [0] 2020.10.30 16:08:56 1.65631 1.65637 0.0000        0 1604074136152       6       0.00000
2020.10.30 16:08:51.130 Test9 (GBPUSD,H1)       NewTick EURSGD:
2020.10.30 16:08:51.130 Test9 (GBPUSD,H1)                        [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:08:51.130 Test9 (GBPUSD,H1)       [0] 2020.10.30 16:08:56 1.59391 1.59404 0.0000        0 1604074136149       4       0.00000
2020.10.30 16:09:14.707 Test9 (USDCHF,H1)       Alert: BUG?
2020.10.30 16:09:14.707 Test9 (USDCHF,H1)       PrevTick EURGBP:
2020.10.30 16:09:14.707 Test9 (USDCHF,H1)                        [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:09:14.707 Test9 (USDCHF,H1)       [0] 2020.10.30 16:09:19 0.90135 0.90138 0.0000        0 1604074159733       4       0.00000
2020.10.30 16:09:14.707 Test9 (USDCHF,H1)       NewTick XAUUSD:
2020.10.30 16:09:14.707 Test9 (USDCHF,H1)                        [time]      [bid]      [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:09:14.707 Test9 (USDCHF,H1)       [0] 2020.10.30 16:09:19 1882.94000 1882.97000 0.0000        0 1604074159728       6       0.00000
2020.10.30 16:09:19.935 Test9 (GBPUSD,H1)       Alert: BUG?
2020.10.30 16:09:19.935 Test9 (GBPUSD,H1)       PrevTick AUDNZD:
2020.10.30 16:09:19.935 Test9 (GBPUSD,H1)                        [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:09:19.935 Test9 (GBPUSD,H1)       [0] 2020.10.30 16:09:24 1.06010 1.06012 0.0000        0 1604074164946       4       0.00000
2020.10.30 16:09:19.935 Test9 (GBPUSD,H1)       NewTick USDNOK:
2020.10.30 16:09:19.935 Test9 (GBPUSD,H1)                        [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:09:19.935 Test9 (GBPUSD,H1)       [0] 2020.10.30 16:09:24 9.50256 9.50288 0.0000        0 1604074164945       2       0.00000
2020.10.30 16:09:23.612 Test9 (USDJPY,H1)       Alert: BUG?
2020.10.30 16:09:23.612 Test9 (USDJPY,H1)       PrevTick USDCAD:
2020.10.30 16:09:23.612 Test9 (USDJPY,H1)                        [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:09:23.612 Test9 (USDJPY,H1)       [0] 2020.10.30 16:09:28 1.33050 1.33052 0.0000        0 1604074168639       2       0.00000
2020.10.30 16:09:23.612 Test9 (USDJPY,H1)       NewTick XAUUSD:
2020.10.30 16:09:23.612 Test9 (USDJPY,H1)                        [time]      [bid]      [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:09:23.612 Test9 (USDJPY,H1)       [0] 2020.10.30 16:09:28 1883.11000 1883.18000 0.0000        0 1604074168634       4       0.00000


Es gibt ein Problem. Es ist schwer zu sagen, wie ernst es ist.

 
Anton:

Wenn ich es richtig verstehe, laufen in diesem Test 6 EAs in einer Schleife auf 4 CPU-Kernen, und jeder versucht, einen Kern zu 100 % auszulasten. Das heißt, es handelt sich definitiv um einen Stresstest, der sehr weit von normalen Betriebsbedingungen entfernt ist.

Ist dieser EA ein Stresstest? Ich frage Sie das, weil ich in der letzten Zeit

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

void GetMarketWatch( MqlTick &Ticks[] )
{
  for (int i = ArrayResize(Ticks, Size2) - 1; i >= 0; i--)
    _B(SymbolInfoTick(Symbols[i], Ticks[i]), 100);
}

gibt ein Meer von Warnungen aus.

2020.10.30 16:18:53.713 Test9 (USDJPY,H1)       Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 107 in GetMarketWatch: SymbolInfoTick(Symbols[i],Ticks[i])] = 166 mcs.
2020.10.30 16:18:53.729 Test9 (USDJPY,H1)       Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 107 in GetMarketWatch: SymbolInfoTick(Symbols[i],Ticks[i])] = 120 mcs.
2020.10.30 16:18:53.901 Test9 (EURUSD,H1)       Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 107 in GetMarketWatch: SymbolInfoTick(Symbols[i],Ticks[i])] = 127 mcs.
2020.10.30 16:18:53.917 Test9 (EURUSD,H1)       Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 107 in GetMarketWatch: SymbolInfoTick(Symbols[i],Ticks[i])] = 131 mcs.
2020.10.30 16:18:55.141 Test9 (USDCHF,H1)       Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 107 in GetMarketWatch: SymbolInfoTick(Symbols[i],Ticks[i])] = 104 mcs.
2020.10.30 16:18:55.204 Test9 (EURUSD,H1)       Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 107 in GetMarketWatch: SymbolInfoTick(Symbols[i],Ticks[i])] = 107 mcs.
 

Es gibt einen Fehler in der seriellen Log-Ausgabe von ArrayPrint.

2020.10.30 16:26:05.320 Test9 (USDCAD,H1)       PrevTick AUDCAD:
2020.10.30 16:26:05.320 Test9 (GBPUSD,H1)       NewTick XAUEUR:
2020.10.30 16:26:05.320 Test9 (GBPUSD,H1)                        [time]      [bid]      [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:26:05.320 Test9 (USDCAD,H1)                        [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2020.10.30 16:26:05.320 Test9 (GBPUSD,H1)       [0] 2020.10.30 16:26:10 1612.03000 1612.43000 0.0000        0 1604075170357       4       0.00000
2020.10.30 16:26:05.320 Test9 (USDCAD,H1)       [0] 2020.10.30 16:26:10 0.93785 0.93790 0.0000        0 1604075170359       4       0.00000

Es ist klar, dass dies ein Fehler ist, da es sich um den Quellcode handelt.

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

MT5 und Geschwindigkeit in Aktion

fxsaber, 2020.10.30 15:04

// Распечатка тика.
void PrintTick( const string Str, const MqlTick &Ticks[], const int Pos )
{
  Print(Str + " " + Symbols[Pos] + ":");
  ArrayPrint(Ticks, 5, NULL, Pos, 1);
}

      PrintTick("PrevTick", LastTicks, LastPos);
      PrintTick("NewTick", NewTicks, FirstFreshPos);
Dies ist ein ziemlich typischer Fehler. Die aktuelle Implementierung von ArrayPrint druckt Zeichenketten durch aufeinanderfolgende Aufrufe mehrerer Prints. Sie sollten zunächst eine große Zeichenkette mit allen Daten bilden und diese dann über einen einzigen Druckvorgang ausgeben.
 

Ich habe mehrmals jede Sekunde Alert ausgelöst.

17:59:50.126    Temp (SILV-9.21,H1)                      [time]     [bid]     [ask]    [last] [volume]    [time_msc] [flags] [volume_real]
KD      0       17:59:50.126    Temp (SILV-9.21,H1)     [0] 2020.10.30 17:59:49 155.38000 155.39000 155.38000        3 1604080789146       0       3.00000
CH      0       17:59:50.141    Temp (SILV-9.21,H1)     Alert: BUG?
JO      0       17:59:50.141    Temp (SILV-9.21,H1)     PrevTick Si-12.20:
LE      0       17:59:50.141    Temp (SILV-9.21,H1)                      [time]       [bid]       [ask]      [last] [volume]    [time_msc] [flags] [volume_real]
OK      0       17:59:50.141    Temp (SILV-9.21,H1)     [0] 2020.10.30 17:59:49 79741.00000 79742.00000 79743.00000        1 1604080789200       0       1.00000
QF      0       17:59:50.141    Temp (SILV-9.21,H1)     NewTick ROSN:
FS      0       17:59:50.141    Temp (SILV-9.21,H1)                      [time]     [bid]     [ask]    [last] [volume]    [time_msc] [flags] [volume_real]
HR      0       17:59:50.141    Temp (SILV-9.21,H1)     [0] 2020.10.30 17:59:49 349.80000 349.95000 349.85000       57 1604080789179       0      57.00000
 
War am Computer, hat keine Berechnungen gemacht. Die CPU wurde nicht mit irgendetwas belastet.
2020.11.03 16:04:01.137         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 48764 mcs.
2020.11.03 18:31:04.622         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 4143 mcs.
2020.11.03 19:00:34.117         Bench_Stack = 2, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1069 mcs.
2020.11.03 19:00:34.117         Bench_Stack = 2, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1100 mcs.
2020.11.03 19:01:49.199         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 19301 mcs.

19 ms und 48 ms für die Ausführung von SymbolInfoTick. Es gab mehrere Dutzend Fälle, in denen die Dauer Hunderte von Mikrosekunden betrug. Aber ich habe sie nicht zitiert.


Offenbar müssen wir, um es zu reproduzieren, die Kampfberater 24 Stunden lang laufen lassen und dann nur noch beobachten. Meiner Meinung nach ist es unrealistisch, herauszufinden, was solche Verzögerungen auslöst.

 

Ich habe mir den Test9-Code oben auf der Seite angesehen. Warum 10 Millionen Mal ohne Schlaf, um Ticks von einem Symbol abzufragen? Was hat dieser Test mit dem realen Handel zu tun?

Ich denke, der Test sollte wie folgt aussehen: Wir fordern für jedes Symbol in der Marktübersicht einen Tick an. Wir pausieren Sleep(1) und so weiter. Überarbeiten Sie Ihren Code geringfügig:

int OnInit()
{
   string Symbols[];
   int    TotalSymbol= SymbolsTotal(true);
   
   ArrayResize(Symbols,TotalSymbol);
   for(int i=0;i<TotalSymbol;i++)
   Symbols[i]= SymbolName(i, true);
   
   
   MqlTick Tick;
//---
   double temp=0;
   ulong start,end,max_time=0,avr_time=0,counter=0;
   int   count=1 e4;
   
   for(int i=0; !IsStopped() && (i<count); i++)
     {
      Sleep(1);   
      for(int j=0;j<TotalSymbol;j++)
        {
         start=GetMicrosecondCount();   
         SymbolInfoTick(Symbols[j], Tick);
        // temp++;
         
         end=GetMicrosecondCount()-start;
      //---
         if(end>max_time)
         max_time=end;
         if(end>1000)
        {
         avr_time+=end;
         counter++;
        }
       } 
     }
   Comment("SymbolInfoTick max bad time: ",DoubleToString(max_time/1000.0,3)," ms; avr bad time: ",counter ? DoubleToString(avr_time/1000.0/counter,3):"0"," ms; bad iterations: ",counter," total iterations: ",count);
   Print("SymbolInfoTick max bad time: ",DoubleToString(max_time/1000.0,3)," ms; avr bad time: ",counter ? DoubleToString(avr_time/1000.0/counter,3):"0"," ms; bad iterations: ",counter," total iterations: ",count);
   return INIT_FAILED;
  }  

Testen Sie 55 Symbole in der Übersicht.

SymbolInfoTick max bad time: 0.212 ms; avr bad time: 0 ms; bad iterations: 0 total iterations: 10000

Testen wir nun temp++ anstelle von SymbolInfoTick;

SymbolInfoTick max bad time: 0.102 ms; avr bad time: 0 ms; bad iterations: 0 total iterations: 10000
 
pivomoe:

Ich habe mir den Test9-Code oben auf der Seite angesehen. Warum 10 Millionen Mal ohne Schlaf, um Zecken von einem Zeichen zu verlangen?

Ganz und gar nicht. Lesen Sie die Zweigstelle für weitere Einzelheiten.

 
fxsaber:

Nicht auf gleicher Augenhöhe. Lesen Sie den Thread für Details.

Verwirrt Sie nicht die Tatsache, dass selbst die maximale Ausführungszeit von temp++ bei dieser Messtechnik einige zehn Mikrosekunden beträgt?