MT5 et la vitesse en action - page 64

 

Anton:

Exécution de votre EA sur Idle-CPU, RannForex-Server, 6 graphiques avec différents symboles. Quand je suis revenu à mon ordinateur, j'en ai vu beaucoup.

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


J'ai une mauvaise condition de temps comme ça.

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


SZZ J'ai joint le code pour l'objectivité de la part des membres du forum.

Dossiers :
Test9.mq5  6 kb
 
fxsaber:

Exécution de votre EA sur Idle-CPU, RannForex-Server, 6 graphiques avec différents symboles. Quand je suis revenu à mon ordinateur, j'ai vu beaucoup de choses de ce genre.

Si j'ai bien compris, dans ce test il y a 6 EAs en boucle qui tournent sur 4 cœurs de CPU, et chacun essaie de charger un cœur à 100%. C'est-à-dire qu'il s'agit bien d'un test de stress, très éloigné des conditions normales de fonctionnement.

Dans ces conditions, 1 ou 2 éjections de 1-2ms pour 10 millions de requêtes est un excellent résultat.

Et une fois de plus, je vous le rappelle : plus la charge est importante, plus vous testez l'efficacité du planificateur de tâches du système d'exploitation, et non du terminal. Ne vous laissez pas berner.

 
pivomoe:

J'ai une question sur la pertinence des ticks donnés par SymbolInfoTick.

Situation :

1. Nous faisons TimeCurretn() ; nous obtenons le temps 18:00:00

2. Effectue SymbolInfoTick sur un symbole non étiqueté. Nous obtenons un tic-tac avec l'heure 17:58:00.

3. Sommeil(1)

4. Ajoute un SymbolInfoTick pour le symbole non gauche. Nous obtenons un tick avec l'heure 17:59:00.


C'est-à-dire que dans le quatrième élément, nous avons un nouveau tick, qui est différent d'une minute de TimeCurretn().

Voyez-vous un problème dans cette situation ?

Comment se retrouver plus rarement dans cette 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); // Запоминаем последний опрос Обзора рынка.
  }  
}


Je n'ai pas d'Alertite. Résultat (testé sur six tableaux).

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


Il y a un problème. C'est difficile de dire à quel point c'est sérieux.

 
Anton:

Si je comprends bien, dans ce test il y a 6 EAs en boucle qui tournent sur 4 cœurs de CPU, et chacun essaie de charger un cœur à 100%. C'est-à-dire qu'il s'agit bien d'un test de stress, très éloigné des conditions normales de fonctionnement.

Est-ce que cette EA est un test de stress ? Je te demande ça parce que ça a été mesuré...

#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);
}

donne une mer d'alertes.

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.
 

Il y a un bogue dans la sortie du journal de série de 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

Il est clair qu'il s'agit d'une erreur, puisqu'il s'agit du code source.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

MT5 et la vitesse en action

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);
C'est un bug assez typique. L'implémentation actuelle de ArrayPrint imprime des chaînes de caractères via des appels consécutifs à plusieurs Prints. Vous devez d'abord former une grande chaîne de caractères avec toutes les données, puis l'imprimer avec une seule impression.
 

J'ai déclenché l'alerte à chaque seconde de nombreuses fois.

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
 
J'étais devant l'ordinateur, je n'ai pas fait de calculs. Je n'ai pas chargé le processeur avec quoi que ce soit.
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 et 48 ms pour l'exécution de SymbolInfoTick. Il y avait plusieurs dizaines de cas où la durée était de plusieurs centaines de microsecondes. Mais je ne les ai pas cités.


Apparemment, pour le reproduire, il faut faire tourner des conseillers de combat pendant 24 heures, et ensuite seulement regarder. À mon avis, il est irréaliste de chercher à savoir ce qui est à l'origine de ces décalages.

 

J'ai regardé le code de Test9 en haut de la page. Pourquoi 10 millions de fois sans aucun sommeil pour demander les ticks d'un symbole ? Quel est le rapport entre ce test et le trading réel ?

Je pense que le test devrait ressembler à ceci : Nous demandons le tick de chaque symbole dans la revue de marché. On met en pause Sleep(1) et ainsi de suite. Retravaillez légèrement votre code :

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;
  }  

Testez 55 symboles dans la vue d'ensemble.

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

Maintenant testons temp++ au lieu de SymbolInfoTick;

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

J'ai regardé le code de Test9 en haut de la page. Pourquoi 10 millions de fois sans aucun sommeil pour demander des ticks à un personnage ?

Pas du tout. Lisez la branche pour plus de détails.

 
fxsaber:

Pas sur un pied d'égalité. Lisez le fil de discussion pour plus de détails.

N'êtes-vous pas troublé par le fait que même le temps d'exécution maximal de Temp++ prend des dizaines de microsecondes, avec cette technique de mesure ?

Raison: