Erreurs, bugs, questions - page 2099

 
Nikolai Semko:

Pourquoi une fonction très utile comme ChartXYToTimePrice() est-elle si coûteuse en temps d'exécution ?

J'ai écrit une fonction analogue à XYToTimePrice() et elle fonctionne beaucoup plus rapidement. Jusqu'à plusieurs centaines de fois plus rapide.

Mais il y a aussi ChartID_in avec SubWindow_out dans la fonction originale. Faites un analogue complet.

 
fxsaber:

Il y a donc aussi ChartID_in avec SubWindow_out dans l'original. Faites un analogue complet.


L'ajout de ChartID_in et SubWindow_out n'est pas du tout difficile. Mais je ne cherche pas à créer un analogue complet, j'ai juste créé cette fonction pour montrer la lenteur de ChartXYToTimePrice().

void XYToTimePrice(long chart_id,int x,int y,int& sub_window,datetime &time,double &price,int id)
  {
   static int left_bar; // номер самого левого бара на экране
   static int WidBar;
   static int Wid;
   static int Hei;
   static double y_min;
   static double y_max;
   static int PerSec=PeriodSeconds();
   static bool ChartChange=true;
   if(id==CHARTEVENT_CHART_CHANGE) { ChartChange=true; return; } 
   if(ChartChange) // если было изменение чатра после последнего вычисления
     {
      left_bar=(int)ChartGetInteger(chart_id,CHART_FIRST_VISIBLE_BAR, sub_window);        // номер самого левого бара на экране
      Wid=(int)ChartGetInteger(chart_id,CHART_WIDTH_IN_PIXELS, sub_window);               // ширина экрана в пикселях
      WidBar=(int)ChartGetInteger(chart_id,CHART_WIDTH_IN_BARS, sub_window);              // ширина экрана в барах
      Hei=(int)ChartGetInteger(chart_id,CHART_HEIGHT_IN_PIXELS, sub_window);              // высота экрана в пикселях
      y_min=ChartGetDouble(chart_id,CHART_PRICE_MIN, sub_window);                         // макс. цена на экране
      y_max=ChartGetDouble(chart_id,CHART_PRICE_MAX, sub_window);                         // мин. цена на экране
     }
   if(x>Wid || x<0 || y<0 || y>Hei) return;  // выходим если точка (x,y) за пределами экрана
   price=y_min+(Hei-y)*(y_max-y_min)/Hei;
   int NrBar=left_bar-(int)((double)x/((double)Wid/(double)WidBar)); 
   datetime T[1];
   if(NrBar>=0) CopyTime(NULL,0,NrBar,1,T);
   else { CopyTime(NULL,0,0,1,T); T[0]+=fabs(NrBar)*PerSec;}
   ChartChange=false;
   time=T[0];
  }

Mais c'est vrai, ma fonction a besoin d'un paramètre supplémentaire : l'identifiant de l'événement. Jusqu'à présent, cette fonction fonctionne plus ou moins de la même manière que l'épaisseur originale de la bougie d'un pixel, mais vous pouvez l'améliorer, si nécessaire.

 
Nikolai Semko:

L'ajout de ChartID_in et SubWindow_out n'est pas du tout difficile. Mais je ne cherche pas à créer un analogue complet, j'ai juste créé cette fonction pour montrer la lenteur de ChartXYToTimePrice().

Mais c'est vrai, ma fonction a besoin d'un paramètre supplémentaire : l'identifiant de l'événement. Et bien que cette fonction fonctionne plus ou moins de la même manière avec l'épaisseur originale de la bougie d'un pixel, vous pouvez l'améliorer, si nécessaire.


Et j'ai également remarqué une caractéristique étrange de ChartXYToTimePrice. Son temps d'exécution est directement proportionnel au nombre de barres du graphique.

Cela indique un algorithme "étrange" pour son calcul. En effet, il s'agit d'une sommation cyclique, ce qui est assez étrange pour la solution optimale d'un tel problème.

La vitesse de la fonction XYToTimePrice est la même quel que soit le nombre de barres.

Et pour être honnête, la vitesse des fonctions ChartGetInteger et ChartGetDouble est également clairement surestimée et présente des caractéristiques très étranges. Par exemple, la fonction

ChartGetDouble(0,CHART_PRICE_MAX);

est 20 à 100 fois plus rapide que la fonction

ChartGetDouble(0,CHART_PRICE_MIN);          

si MAX est après MIN :

mais si vous les intervertissez, la situation est inversée.


C'est-à-dire que cela semble logique - la même fonction, qui est calculée à plusieurs reprises, utilise des données déjà calculées et stockées provenant d'un appel de fonction précédent. Mais cela montre juste quelques calculs fous et la création de beaucoup de données intermédiaires et peut-être même de tableaux pour calculer une simple valeur double du prix maximum (ou minimum) du graphique, qui se trouve probablement déjà dans une variable et qui a juste besoin d'être prise.

Bien que je n'exclue pas que cet effet soit dû à certaines particularités du profilage et qu'il soit de nature factice. Mais la lenteur de ces fonctions n'est pas feinte.

 
Nikolai Semko:

il peut être affiné, si nécessaire.

Il est probablement encore valable de dire qu'il est correct de comparer les caractéristiques de vitesse des deux fonctions lorsque leurs résultats coïncident. Veuillez le compléter.

 
Vladimir Pastushak:
Les gars, je suis fatigué d'entrer mon nom d'utilisateur et mon mot de passe depuis www.mql5.com sur android dans mt5.
Pourquoi perdent-ils constamment leur nom d'utilisateur et leur mot de passe ?

Écrivez à Servicedesk. Veuillez joindre les journaux. Je suis désolé. Merci.

 

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

Bugs, bugs, questions

fxsaber, 2017.10.04 09:13

Cela a été écrit à maintes reprises. Pas corrigé pour une raison quelconque.

On dirait qu'ils l'ont déjà réparé. Je n'ai plus ce problème dans la build 1730.
 
Nikolai Semko:

J'ai également remarqué une caractéristique étrange de ChartXYToTimePrice. Son temps d'exécution est directement proportionnel au nombre de barres du graphique.

Cela montre la "bizarrerie" de son algorithme de calcul. En effet, il s'agit d'une sommation cyclique, ce qui est assez étrange pour la solution optimale d'un tel problème.

La vitesse de la fonction XYToTimePrice est la même quel que soit le nombre de barres.

Et pour être honnête, la vitesse des fonctions ChartGetInteger et ChartGetDouble est également clairement surestimée et présente des caractéristiques très étranges. Par exemple, la fonction

est 20 à 100 fois plus rapide que la fonction

si MAX est après MIN :

mais si vous les intervertissez, la situation est inversée.


C'est-à-dire que cela semble logique - la même fonction, qui est calculée à plusieurs reprises, utilise des données déjà calculées et stockées provenant d'un appel de fonction précédent. Mais cela montre juste quelques calculs fous et la création de beaucoup de données intermédiaires et peut-être même de tableaux pour calculer une simple valeur double du prix maximum (ou minimum) du graphique, qui se trouve probablement déjà dans une variable et qui a juste besoin d'être prise.

Bien que je n'exclue pas que cet effet soit dû à certaines particularités du profilage et qu'il soit de nature factice. Mais la lenteur de ces fonctions n'est pas feinte.

La lenteur des fonctions de demande de données graphiques réside dans la manière dont les informations sont envoyées et reçues, et non dans l'implémentation elle-même. L'implémentation de ces fonctions est elle-même primitive et ne dépend pas du nombre de barres du graphique.

Mais comme le graphique est un objet dont les informations sont réparties entre de nombreuses sources, l'ensemble du contrôle est basé sur des files de messages. Jusqu'à ce que la demande précédente soit traitée, la suivante attend.

Mais si vous avez plusieurs demandes pour le même graphique à la suite, ces demandes ultérieures sont exécutées très rapidement. Cela est dû au fait que personne n'a eu le temps de s'intercaler entre eux et la première demande.

 
Slava:

Le goulot d'étranglement des fonctions de demande de données graphiques réside dans la manière dont les informations sont envoyées et reçues, et non dans l'implémentation elle-même. L'implémentation de ces fonctions est elle-même primitive et ne dépend pas du nombre de barres du graphique.

Mais comme le graphique est un objet dont les informations sont réparties entre de nombreuses sources, l'ensemble du contrôle est basé sur des files de messages. Tant que la demande précédente n'est pas traitée, la suivante est en attente.

Mais si vous avez plusieurs demandes pour le même graphique à la suite, ces demandes ultérieures sont exécutées très rapidement. C'est parce que personne n'a eu le temps de s'intercaler entre eux et la première requête.


Ainsi soit-il. Mais le fait de s'en rendre compte ne rend pas les choses plus faciles. Slava, ne te méprends pas sur un simple programmeur. Mon exemple d'indicateur de test des messages précédents montre clairement que le temps d'exécution moyen d'une requêteChartXYToTimePrice() est de 5000 - 10000 microsecondes (à l'épaisseur d'une bougie de 1 pixel et de la fenêtre MT standard sur l'écran FullHD). Que peut-on faire dans un tel délai ?

Eh bien, par exemple, pendant ce temps, vous pouvez former une image dans le même écran de 500 cercles ombrés et les afficher à l'écran :

Même s'il y a une file d'attente, mais pourquoi cette file est-elle si longue ?
D'un côté de l'échelle, il y a une génération pixel par pixel de 500 cercles avec leur sortie sur l'écran, et de l'autre côté il y a une simple requête pour deux chiffres. Et le poids est le même.
Un simple programmeur reste assis, se gratte la tête et n'arrive pas à assembler les pièces du puzzle.

 
Nikolai Semko:

Ainsi soit-il. Mais réaliser cela ne rend pas les choses plus faciles. Slava, ne te méprends pas sur un simple programmeur. Mon exemple d'indicateur de test des messages précédents montre clairement que le temps d'exécution moyen de la requêteChartXYToTimePrice() est de 5000 - 10000 microsecondes ( pour une largeur de bougie de 1 pixel et une fenêtre standard MT sur écran FullHD). Que peut-on faire dans un tel délai ?

Eh bien, par exemple, pendant ce temps, il est possible de former une image dans le même écran de 500 cercles ombrés et de les afficher sur l'écran :

Même s'il y a une file d'attente, mais pourquoi cette file est-elle si longue ?
D'un côté de l'échelle, il s'agit de former pixel par pixel 500 cercles et de les afficher sur l'écran, et de l'autre côté, d'une simple requête à deux chiffres. Et le poids est le même.
Un simple programmeur s'assoit et se gratte la tête et n'arrive pas à assembler les puzzles.

Vous avez senti la différence entre la commande synchrone et la commande asynchrone.

 
Slava:

Vous avez perçu la différence entre une commande synchrone et une commande asynchrone.

Pourriez-vous fournir une liste des fonctions asynchrones.

Si je comprends bien, les fonctions Object et Chart (quelles autres ?) sont toutes asynchrones. Alors on ne comprend pas bien pourquoi ChartGet fonctionne plus vite que ChartXY ?

Raison: