Ce que rapportent les fonctions Lowest et Highest

 
Chers développeurs Metatrader !

Que retournent les fonctions Lowest et Highest ?
Pourquoi est-ce que je pose une telle question ? La description de ces fonctions prête à confusion. En analysant pourquoi ZigZag inclus dans MetaTrader ne fonctionne pas correctement, j'ai été confronté au fait qu'il n'est pas clair ce que les fonctions ci-dessus retournent. Ou peut-être qu'à cause de la description confuse, ils ne sont pas appliqués correctement ? J'ai décrit ce problème sur ce forum page 77 dans la section "Stratégie de trading basée sur la théorie des vagues d'Elliot". J'essaie de comprendre, peut-être que l'algorithme ZigZag est mauvais. Mais tout dépend du fonctionnement de ces fonctions.

J'ai également observé des problèmes avec ces fonctions dans d'autres indicateurs. Mais pour le moment, c'est en ZigZag.

Veuillez clarifier.
 
Ils renvoient le numéro de la barre qui est la plus haute et la plus basse sur N barres à partir de la barre actuelle jusqu'à la fin de l'historique. Dans ce cas, si deux valeurs sont égales (deux barres sont des extrêmes sur cet échantillon), le numéro de la barre qui est arrivée plus tôt (est plus ancienne) est toujours renvoyé.

L'algorithme Zigzag (inclus dans MT4 en standard) ne prend pas en compte la situation où une barre peut être à la fois un maximum et un minimum en même temps (une barre externe).
 
Rosh, c'est compréhensible. Essayez d'insérer les lignes que j'ai données dans le fil de discussion sur l'analyse des ondes dans le texte en zigzag. Et voyez ce que vous obtenez. Et vous obtenez des déchets. C'est pourquoi la question s'est posée.

Tout est clair avec la théorie jusqu'à ce qu'elle commence à diverger de la pratique. Si des erreurs se produisent, vous devez aller jusqu'au bout. Et découvrez d'où viennent les erreurs.
 
Rosh, c'est compréhensible. Essayez d'insérer les lignes que j'ai données dans le fil de discussion sur l'analyse des ondes dans le texte en zigzag. Et voyez ce que vous obtenez. Et vous obtenez des déchets. C'est pourquoi je vous ai posé cette question. <br / translate="no">


J'ai regardé cette page sur onyx et ouvert le Zigzag standard pour comparer. Les codes sont différents, vous devez trouver votre variante de Zigzag, la démonter minutieusement et seulement alors vous pourrez dire quelque chose. C'est pourquoi je ne peux pas répondre.

Mais oui, il y a quelques différences dans l'enregistrement des valeurs dans le code, qui est affiché sur votre page, mais peut-être que ça devrait être comme ça, c'est difficile à dire. J'ai fait de tels indicateurs avec des valeurs de crawl, ça ressemble à un canal, mais au moins ça ne ment pas sur l'histoire.
 
Rosh, voici le code en zigzag provenant de codebase.mql.com

//+------------------------------------------------------------------+
//| Moyenne mobile personnalisée.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp.
//| https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#lien de propriété "https://www.metaquotes.net/

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- paramètres de l'indicateur
extern intDepth=12 ;
extern inttern ExtDeviation=5 ;
externe inttern ExtBackstep=3 ;
//---- tampons indicateurs
double ExtMapBuffer[] ;
double ExtMapBuffer2[] ;

//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'indicateur personnalisé |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(2) ;
//---- paramètres de dessin
SetIndexStyle(0,DRAW_SECTION) ;
//---- mise en correspondance des tampons indicateurs
SetIndexBuffer(0,ExtMapBuffer) ;
SetIndexBuffer(1,ExtMapBuffer2) ;
SetIndexEmptyValue(0,0.0) ;
//---- indicateur nom court
IndicatorShortName("ZigZag("+ExtDepth+", "+ExtDeviation+", "+ExtBackstep+")") ;
//---- initialisation faite
retour(0) ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
int shift,back,lasthighpos,lastlowpos ;
double val,res ;
double curlow, curhigh, lasthigh, lastlow ;

for(shift=Bars-ExtDepth ; shift>=0 ; shift--)
{
val=Low[Lowest(NULL,0,MODE_LOW,ExtDepth,shift)] ;
si(val==lastlow) val=0.0 ;
sinon
{
lastlow=val ;
si((Low[shift]-val)>(ExtDeviation*Point)) val=0.0 ;
sinon
{
for(back=1 ; back<=ExtBackstep ; back++)
{
res=ExtMapBuffer [shift+back] ;
si((res!=0)&&(res>val)) ExtMapBuffer[shift+back]=0.0 ;
}
}
}
****** ExtMapBuffer[shift]=val;
//--- haut
val=High[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)] ;
si(val==lasthigh) val=0.0 ;
sinon
{
lasthigh=val ;
si((val-High[shift])>(ExtDeviation*Point)) val=0.0 ;
sinon
{
for(back=1 ; back<=ExtBackstep ; back++)
{
res=ExtMapBuffer2 [shift+back] ;
si((res!=0)&&(res<val)) ExtMapBuffer2[shift+back]=0.0 ;
}
}
}
***** ExtMapBuffer2[shift]=val;
}


============================

Les astérisques indiquent les endroits que j'ai cités à la page 77 de ma branche sur l'analyse des ondes. En quoi ce code est-il différent de celui que j'ai cité ? Il s'agit d'un code standard.

Maintenant, je cite vos mots du deuxième message de ce fil de discussion

Rosh 18.10.06 10:14

Il renvoie le numéro de la barre, qui est la plus haute et la plus basse dans les N barres à partir de la barre actuelle dans la profondeur de l'historique. Dans ce cas, si deux valeurs sont égales (deux barres sont extrema sur cet échantillon), elles renvoient toujours le numéro de la barre qui est arrivée en premier (est la plus ancienne).

L'algorithme Zigzag (inclus dans MT4 en standard) ne prend pas en compte la situation où une barre peut être un maximum et un minimum en même temps (barre externe).
======================
Il y a une ligne dans le code : val=High[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)] ;
Les crochets contiennent le numéro de la barre... votre réponse dit ce qu'est ce numéro de barre

Ensuite, dans la ligne : ExtMapBuffer[shift]=val ; - qu'avons-nous ? Dois-je m'expliquer davantage ?

Tout d'abord, l'index du tampon de l'indicateur doit être égal à l'index de la barre, à partir de laquelle nous prenons la valeur val. Sinon, il y aura une divergence. Ce que nous avons en fait, quand nous voyons que le zigzag a une rupture dans l'air.

Rosh, ne te laisse pas distraire. Votre invention est un zigzag. Allons au fond des choses. Il y a beaucoup d'erreurs dans le code. Si vous analysez soigneusement ce que j'écris, vous verrez des erreurs évidentes.

Mais ce n'est pas l'essentiel non plus. S'il ne s'agissait que de ces erreurs, je n'aurais pas posé la question, qui est le titre de ce fil.
 
Encore une fois à propos des fonctions les plus basses et les plus hautes.

Dans le billet précédent, j'ai parlé d'une erreur dans le code zigzag.

L'erreur principale.

Dans un ensemble de barres ExtDepth, la barre ayant le plus haut ou le plus bas niveau est recherchée. La recherche s'effectue à partir de la barre SHIFT. Roche a donné la définition de la fonction suivante : elle renvoie le numéro de la barre la plus haute et la plus basse dans les N barres de la barre actuelle dans la section historique. Mais il n'y a pas de définition de ce qu'est le bar actuel. La barre actuelle est une barre zéro ou une barre avec un numéro de décalage. D'après le code donné du zigzag, la barre actuelle doit être comprise comme une barre avec un numéro d'équipe.

Supposons que nous ayons trouvé le numéro de la barre dans la section ExtDepth des barres, en comptant à partir de la barre avec le numéro d'équipe. Et cette barre n'aurait pas nécessairement un numéro d'équipe. Mais la valeur de l'extremum de la barre que nous avons trouvée et qui diffère de la barre avec le numéro de décalage est placée dans le tampon indicateur avec le numéro de décalage : ExtMapBuffer[shift]=val. D'où des ruptures dans le zigzag suspendu dans l'air. Tous ceux qui ont essayé de travailler avec le zigzag à partir de MT l'ont vu.

C'est une erreur majeure. Mais cette erreur est facile à corriger. Et ce n'était pas la peine d'en parler.

Lorsqu'on commence à effacer cette erreur, on se demandera : sur la barre avec quel numéro les fonctions Lowest et Highest ont trouvé l'extremum que nous cherchons ? Aucune logique n'aide ici. J'ai eu beau essayer de trouver le numéro de cette barre, ça n'a pas marché.

C'est pourquoi la question a été adressée aux développeurs.

Mais j'étais heureux que la question ait été répondue par Rosh. C'est après ses modifications que nous utilisons depuis longtemps le zigzag inclus avec MT.

Chers développeurs, veuillez prêter attention aux questions posées. Les questions sont sérieuses. De nombreux indicateurs utilisent le zigzag qui est inclus dans le MT. Je ne peux pas compter le nombre de plaintes concernant le travail du zigzag.
J'ai donné une description des erreurs. Dans une bonne mesure, les erreurs doivent être corrigées. Ignorer la correction des erreurs nuit à la réputation de l'entreprise. Et ce n'est pas bon. Personne ne veut ça.
 
...la question se pose : sur quelle barre les fonctions Lowest et Highest ont-elles trouvé l'extremum que nous recherchons ? Aucune logique n'aide ici. J'avais beau essayer de calculer le numéro de la barre, ça ne marchait pas.
Selon l'idée, indice de la barre = Highest(NULL,0,MODE_HIGH,ExtDepth,shift)

C'est-à-dire que cela devrait être ExtMapBuffer2[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)]=val ;
 
nen, maintenant j'ai regardé dans l'algorithme standard Zig-Zag - il y a un autre algorithme, différent de celui que vous avez donné :

.
//+------------------------------------------------------------------+
//|                                                       ZigZag.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
//---- indicator buffers
double ExtMapBuffer[];
double ExtLowBuffer[];
double ExtHighBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(3);
//---- drawing settings
   SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer);
   SetIndexBuffer(1,ExtLowBuffer);
   SetIndexBuffer(2,ExtHighBuffer);
   SetIndexEmptyValue(0,0.0);
//---- indicator short name
   IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int    shift, back,lasthighpos,lastlowpos,index;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;
//----
   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      index=Lowest(NULL,0,MODE_LOW,ExtDepth,shift);
      val=Low[index];
      if(val==lastlow) val=0.0;
      else 
        { 
         lastlow=val; 
         if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtLowBuffer[shift+back];
               if((res!=0)&&(res>val)) ExtLowBuffer[shift+back]=0.0; 
              }
           }
        } 
      ExtLowBuffer[shift]=0.0;
      if(val!=0.0) ExtLowBuffer[index]=val;
      //--- high
      index=Highest(NULL,0,MODE_HIGH,ExtDepth,shift);
      val=High[index];
      if(val==lasthigh) val=0.0;
      else 
        {
         lasthigh=val;
         if((val-High[shift])>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtHighBuffer[shift+back];
               if((res!=0)&&(res<val)) ExtHighBuffer[shift+back]=0.0; 
              } 
           }
        }
      ExtHighBuffer[shift]=0.0;
      if(val!=0.0) ExtHighBuffer[index]=val;
     }
//---- final cutting 
   lasthigh=-1; lasthighpos=-1;
   lastlow=-1;  lastlowpos=-1;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      curlow=ExtLowBuffer[shift];
      curhigh=ExtHighBuffer[shift];
      if(curlow==0 && curhigh==0) continue;
      //---
      if(curhigh!=0)
        {
         if(lasthigh>0) 
           {
            if(lasthigh<curhigh) ExtHighBuffer[lasthighpos]=0;
            else ExtHighBuffer[shift]=0;
           }
         //---
         if(lasthigh<curhigh || lasthigh<0)
           {
            lasthigh=curhigh;
            lasthighpos=shift;
           }
         lastlow=-1;
        }
      //----
      if(curlow!=0)
        {
         if(lastlow>0)
           {
            if(lastlow>curlow) ExtLowBuffer[lastlowpos]=0;
            else ExtLowBuffer[shift]=0;
           }
         //---
         if((curlow<lastlow)||(lastlow<0))
           {
            lastlow=curlow;
            lastlowpos=shift;
           } 
         lasthigh=-1;
        }
     }
//---- merge 2 buffers
   lasthighpos=-1;
   lastlowpos=-1;
   for(shift=Bars-1; shift>=0; shift--)
     {
      if(shift>=Bars-ExtDepth) ExtMapBuffer[shift]=0.0;
      else
        {
         curlow=ExtLowBuffer[shift];
         curhigh=ExtHighBuffer[shift];
         //----
         res=0;
         if(curlow!=0)
           {
            if(lastlowpos==-1)
              {
               res=curlow;
               lastlowpos=shift;
              }
            else
              {
               if(lasthighpos!=-1 && lastlowpos>lasthighpos)
                 {
                  res=curlow;
                  lastlowpos=shift;
                 }
              }
           }
         if(curhigh!=0)
           {
            if(lasthighpos==-1)
              {
               res=curhigh;
               lasthighpos=shift;
              }
            else
              {
               if(lastlowpos!=-1 && lasthighpos>lastlowpos)
                 {
                  res=curhigh;
                  lasthighpos=shift;
                 }
              }
           }
         //----
         ExtMapBuffer[shift]=res;
        }
     }
  }
//+------------------------------------------------------------------+



Tout semble correct ici - l'index est enregistré et la valeur est écrite dans l'élément de tableau souhaité. Partons de cet algorithme.

 
nen, excusez-moi, mais ne serait-il pas plus facile d'écrire un code court qui trouve ces Lowest et Highest ? Je n'ai tout simplement jamais utilisé ces fonctions, précisément parce que les données dont j'ai besoin pour les extrema sont obtenues par un simple code court, car il fonctionnera certainement plus rapidement que les fonctions standard. Il me semble qu'il est judicieux de ne les utiliser que lorsqu'il est nécessaire d'obtenir des données d'une autre période.
 
komposter, c'est ça. Regardez ensuite où il est écrit. Dans le tampon de l'indicateur avec quel indice.
Vladislav, le code provient de codebase.mql.com et c'est exactement le même. Je vais essayer de mettre votre code. Je vais voir ce qui peut se passer.
Candidat, je suis d'accord que cela peut être plus simple. Mais j'aurai besoin de ces fonctions pour travailler avec une autre période.
Raison: