Mon approche. Le noyau est le moteur. - page 124

 
Andrey Barinov:

Parce qu'au lieu de OrderOpenPrice mettez OrderOpenTime()

Bien. Je me suis mélangé. :)

 
Реter Konow:

Je dois admettre que j'ai été un peu surpris par les résultats du test.

C'est pourquoi je voulais que vous fassiez tout vous-même, et non pas que vous donniez des solutions toutes faites qui se heurteraient à un mur.
Tu sais, Peter, il existe également une fonctionnalité telle que le pointeur vers une fonction, grâce à laquelle tu peux organiser les appels de fonction en prenant simplement ces pointeurs dans un tableau de tels pointeurs. Je pense que cela vous serait très utile dans votre tâche. Le seul problème, c'est que vous devez à nouveau vous occuper des classes.
 
Nikolai Semko:
C'est pourquoi j'ai voulu que vous fassiez tout vous-même, et non que vous donniez des solutions toutes faites, qui sont comme des pois contre le mur.
Et tu sais, Peter, il existe aussi une chose telle qu'un pointeur vers une fonction, grâce à laquelle tu peux organiser les appels de fonction en prenant simplement ces pointeurs dans un tableau de tels pointeurs. Je pense que cela serait très utile pour votre problème. Mais le problème, c'est que vous devez à nouveau vous occuper des classes.

J'ai entendu parler des pointeurs vers les fonctions. Mais j'ai très peu de fonctions. C'est pour cette raison que je n'ai pas d'espace et que je dois utiliser la POO.

J'ai un concept de développement différent. Je pense que le fonctionnement de blocs multifonctions holistiques est plus efficace que celui de grands complexes de petites fonctions.

Plus prometteur, du point de vue du développement des mécanismes.

C'est mon opinion...

J'ai plusieurs gros blocs. Pour appliquer la POO, il faut les décomposer en petites fonctions, les organiser en classes, et ensuite, utiliser des pointeurs et d'autres choses.

Mais je ne pourrai pas le faire. Tout simplement parce que je pense différemment.

Le concept de la POO ne coïncide pas avec les particularités de ma façon de penser, et je ne peux pas m'y étendre. C'est la raison.

 
Nikolai Semko:

Notez, Nikolaï, qu'en matière de développement programmatique, je n'ai aucun problème. Tout se développe très rapidement.

En même temps, les mécanismes fonctionnent bien.

J'ai maintenant maîtrisé les unions, et je vois leur application dans une tâche particulière, - l'écriture de chaînes de caractères dans une ressource.

Je vais essayer de vérifier la vitesse et la charge CPU dans l'EA de test et poster le résultat.

Si c'est bon, je vais reconstruire la communication entre le moteur et l'EA, en la faisant sur les ressources.

 

Afin d'utiliser les ressources pour transmettre des chaînes de longueur indéfinie, ces chaînes doivent être écrites dans un tableau de caractères.

Cependant, il semble que leur taille ne soit déclarée qu'à l'intérieur de l'union et qu'elle ne change pas par la suite.

J'ai essayé de redimensionner le tableau de chars de l'union, par le biais de ArrayResize, mais il n'y a aucun effet.

Il semble que la taille du tableau de caractères doive être définie au préalable. Et il devrait être de taille maximale.


Voici le code :

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[4];
   uint    Uint[1];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(1000);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand();
   if(q > 10000)q = 10000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Меняем размер массива из Char[] юниона. 
   //-------------------------------------------------------
   ArrayResize(u.Char,StrSize);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   //StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //
   //-------------------------------------------------------
   Print("StrSize  ",StrSize," Размер u.Char  ",ArraySize(u.Char));
  }
//+------------------------------------------------------------------+
 

Il est maintenant clair que la taille du tableau dechars dans l' union doit être connue à l'avance. Parce queArrayResize(u.Char,StrSize) ne le change pas.

Nous devons donc définir la taille du tableau comme étant égale à la longueur de la chaîne maximale...

 

Bonne nouvelle. Tout fonctionne bien.

La chaîne est écrite dans la ressource et lue par un autre EA sur un autre graphique.

Il n'y a pas de charge sur le processeur. La charge n'est causée que par l'appel de l'Alert qui imprime la chaîne de caractères.

Voici le code des Expert Advisors :

1. Expert Advisor forme la chaîne et l'écrit dans une ressource.

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(16);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand(),width,height;
   if(q > 1000)q = 1000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //Cохраняем строку переведенную в байты в ресурсе.
   //-------------------------------------------------------
   if(!ResourceCreate("::Resource",u.Uint,8000,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //-------------------------------------------------------
  }
//+------------------------------------------------------------------+
 

Un conseiller qui lit une ligne d'une ressource sur un autre graphique :

//+------------------------------------------------------------------+
//|                                              Resource reader.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(16); 
   
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"\\Experts\\TEST_2.ex4::Resource"))Print("Resource is not connected!");
   else Print("Resource connected!");
//---
   return(INIT_SUCCEEDED);
  }


//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   Char_Uint u;   
   uint width,height;
   //string Message; 
   //-----------------------------
   if(!ResourceReadImage("\\Experts\\TEST_2.ex4::Resource",u.Uint,width,height))Print("Failed to read resource!  ",GetLastError());
   //-----------------------------
   string String = CharArrayToString(u.Char);
   //-----------------------------
   Alert("  String  ",String);
   //-----------------------------
  }
//+------------------------------------------------------------------+


Utilisera les ressources pour la communication. Le seul inconvénient est que vous devez définir la taille maximale du tableau de caractères dans l'union. Mais il n'est pas nécessaire de penser à la taille de la chaîne et au nombre d'objets MT.

Cette méthode est plus lente que la méthode de liaison MT-objet, mais c'est bien.

 
Реter Konow:

Votre théorie est intéressante, bien qu'elle ne corresponde pas tout à fait aux résultats de mes expériences, que je vais maintenant poster ci-dessous.

Comme le montre le test, c'est l'initialisation de la matrice de pixels qui sollicite le plus le CPU.

Découvrez l'EA de test ci-dessous.

Relisez la tâche :

Vasiliy Sokolov:

Peter, voici la mission. Créez un panneau montrant les ouvertures d'ordres en cours dans MT4. Il n'est pas nécessaire de faire une copie complète du panneau système, il suffit de créer un tableau simple avec les propriétés de base des ordres ouverts : prix ouvert, direction, profit. Le reste dépend de vous. L'essentiel est que lorsqu'une commande est clôturée, son indication dans votre tableau disparaît également. Et vice versa, elle apparaîtrait dans ce tableau lorsqu'une nouvelle commande est ouverte.

Vous pouvez voir ici les deux opérations nécessaires de redécoupage lorsque le tableau change à l'écran : 1. lors de la fermeture d'une transaction et 2. lors de l'ouverture d'une transaction. Pourquoi redessiner les pixels le reste du temps ?

Est-ce que vous résolvez un autre problème ?

 
Vladimir:

Relisez le problème :

Vasiliy Sokolov:

Nous voyons ici deux opérations de redécoupage nécessaires lorsque le tableau change à l'écran : 1. lors de la fermeture d'une transaction et 2. lors de l'ouverture d'une transaction. Pourquoi redessiner les pixels à d'autres moments ?

Est-ce que vous résolvez un autre problème ?

Eh bien, ils sont redessinés exactement comme vous l'avez dit.

La charge sur le processeur apparaît pendant l'animation:

Il y a une réinitialisation constante des valeurs dans le tableau des pixels. Toutes les 16 millisecondes. Cela charge le processeur jusqu'à 40%.

J'essayais de comprendre ce qu'est exactement la charge. Je pensais que c'était sauvegarder une ressource ou la lire. Il s'est avéré que c'était la réinitialisation du tableau dans la boucle de dessin.


Il s'est également avéré qu'un appel constant de ObjectSetInteger(0, "MT object",OBJPROP_SELECTED,1) ; (toutes les 16 ms) charge également le processeur. D'environ 10 %.

J'utilise cet appel pour dire à un autre EA de lire la ressource avec les données d'animation.

Au total, il obtient +~50% de charge CPU pendant l'animation.