MT5 et la vitesse en action - page 62

 
Rorschach:
Un noyau en temps réel serait-il utile ?

Mettez plus de cœurs dans le système et ne faites pas de la situation une charge à 100 % d'un seul cœur.

Ne croyez pas aux contes de fées, les processeurs et le planificateur de threads ne fonctionnent pas comme vous l'imaginez.

 
Anton:

Dans les dernières versions, la réception du flux tic n'a aucun effet, même en théorie. Pratiquement, SymbolInfoTick fonctionne déjà avec le cache, mais les particuliers continuent à chercher un chat noir.

Et ce n'est même pas 80% dans le test. Il compte 6 agents fonctionnant sur 4 cœurs, soit une garantie de 100%.

La seule question est de savoir comment le planificateur de tâches de son système gère la situation. Dans le même temps, certains affirment que c'est la mise en œuvre du terminal qui est en cause.

En d'autres termes, une situation est créée artificiellement lorsqu'un ordinateur est surchargé, lorsque littéralement tout ce qui s'y trouve ralentit, et ensuite certaines revendications sont faites sous la forme de "Oh, regardez, pourquoi le terminal traîne-t-il parfois".

Fermons les yeux sur le fait que, même dans de telles conditions, elle est "d'environ 0,01%" - au diable les détails ! Il suffit de dire que "personne ne se soucie de la température moyenne d'un hôpital", "les décalages posent des problèmes lors des transactions" et "nous voulons du HFT".

De plus, il est évident que nous voulons HFT dans 20 experts sur un vieux bureau de bureau ou une machine virtuelle morte.

PS PositionSelectByTicket() dans son implémentation a certainement accès à une ressource partagée avec synchronisation des accès. Et si vous ne sélectionnez pas la position sur chaque appel, vous lisez l'ancien prix. Il était plus facile de faire un "snapshot" via SymbolInfoDouble.

merci

J'ai obtenu ma question parce qu'il y a six mois, j'optimisais mon code et testais la vitesse des fonctions du système, et il y a six mois, SymbolInfoDouble était plus lent que SymbolInfoTick

Peut-être que c'est vrai ce que vous dites. J'ai cherché quelques articles sur le cache multi-core aujourd'hui (je ne me suis pas intéressé à cette information depuis longtemps),

voici un court articlehttps://i2hard.ru/publications/25666/

le fait est que les données ne peuvent être exécutées dans l'ALU qu'à partir du cache L1 qui est très petit et si vous chargez le processeur à pleine vitesse, alors vraiment - le test se transformera en un test du système d'exploitation + un test de la vitesse du cache du processeur (chargement, prédiction des données L1+L3) mais pas en un test des performances du code (application).

 

fxsaber, et si vous définissiez une priorité faible pour les agents dans le gestionnaire de tâches et une priorité élevée pour MT5 ?

Je n'arrive pas à trouver un utilitaire qui bloque l'allocation de tous les programmes/filières du système d'exploitation à un thread spécifique du CPU, sinon il serait possible de réserver un thread pour MT5 et de le bloquer automatiquement pour qu'il ne soit pas utilisé par d'autres programmes, ce qui pourrait en théorie réduire les décalages.

 
Anton:

Dans les dernières versions, la réception du flux tic n'a aucun effet, même en théorie. En pratique, SymbolInfoTick fonctionne déjà avec le cache, mais certains citoyens continuent à chercher un chat noir.

Un citoyen particulier a faitdupliquer le code MQL de son pantalon large qui a montré que la béquille fonctionne plus rapidement que la fonction régulière dans les mêmes conditions.

Mais vous soutenez que votre fonction est bonne, elle a juste des limitations sur les conditions d'utilisation.

Et ce n'est même pas 80% dans le test. Il y a 6 agents fonctionnant sur 4 cœurs, c'est-à-dire 100% garantis.

La seule question est de savoir comment le planificateur de tâches de son système gère la situation. Dans le même temps, certains prétendent que c'est la mise en œuvre du terminal qui est en cause.

En d'autres termes, une situation est créée artificiellement lorsqu'un ordinateur est surchargé jusqu'à ses limites et que tout y est ralenti, puis certaines revendications sont formulées sous la forme de "Oh, regardez, pourquoi le terminal est parfois lent".

6/8 - rien ne traîne. Les navigateurs, la compilation, le débogage, etc. fonctionnent en parallèle sans aucun décalage.

Mais maintenant, j'ai fait exprès de tout éteindre, ne laissant que 4/8 agents. La situation n'a pas changé avec votre freinage de fonction.

Deplus, nous voulons bien sûr HFT en 20 experts sur un vieux bureau de bureau ou une machine virtuelle morte.

Une machine rapide a été utilisée. Et seulement 6 graphiques donnaient déjà le coup de frein.

PS PositionSelectByTicket() dans son implémentation a certainement accès à une ressource partagée avec synchronisation des accès. Et si vous ne sélectionnez pas la position sur chaque appel, vous lisez l'ancien prix. Il était plus facile de faire un "snapshot" via SymbolInfoDouble.

Je l'utilise aussi.

// Снепшот SymbolInfoTick для текущего символа.
bool SymbolInfoTick( MqlTick &Tick )
{
  static MqlTick PrevTick = {0};
  static ulong PrevTime = 0;
  
  const ulong NewTime = GetMicrosecondCount();
  const bool Res = (NewTime - PrevTime < 1000) || (::SymbolInfoTick(_Symbol, PrevTick) && (bool)(PrevTime = NewTime));
  
  Tick = PrevTick;
  
  return(Res);
}
 

De quelle sorte de rapidité dans les performances de combat pouvons-nous parler quand il y a des problèmes dans le terminal.

Le conseiller expert analyse tous les instruments financiers et recherche un modèle donné.

Il trébuche sur un symbole et s'accroche ! !!

Code de l'aide, je ne mets que les étapes, l'instrument financier avec le problème et le timer :

//+------------------------------------------------------------------+ 
//|                                              TestLoadHistory.mq5 | 
//|                        Copyright 2009, MetaQuotes Software Corp. | 
//|                                              https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#property copyright "2009, MetaQuotes Software Corp." 
#property link      "https://www.mql5.com" 
#property version   "1.02" 
#property script_show_inputs 
//--- input parameters 
input string          InpLoadedSymbol="RTSCHH1";   // Symbol to be load 
input ENUM_TIMEFRAMES InpLoadedPeriod=PERIOD_H1;  // Period to be load 
input datetime        InpStartDate=D'2006.01.01'; // Start date 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart() 
  { 
   Print("Start load",InpLoadedSymbol+","+GetPeriodName(InpLoadedPeriod),"from",InpStartDate); 
//--- 
   int res=CheckLoadHistory(InpLoadedSymbol,InpLoadedPeriod,InpStartDate); 
   switch(res) 
     { 
      case -1 : Print("Unknown symbol ",InpLoadedSymbol);             break; 
      case -2 : Print("Requested bars more than max bars in chart "); break; 
      case -3 : Print("Program was stopped ");                        break; 
      case -4 : Print("Indicator shouldn't load its own data ");      break; 
      case -5 : Print("Load failed ");                                break; 
      case  0 : Print("Loaded OK ");                                  break; 
      case  1 : Print("Loaded previously ");                          break; 
      case  2 : Print("Loaded previously and built ");                break; 
      default : Print("Unknown result "); 
     } 
//--- 
   datetime first_date; 
   SeriesInfoInteger(InpLoadedSymbol,InpLoadedPeriod,SERIES_FIRSTDATE,first_date); 
   int bars=Bars(InpLoadedSymbol,InpLoadedPeriod); 
   Print("First date ",first_date," - ",bars," bars"); 
//--- 
  } 
//+------------------------------------------------------------------+ 
//|                                                                  | 
//+------------------------------------------------------------------+ 
int CheckLoadHistory(string symbol,ENUM_TIMEFRAMES period,datetime start_date) 
  { 
  Print(" === 1 === ");
   datetime first_date=0; 
   datetime times[100]; 
//--- check symbol & period 
   if(symbol==NULL || symbol=="") symbol=Symbol(); 
   if(period==PERIOD_CURRENT)     period=Period(); 
//--- check if symbol is selected in the MarketWatch 
   if(!SymbolInfoInteger(symbol,SYMBOL_SELECT)) 
     { 
      if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) return(-1); 
      SymbolSelect(symbol,true); 
     } 
     
     ulong time = GetMicrosecondCount();
     Print(" === 2 === ",first_date);
//--- check if data is present 
  bool date = SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date); 
   
   Print(" === 2.1 === ",(time - GetMicrosecondCount()));
   
   if(first_date>0 && first_date<=start_date) return(1); 
//--- don't ask for load of its own data if it is an indicator 

Print(" === 2.2 === ");
   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol) 
      return(-4); 
//--- second attempt 
Print(" === 2.3 === ");
   if(SeriesInfoInteger(symbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,first_date)) 
     { 
      //--- there is loaded data to build timeseries 
      Print(" === 2.4 === ");
      if(first_date>0) 
        { 
         //--- force timeseries build 
         CopyTime(symbol,period,first_date+PeriodSeconds(period),1,times); 
         //--- check date 
         Print(" === 2.5 === ");
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)) 
            if(first_date>0 && first_date<=start_date) return(2); 
        } 
     } 
     
     Print(" === 3 === ");
     
//--- max bars in chart from terminal options 
   int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS); 
//--- load symbol history info 
   datetime first_server_date=0; 
   while(!SeriesInfoInteger(symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopped()) 
      Sleep(5); 
//--- fix start date for loading 

Print(" === 4 === ");


   if(first_server_date>start_date) start_date=first_server_date; 
   if(first_date>0 && first_date<first_server_date) 
      Print("Warning: first server date ",first_server_date," for ",symbol, 
            " does not match to first series date ",first_date); 
//--- load data step by step 

Print(" === 5 === ");

   int fail_cnt=0; 
   while(!IsStopped()) 
     { 
      //--- wait for timeseries build 
      while(!SeriesInfoInteger(symbol,period,SERIES_SYNCHRONIZED) && !IsStopped()) 
         Sleep(5); 
      //--- ask for built bars 
      int bars=Bars(symbol,period); 
      if(bars>0) 
        { 
         if(bars>=max_bars) return(-2); 
         //--- ask for first date 
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)) 
            if(first_date>0 && first_date<=start_date) return(0); 
        } 
      //--- copying of next part forces data loading 
      int copied=CopyTime(symbol,period,bars,100,times); 
      if(copied>0) 
        { 
         //--- check for data 
         if(times[0]<=start_date)  return(0); 
         if(bars+copied>=max_bars) return(-2); 
         fail_cnt=0; 
        } 
      else 
        { 
         //--- no more than 100 failed attempts 
         fail_cnt++; 
         if(fail_cnt>=100) return(-5); 
         Sleep(10); 
        } 
     } 
     
     Print(" === 6 === ");
//--- stopped 
   return(-3); 
  } 
//+------------------------------------------------------------------+ 
//| Возвращает строкое значение периода                              | 
//+------------------------------------------------------------------+ 
string GetPeriodName(ENUM_TIMEFRAMES period) 
  { 
   if(period==PERIOD_CURRENT) period=Period(); 
//--- 
   switch(period) 
     { 
      case PERIOD_M1:  return("M1"); 
      case PERIOD_M2:  return("M2"); 
      case PERIOD_M3:  return("M3"); 
      case PERIOD_M4:  return("M4"); 
      case PERIOD_M5:  return("M5"); 
      case PERIOD_M6:  return("M6"); 
      case PERIOD_M10: return("M10"); 
      case PERIOD_M12: return("M12"); 
      case PERIOD_M15: return("M15"); 
      case PERIOD_M20: return("M20"); 
      case PERIOD_M30: return("M30"); 
      case PERIOD_H1:  return("H1"); 
      case PERIOD_H2:  return("H2"); 
      case PERIOD_H3:  return("H3"); 
      case PERIOD_H4:  return("H4"); 
      case PERIOD_H6:  return("H6"); 
      case PERIOD_H8:  return("H8"); 
      case PERIOD_H12: return("H12"); 
      case PERIOD_D1:  return("Daily"); 
      case PERIOD_W1:  return("Weekly"); 
      case PERIOD_MN1: return("Monthly"); 
     } 
//--- 
   return("unknown period"); 
  }

Résultat des travaux :

2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)   Start loadRTSCHH1,H1from2006.01.01 00:00:00
2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)    === 1 === 
2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)    === 2 === 1970.01.01 00:00:00
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.1 === 18446744073475877138    Время выполнения SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date); 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.2 === 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.3 === 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 3 === 

Je n'ai jamais attendu que le script finisse de s'exécuter.

Tant que le terminal présente de tels bugs, il est hors de question d'exécuter une bataille ! !!

On s'attendait à ce que, lorsqu'un titre fait l'objet d'un examen du marché, au moins toutes ses propriétés et la date de début de l'historique soient affichées. S'il n'y a pas d'historique sur le serveur, alors

SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)

Devrait retourner NULL instantanément, pourquoi le temps d'exécution est de 18446744073475877138 ?


Peut-être que je ne connais pas quelque chose, la fonction CopyXXX se bloque également pendant 16-29 secondes !!!

Il n'est pas normal qu'un courtier dispose de 3000 à 6000 instruments financiers.

 
Vladimir Pastushak:

Peut-être que je ne sais pas quoi, les fonctions CopyXXX se bloquent aussi pendant 16-29 secondes !!!

Il n'est pas normal qu'un courtier dispose de 3000 à 6000 instruments financiers.

Les bars sont diaboliques. Veuillez donc en parler dans un autre fil.

 
fxsaber:

Les bars sont diaboliques. Veuillez donc en parler dans un autre fil.

Peut-être savez-vous comment sélectionner par programme un instrument financier et ne pas rester bloqué pendant des heures ?

 
Vladimir Pastushak:

Peut-être savez-vous comment sélectionner par programme un instrument financier et ne pas rester bloqué pendant des heures ?

Je n'ai jamais rencontré une telle tâche.

 
Aleksey Vyazmikin:

fxsaber, et si vous définissiez une priorité faible pour les agents dans le gestionnaire de tâches et une priorité élevée pour MT5 ?

Je n'arrive pas à trouver un utilitaire qui bloquerait l'allocation d'un thread CPU spécifique à tous les programmes/secteurs d'activité, sinon il serait possible de réserver un thread pour MT5 et de bloquer automatiquement son occupation par d'autres programmes, ce qui pourrait en théorie réduire les décalages.

Réglez tous les agents sur la priorité la plus basse.

Cela ne fonctionne pas.


ZZZ Le nombre d'EAs en cours d'exécution affecte le résultat.

 

Chers développeurs, pourriez-vous me dire comment est calculé MQL_MEMORY_USED ?

J'ai fait un calcul de la mémoire qu'occupent toutes les variables EA.

MQL_MEMORY_USED = 60 MB, Virtual = 3.40 MB ( 5.7%)

Il est inférieur à 10%. Si je comprends bien, MQL_MEMORY_USED contient le cache de l'historique et le cache de CopyTicks. Mais c'est toujours beaucoup moins.

Dans le même temps, le conseiller expert parallèle consomme plusieurs fois moins. Mais le principe est le même.

En général, qu'est-ce qui est inclus dans cette valeur ?


J'ai enregistré un modèle avec Expert Advisor et je l'ai appliqué au même graphique en provoquant un rechargement. Je l'ai vu comme ça.

MQL_MEMORY_USED = 7 MB, Virtual = 3.40 MB ( 48.6%)

L'utilisation de la mémoire a changé de près d'un ordre de grandeur. Il est difficile d'expliquer ce que cela signifie pour le moment.