Erreurs, bugs, questions - page 1999

 
Stanislav Korotky:

Je ne dis rien à propos d'un tableau dynamique personnalisé - la règle s'applique vraiment là : celui qui l'a alloué est responsable de le nettoyer correctement.

N'insulte pas les tableaux.

#property strict

void OnStart()
{
  uchar Array[];
  
  const int Size = ArrayResize(Array, 10000);
  
  bool Res = false;
  
  for (int i = 0; (i < Size) && (!Res); i++)
    Res = Array[i];
    
  Print(Res);
}

Dans MT4, il retournera toujours false, car sans déchets - tous les zéros. Dans MT5, c'est vrai.

Par conséquent, le même code dans le testeur MT4 donnera toujours des résultats identiques d'une exécution à l'autre. Dans un testeur MT5, ce ne sera pas le cas.

 
fxsaber:

Dans MT4, il retournera toujours false, parce que sans déchets, il n'y a que des zéros. Dans MT5, c'est vrai.

Est-ce un test pour vérifier que MT4 remplit le tableau avec des zéros ? Ensuite, nous devons garder à l'esprit que si ArrayResize utilise un troisième paramètre avec réserve, alors les réallocations ultérieures dans la réserve n'initialiseront rien. Il y aura des déchets. Je recommande de faire une initialisation explicite, afin de ne pas être accidentellement surpris plus tard, comme dans l'exemple d'optimisation qui a suscité cette discussion.

Pour ceux qui s'inquiètent du freinage à cause de l'initialisation, j'ose dire qu'il y a généralement beaucoup d'autres endroits et techniques où l'efficacité peut être améliorée dans une bien plus grande mesure.

 
Stanislav Korotky:

Est-ce un test pour que MT4 remplisse le tableau avec des zéros ? Ensuite, il faut garder à l'esprit que si ArrayResize utilise un troisième paramètre avec une réserve, alors les réallocations ultérieures dans la réserve n'initialiseront rien. Il y aura des déchets.

Il n'y aura pas de déchets.

Je recommande de procéder à une initialisation explicite afin de ne pas être accidentellement surpris par la suite, comme dans l'exemple d'optimisation qui a suscité cette discussion.

Cela ne sauvera pas

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

Bugs, bugs, questions

fxsaber, 2017.09.12 11:18

Même si j'écrivais parfaitement (sans faire de fautes - ce qui n'est pas le cas), il est normal de prendre la bibliothèque de quelqu'un d'autre (parfois sans code source - sur le Marché) et de l'utiliser, en espérant qu'elle soit écrite de manière compétente. Et il n'y a aucune assurance qu'après cela, vous obtiendrez des résultats différents dans le testeur. Et trouver la véritable cause sera TRÈS difficile. Et le réparer est parfois impossible.

L'objectif est que, d'une exécution à l'autre, le résultat soit reproductible - identique, même en cas d'erreur.

 
fxsaber:

Il n'y aura pas de déchets.



Devrions-nous alors corriger la documentation ?

Initialiser un tableau avec l'expressionArrayInitialize(tableau, init_val) ne signifie pas initialiser les éléments de la réserve allouée pour ce tableau avec la même valeur. Lorsque lafonction ArrayResize() augmente ensuite la taille du tableau dans la réserve actuelle, les éléments dont les valeurs ne sont pas définies et le plus souvent ne sont pas égales àinit_val sont ajoutés à la fin du tableau.

 
Stanislav Korotky:

Devons-nous alors corriger la documentation ?

Initialiser un tableau avec l'expressionArrayInitialize(array, init_val) ne signifie pas que les éléments de la réserve, allouée pour ce tableau, sont initialisés avec la même valeur. LorsqueArrayResize() augmente ensuite la taille du tableau dans la réserve actuelle, les éléments sont ajoutés à la fin du tableau dont les valeurs ne sont pas définies et, le plus souvent, ne sont pas égales àinit_val.

Vous ne le savez pas, parce que la documentation MT4 ne mentionne rien de tel.


Il est effrayant de penser qu'une bibliothèque mathématique (Include\Math -code source de 7 Mo) n'a pas été initialisée à un ou deux endroits ! Et comment résoudre cette erreur, qui donne des exécutions uniques différentes dans le testeur MT5, et la même dans MT4 ?

 
Stanislav Korotky:

Je dois être en retard sur mon temps. Il me semble que le tampon de l'indicateur a toujours une longueur égale au nombre de barres. Et le refus de son initialisation dans MT5 conduit à l'affichage de déchets à l'écran. Il s'avère que l'initialisation explicite est obligatoire. Et il n'est pas clair pourquoi il est simplement transféré du noyau (comme il l'était dans MT4) au programmeur MQL. Je n'ai pas vu d'arguments concrets pour dire qu'il est possible d'accélérer sans initialisation et d'obtenir quand même l'affichage dégoûtant.

Je ne dis rien à propos d'un tableau dynamique personnalisé - il y a vraiment une règle : celui qui l'a alloué, est responsable de son nettoyage correct. ArrayInitialize est utile dans de nombreux cas. Ce n'est pas une question de vitesse, mais de justesse du programme. Priorité : rapide et/ou correcte. En général, certains contrôles d'exactitude et de préparation des données nécessitent un temps supplémentaire (bien que minime), mais vous ne pouvez pas vous en passer - des miracles se produisent.

Vous n'avez pas fait attention à la phrase

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

Bugs, bugs, questions

Alexey Viktorov, 2017.09.12 10:50

Prenons l'exemple du tableau tampon de l'indicateur : lors de l'initialisation de l'indicateur, le tampon a une longueur nulle. Qu'y a-t-il à initialiser avec des zéros ? Lorsqu'un autre index est ajouté, il est forcé d'être mis à zéro et ensuite rempli avec une valeur quelconque ? À quoi sert cette mise à zéro ou ce remplissage avec EMPTY_VALUE? Et s'il y a un besoin d'assigner PLOT_EMPTY_VALUE et non 0 ou EMPTY_VALUE ou de forcer un, mais nous avons besoin d'un autre... Peu importe comment on le découpe, on finit par perdre son temps...

Et un tableau personnalisé... Le tableau est déclaré pour des données différentes de zéro et EMPTY_VALUE. Alors pourquoi devrait-il être initialisé de force avec quelque chose ?

Il s'avère donc que cela affecte les performances dans la plupart des cas.



Et cela n'a aucun sens de le faire dans OnCalculate. Pourquoi aurions-nous besoin d'initialiser le tableau avec quelque chose, puis de le remplir avec des valeurs issues de la formule ? Lorsque vous ajoutez une barre, respectivement une cellule de tableau, quel est l'intérêt de la remplir avec quelque chose, puis immédiatement avec une valeur de la formule ou une valeur vide ?

 
Alexey Viktorov:

Et c'est déjà dans OnCalculate que ça n'a aucun sens. Pourquoi aurions-nous besoin d'initialiser le tableau avec quelque chose, puis de le remplir immédiatement avec des valeurs issues de la formule ? Lorsque vous ajoutez une barre, et respectivement une cellule de tableau, quel est l'intérêt de la remplir avec quelque chose et ensuite immédiatement avec une valeur de la formule ou une valeur vide ?

Seuls les nouveaux éléments du tableau sont initialisés. Et le but est toujours le même : des résultats identiques d'une exécution à l'autre, même s'il y a une erreur dans le code (souvent pas la vôtre). J'ai donné un exemple avec la bibliothèque mathématique ci-dessus.

Les déchets sont mauvais.

 
fxsaber:

Ne le faites pas, car il n'y en a tout simplement pas dans la documentation MT4.

Où est-ce que je l'ai trouvé alors ? Allez-y.

ArrayInitialize - Операции с массивами - Справочник MQL4
ArrayInitialize - Операции с массивами - Справочник MQL4
  • docs.mql4.com
ArrayInitialize - Операции с массивами - Справочник MQL4
 
Stanislav Korotky:

D'où est-ce que je sors ça alors ? Allez-y.

Donc ce n'est pas à propos de ArrayResize, c'est à propos de ArrayInitialize. ArrayResize garantit des zéros dans MT4.


Par souci d'intérêt, j'ai regardé dans toutes mes sources pour MT5 combien de fois j'utilise ArrayInitialize. Juste quelques fois. Il semble que ce soit moins d'un pourcentage de toutes les matrices dynamiques. Et là où je l'ai utilisé, j'ai dû utiliser des nuls exprès, donc j'ai utilisé une notation plus courte au lieu de for.

 
Alexey Viktorov:

Et cela n'a aucun sens de le faire déjà dans OnCalculate. Il n'y a aucune raison d'initialiser le tableau avec quelque chose, puis de le remplir avec des valeurs issues de la formule ? Lorsque vous ajoutez une barre, et respectivement une cellule de tableau, quel est l'intérêt de la remplir avec quelque chose et ensuite immédiatement avec une valeur de la formule ou une valeur vide ?

C'est si la formule est appliquée sur toutes les barres. Et si ça ne s'applique qu'au dernier ? J'ai, par exemple, beaucoup d'indices qui me permettent de définir le nombre de barres à calculer, car les calculs peuvent être lourds. Une initialisation est nécessaire.

En général, si vous ne voulez pas le faire, ne le faites pas. Je ne discute plus de ce sujet. ;-)

Raison: