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

 
Maxim Kuznetsov:

Les seules et uniques GlobalVariables et fichiers pour l'échange de données entre EAs, indicateurs et scripts sont les suivants

Les 4 points ci-dessus sont des "trucs" locaux pour le manque de poisson. Les 4 points ci-dessus utilisent des mécanismes qui ne sont pas conçus pour échanger des données arbitraires, et encore moins des tableaux de données.

On pourrait croire que GlobalVariables a été conçu spécialement pour la messagerie. C'est une chose stupide à dire. En fait, il s'agit du même hack que pour n'importe quel autre article.

 
fxsaber:


...En gros,un cycle complet d'écriture/lecture d'une ressource se déroule à un rythme de 4 millions de ticks par seconde.

La lecture/écriture de la ressource est très rapide. Mais dans quelle mesure cela convient-il à une telle transmission ?

1. Ligne A. Événement de chronométrage. Recueillir toutes les valeurs de paramètres qui ont été modifiées lors de l'événement et les traduire en une chaîne de caractères. Traduit la chaîne en Char, écrit dans la ressource. Envoyez un message au côté B.

2. Partie B. L'événement OnChartEvent(), reçoit un signal de message, ouvre la ressource, la lit, remplit le noyau de paramètres avec de nouvelles valeurs, redessine les éléments requis.

Et si cet événement est exécuté en continu, à la fréquence de la minuterie ?

La question est de savoir comment utiliser au mieux les ressources pour cela, s'il existe d'autres options.

//---------------------------------------------------------------------------------------------------------------------

  • L'option EventChartCustom() présente deux inconvénients.

  1. Le colis devient dans la file d'attente des événements.
  2. Le colis ne peut pas comporter plus de 127 caractères. Par conséquent, un message de 1000 caractères doit être divisé puis réassemblé. Et chaque partie du message sera dans la file d'attente des événements.
  • La variante avec passage par les objets du graphe, nécessite de diviser le message en paquets de 64 caractères, de les écrire dans des descriptions d'objets puis de les réassembler. Il est intéressant de constater que cette variante est la plus rapide, mais que plus la longueur de la chaîne augmente, plus sa vitesse diminue. Autrement dit, chaque appel à ObjectSetString() prend 3 microsecondes. Mais si une chaîne de 1000 caractères, nous devons la diviser en 64 caractères, ce qui signifie que nous devons appeler ObjectSetString() environ 8 fois. 8*3 = 24 ms. Il faut ensuite le même temps pour assembler la chaîne. C'est pourquoi, si la chaîne de caractères comportait 10 000 caractères, cette méthode approcherait certainement la vitesse de la méthode fonctionnant par ressources. (Je parle du temps de sauvegarde et de lecture de la ressource + transfert des chaînes de caractères en uint et retour).
La variante de ressource reste non testée jusqu'au bout. Je le testerai aujourd'hui dans le testeur et il sera enfin clair s'il peut être universel.
 
Реter Konow:

Et si cet événement est exécuté en continu, à la fréquence de la minuterie ?

La question est de savoir comment utiliser au mieux les ressources pour cela, s'il existe d'autres options.

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

Échange de données entre programmes

fxsaber, 2018.11.21 13:12

J'ai probablement beaucoup de temps pour décrire de manière aussi détaillée les différentes possibilités d'interaction. Malheureusement, je ne possède pas une telle ressource.

Voici un article sur le sujet où une interaction complète a lieu. Chaque bâtiment est construit à partir de briques et pour des tâches spécifiques. Toutes les briques possibles sont indiquées au début du fil. Le reste est du ressort du constructeur.

 
fxsaber:

L'article ne teste pas la communication de deux programmes via des ressources, dont l'une se trouve dans le testeur.

 

Quel est le problème avec le syndicat ? S'il vous plaît, un exemple :

union UZ{
   double d;
   int i[2];
};

void OnStart(){

   UZ u1;
   UZ u2;
   
   u1.d=12345.678;
   
   ArrayCopy(u2.i,u1.i);
   
   Alert(u2.d);

}
 
Реter Konow:

L'article ne teste pas la communication de deux programmes via des ressources, dont l'une se trouve dans le testeur.

Lisez la phrase sur les briques.

 
fxsaber:

...

Cet article tire un canon sur des moineaux. Comme de nombreux articles. Je préfère résoudre le problème moi-même plutôt que de comprendre l'article.

Tout peut être fait dix fois plus facilement et plus clairement. Mais l'article est beaucoup plus facile...


Et à quoi sert l'article si vous dites que vous n'avez pas vérifié le fonctionnement des ressources dans le testeur ?

 
Реter Konow:

Et à quoi sert cet article si vous dites que vous n'avez pas vérifié le fonctionnement des ressources dans le testeur ?

Je me suis retiré de la discussion.

 

Il y a quelque chose qui cloche avec cette solution. Peut-être que je fais quelque chose de mal.

Pour faire court :

La fonction StringToCharArray() prend UNIQUEMENT un tableau de caractères.

La fonction ResourceCreate() accepte UNIQUEMENT un tableau d'uint.

Par conséquent, il est nécessaire de réécrire de façon intermédiaire le contenu du tableau char (rempli avec la chaîne convertie), dans le tableau uint.

 
//+------------------------------------------------------------------+
//|                                                    Tester EA.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //----------------------------------------------
   ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   uchar Arr[];
   uint  Data[];
   //---------------------------
   string price = (string)Bid;
   //---------------------------
   int width = StringToCharArray(price,Arr);
   //---------------------------
   ArrayResize(Data,width);
   //---------------------------
   ArrayCopy(Arr,Data);
   //---------------------------
   if(!ResourceCreate("::Resource",Data,width,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //---------------------------
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+

Indicateur sur un graphique normal :

//+------------------------------------------------------------------+
//|                                              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
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(25); 
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   uint Data[50],width,height;
   //-----------------------------
   if(!ResourceReadImage("::Resource",Data,width,height))Print("Failed to read resource!");
   else Print("Resource is readable!");
   //-----------------------------
   
  }
//+------------------------------------------------------------------+
Raison: