Comportement étrange de l'opérateur WHILE - page 3

 
Faut-il utiliser WHILE alors que l'on peut utiliser FOR ?
 

quand est-ce que c'est pendant le démarrage et

quand cela se produit-il lors des arrêts ?

while (StringHighStatus == "False" && SwingHighShift <= SwingBarCount)
 
Ceci ne sera jamais vrai (L'opérande ==. - Forum MQL4)
if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift)
Par conséquent, ceci n'est jamais exécuté
StringHighStatus="True";
ce qui entraîne une boucle infinie.
while(StringHighStatus=="False" || ...
  1. Si vous aviez imprimé vos variables et vos entrées avant et à l'intérieur des instructions if, vous l'auriez compris.
  2. N'utilisez pas de chaînes de caractères ou d'entiers quand vous voulez dire booléens.
    string StringHighStatus = "False";
    while (StringHighStatus == "False" || SwingHighShift <= SwingBarCount){
       if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == ...{
          StringHighStatus = "True";
    
    bool String HighStatus = False;
    while (!String HighStatus || SwingHighShift <= SwingBarCount){
       if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == ...{
          String HighStatus = True;
    

 
WHRoeder:
Ceci ne sera jamais vrai (L'opérande ==. - Forum MQL4)
Par conséquent, ceci n'est jamais exécuté
ce qui entraîne une boucle infinie.

J'ai pensé la même chose jusqu'à ce que je le teste, de manière assez surprenante la partie if(double == double) fonctionne, cela me fait me demander si la comparaison des doubles est gérée différemment dans les nouvelles versions.

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   for(int i=0; i<100; i++)
   {if(iFractals(NULL, 0, MODE_UPPER, i) == iHigh(NULL, 0, i) && iFractals(NULL, 0, MODE_UPPER, i) > Close[0])
    Print("Fractals conditions met on bar ",i);
  }} 

EURUSD,M15 : Conditions Fractales remplies sur la barre 98
EURUSD,M15 : Conditions Fractales remplies sur la barre 95
EURUSD,M15 : Conditions Fractales remplies sur la barre 91
EURUSD,M15 : Conditions fractales rencontrées en barre 81
EURUSD,M15 : Conditions fractales rencontrées en barre 77
EURUSD,M15 : Conditions fractales rencontrées en barre 68
EURUSD,M15 : Conditions fractales rencontrées en barre 61
EURUSD,M15 : Conditions fractales rencontrées en barre 48
EURUSD,M15 : Conditions fractales rencontrées en barre 39
EURUSD,M15 : Conditions fractales rencontrées en barre 24
EURUSD,M15 : Conditions de fractales rencontrées en barre 19
EURUSD,M15 : Conditions fractales rencontrées en barre 12
EURUSD,M15 : Conditions fractales rencontrées en barre 4

 
lord_hiro:

Merci GumRai pour votre patience.

Peut-être que je me trompe et que j'ai la tête dure mais je n'arrive pas à comprendre la logique...

Si le premier IF transforme, comme vous le suggérez, la chaîne de caractères en "true" à disons SwinghHighShift=10 alors le compteur n'augmente pas dans ce cycle ; après cela le contrôle revient au WHILE : le cycle devrait se terminer à ce point car le WHILE contient un OR logique et une de ses conditions est satisfaite.

Inversement, si la variable reste fausse, le compteur devrait atteindre sa valeur maximale et vous avez à nouveau la condition de sortie.

Je pense que votre considération serait vraie avec un opérateur AND.

En suivant votre interprétation, je pourrais sauter l'opérateur OR à l'intérieur du WHILE ; je pourrais simplement mettre la première condition IF sur la chaîne de caractères : si elle devient "true", le break mettra fin au WHILE, sinon le compteur continuera jusqu'à sa valeur maximale.

Le code se transformera en :


Mais cela reste une solution de rechange et, malheureusement, cela n'explique pas (pour moi) pourquoi le WHILE ne s'occupe pas du OU.

Il n'y a rien de mal avec le WHILE ou le OU logique, vous avez deux conditions dans votre WHILE, LES DEUX doivent être brisées avant que le WHILE puisse sortir.

C'est pourquoi il se bloque

  • Le code entre dans la boucle WHILE. Les deux conditions sont vraies au départ.
  • Le code parcourt la boucle WHILE en incrémentant SwingHighShift++ jusqu'à ce qu'une barre soit trouvée avec des fractales pour satisfaire les conditions IF.
  • Tôt ou tard, le code entre dans les opérateurs IF lorsque les fractales remplissent les conditions.
  • StringHighStatus est changé en false pour que la première condition WHILE soit rompue.
  • SwingHighShift++ ; n'est PAS incrémenté car il se trouve dans la partie ELSE de l'opérateur IF (la condition IF a été remplie, donc ELSE est ignoré).
  • La deuxième condition WHILE est toujours vraie et le code recommence à tourner, toujours sur la même barre que la dernière fois.
  • la même fractale remplit à nouveau les conditions IF comme la dernière fois.
  • Le code est maintenant bloqué pour toujours en boucle sur cette barre avec la fractale qui remplit les conditions IF parce que SwingHighShift++ dans la partie ELSE n'est pas incrémenté lorsque les conditions IF sont vraies.

Il n'y a qu'une chance infime que la boucle while puisse sortir et c'est lorsque la condition IF n'est pas remplie pour l'ensemble des 100 barres (SwingBarCount), de sorte que la deuxième condition WHILE est rompue avant la première. Ensuite, les fractales satisfont à la condition IF et le code permettant de rompre la première condition WHILE (modifier StringHighStatus) est exécuté.

Vous devez soit retirer SwingHighShift++ ; du ELSE et le placer seul dans la boucle while après l'opérateur IF, de sorte que, indépendamment de ce qui se passe avec les conditions IF, il continue à s'incrémenter pour que la boucle puisse passer à la barre suivante, soit utiliser break après le bloc de code de dessin de l'objet pour sortir du while une fois l'objet dessiné.

Vous devez également donner à votre objet un moyen de créer différents noms pour lui-même, sinon il ne sera dessiné qu'une seule fois. (sauf si vous voulez qu'il ne soit dessiné qu'une seule fois).

 
J'ai relu vos messages dans ce fil et je vois d'où vient votre confusion. Vous pensez la logique de WHILE et OR à l'envers. Le OU n'a pas pour but d'arrêter le WHILE. Il s'agit de le maintenir lorsque l'une ou l'autre des conditions est valide... C'est comme ça, vous avez deux lumières allumées. Votre instruction est la suivante : Tant que la lumière 1 OU la lumière 2 est allumée, continuez à faire quelque chose. Il est évident que les deux lumières doivent être éteintes avant que vous n'arrêtiez, pas seulement l'une d'entre elles.
 
SDC:

J'ai pensé la même chose jusqu'à ce que je le teste, de manière assez surprenante la partie if(double == double) fonctionne, cela me fait me demander si la comparaison des doubles est gérée différemment dans les nouvelles versions.

EURUSD,M15 : Conditions Fractales remplies sur la barre 98
EURUSD,M15 : Conditions Fractales remplies sur la barre 95
EURUSD,M15 : Conditions Fractales remplies sur la barre 91
EURUSD,M15 : Conditions Fractales remplies sur la barre 81
EURUSD,M15 : Conditions Fractales remplies sur la barre 77
EURUSD,M15 : Conditions Fractales remplies sur la barre 68
EURUSD,M15 : Conditions fractales rencontrées à la barre 61
EURUSD,M15 : Conditions fractales rencontrées à la barre 48
EURUSD,M15 : Conditions fractales rencontrées à la barre 39
EURUSD,M15 : Conditions fractales rencontrées à la barre 24
EURUSD,M15 : Conditions fractales rencontrées à la barre 19
EURUSD,M15 : Conditions fractales rencontrées à la barre 12
EURUSD,M15 : Conditions fractales rencontrées à la barre 4


La raison pour laquelle cela fonctionne est que le code compare effectivement la même valeur.

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift) )

Le tampon fractal aura une valeur vide ou prendra sa valeur à partir du haut de la barre concernée.

Le code est effectivement

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE && iHigh(NULL,0,SwingHighShift==iHigh(NULL,0,SwingHighShift) 

Je ne vois pas pourquoi il ne pourrait pas être remplacé par

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE)
 
GumRai:

Je ne vois aucune raison pour qu'il ne puisse pas être remplacé par

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE)
Oui, je pense que c'est une meilleure façon de faire.
 
SDC:
J'ai relu vos messages dans ce fil et je vois d'où vient votre confusion. Vous pensez que la logique de WHILE et OR est inversée. Le OU n'a pas pour but d'arrêter le WHILE. Il s'agit de le maintenir lorsque l'une ou l'autre des conditions est valide... C'est comme ça, vous avez deux lumières allumées. Votre instruction est la suivante : Tant que la lumière 1 OU la lumière 2 est allumée, continuez à faire quelque chose. Il est évident que les deux lumières doivent être éteintes avant que vous n'arrêtiez, pas seulement l'une d'entre elles.


Et c'est tout !

Honte à moi... :-)

De plus, ce n'est pas la première fois que j'utilise WHILE mais j'ai commencé à penser à l'envers et je ne suis jamais sorti de MA PROPRE boucle :-/

Et donc la suggestion de deVries de remplacer || par && s'avère juste.

Beaucoup d'autres choses à prendre en compte sont ressorties de ce sujet, comme par exemple le fonctionnement de IF( == ).

Merci à tous pour votre patience et le temps que vous avez passé à me faire comprendre.

 

J'aurais dû le faire de cette façon, avec un break, pour interrompre la boucle while, est-ce correct ?

  int counter=0, MaxCount = 10000;
  while( true )
     {
      Print("Counter ", counter);
      counter++;
      if( counter == MaxCount ) break;
      }