Caractéristiques du langage mql5, subtilités et techniques - page 238

 

Je n'aurais jamais imaginé utiliser un morceau de code généré par une machine dans le code source. Surtout dans un endroit qui est un lieu d'archivage pour la performance.


Voici le code généré.

switch (this.Flag)
{
case 0:
  return(false);
case 1:
  return(Tick.bid >= this.bid.Max);
case 2:
  return(Tick.ask <= this.ask.Min);
case 3:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min));
case 4:
  return(Tick.bid <= this.bid.Min);
case 5:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min));
case 6:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 7:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 8:
  return(Tick.ask >= this.ask.Max);
case 9:
  return((Tick.bid >= this.bid.Max) || (Tick.ask >= this.ask.Max));
case 10:
  return((Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 11:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 12:
  return((Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 13:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 14:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 15:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
}

Un script beaucoup plus concis a été écrit pour la génération. Il peut être pratique pour tester rapidement des hypothèses et éviter les erreurs humaines.

 
fxsaber #:

Je n'aurais jamais imaginé utiliser un morceau de code généré par une machine dans le code source. Surtout dans un lieu d'archivage important pour la performance.


Voici le code généré.

Un script beaucoup plus concis a été écrit pour la génération. Il peut être utile pour tester rapidement des hypothèses et éviter les erreurs humaines.

Attention, le même ChatGPT fait beaucoup d'erreurs, à la fois dans la syntaxe et dans la logique, il faut donc tout revérifier.

Mais c'est un très bon outil, qui vous aide à exprimer vos idées en code.

 
fxsaber #:

Voici le code généré.

Un script beaucoup plus concis a été écrit pour la génération. Il peut être utile pour tester rapidement des hypothèses et éviter les erreurs humaines.

Il n'y a pas assez d'informations de base : le nouveau code est-il plus rapide que l'ancien ou non ?

Dans la négative, pourquoi remplacer l'ancien code compréhensible par le nouveau code incompréhensible ?

Si oui, pourquoi le compilateur MQL n'a-t-il pas pu générer le code optimal en termes de performance tout de suite, alors qu'il a beaucoup plus de possibilités pour cela que le chat ?

 
Aleksey Vyazmikin #:

Attention, le même ChatGPT fait beaucoup d'erreurs, tant au niveau de la syntaxe que de la logique, et vous devez donc tout revérifier.

Mais c'est un très bon vendeur, qui aide à exprimer des idées en code.

Générer un script.

// Генерация switch-кода.
string GetString( const int Num )
{
  static const string Condition[] = {"(Tick.bid >= this.bid.Max)", "(Tick.ask <= this.ask.Min)",
                                     "(Tick.bid <= this.bid.Min)", "(Tick.ask >= this.ask.Max)"};
  string Str = NULL;

  for (int i = 0; i < ArraySize(Condition); i++)
    if ((bool)(Num & (1 << i)))
      Str += ((Str == NULL) ? NULL : " || ") + Condition[i];

  return(Str);
}

void OnStart()
{
  for (int i = 0; i < 16; i++)
    Print("case " + (string)i + ":\n  return(" + GetString(i) + ");");
}
 
A100 #:

Pas assez d'informations de base : le nouveau code est-il plus rapide que l'ancien ?

Le nouveau code est plus rapide.

Si oui, pourquoi le compilateur MQL n'a-t-il pas pu générer le code optimal en termes de performances en une seule fois, alors qu'il a beaucoup plus de possibilités que le chat pour le faire ?

Il s'agit d'une optimisation algorithmique, pas d'une optimisation du compilateur.

 
fxsaber #:

Le nouveau est plus rapide.

Il s'agit d'une optimisation algorithmique, et non d'une optimisation du compilateur.

De combien est-elle plus rapide ? De 1,5 % ou de 1,5 fois ? Et comme si c'était plus rapide ? Ou sur la base de mesures correctes ?

Vous ne lui avez donc pas donné un code, mais un algorithme ?

 
A100 #:

De combien ? De 1,5 % ou de 1,5 fois ? Et au toucher ou par des mesures spécifiques ?

Vous ne lui avez donc pas donné un code, mais un algorithme ?

C'est ce qu'utilise le code source de Virtual. Vous devez effectuer quatre vérifications à chaque tic-tac.

return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));


Mais dans certaines situations (commutateur 0-15), on peut se contenter de moins de vérifications : 0-4. Cela dépend du TS.


Par exemple, si le système d'information ouvre/ferme des positions uniquement avec des ordres de marché et n'utilise pas de SL/TP, vous n'avez pas besoin de faire une seule vérification.

Mais si tous les types d'ordres sont utilisés simultanément, vous devez effectuer les quatre contrôles : il n'y aura pas d'accélération.


C'est pourquoi vous devez prendre un TS spécifique et examiner les résultats des mesures le concernant. Des TS différents ont des résultats d'accélération différents.


Il était possible de classer les cas (nombre de cas) en un plus grand nombre de variantes. Franchement, je n'ai pas pu le faire.

 

Dans MQL5, il existe une fonction StringReserve, grâce à laquelle nous pouvons théoriquement réduire le nombre de réallocations de mémoire pour notre chaîne de caractères : nous avons alloué un tampon suffisamment grand en une fois et nous travaillons ensuite dans ce tampon.

Mais, comme le montre la pratique, toute affectation ultérieure d'une valeur à cette chaîne de caractères modifie la taille de son tampon (c'est-à-dire qu'il y a apparemment réallocation de mémoire).

Par conséquent, au lieu de

string str;
str.Reserve(8192);
str="test";

il est judicieux d'utiliser

string str;
str.Reserve(8192);
StringSetLength(str,0);  // или str.SetLen(0); - в документации есть, но у меня в 4073 не поддерживается
str+="test";
 
JRandomTrader #:

il est logique d'utiliser

Exactement. Ce mécanisme fonctionne très bien pour la complétion de chaînes de caractères. Par exemple, lors de la génération de rapports HTML volumineux.

 

Comment puis-je savoir si un symbole a des données, afin de ne pas le laisser dans la fenêtre [Market Watch] s'il n'en a pas ?

J'utilise une telle vérification dans une boucle :

ulong first_server_date = (ulong)SeriesInfoInteger(symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE);

if(first_server_date == NULL) {
  SymbolSelect(symbol, false);
  continue;
}

Mais après cela, je ne peux pas supprimer manuellement les symboles de la fenêtre [Market Watch], soit un par un, soit tous en même temps, pendant que l'Expert Advisor est sur le graphique: