Cosa restituiscono le funzioni Lowest e Highest

 
Cari sviluppatori di Metatrader!

Cosa restituiscono le funzioni Lowest e Highest?
Perché faccio questa domanda? La descrizione di queste funzioni è confusa. Nell'analizzare il motivo per cui ZigZag incluso in MetaTrader non funziona correttamente, ho affrontato il fatto che non è chiaro cosa restituiscono le funzioni di cui sopra. O forse a causa della descrizione confusa non vengono applicate correttamente? Ho descritto questo problema su questo forum a pagina 77 nella sezione "Strategia di trading basata sulla teoria delle onde di Elliot". Sto cercando di capire, forse l'algoritmo ZigZag è sbagliato. Ma tutto dipende da come funzionano queste funzioni.

Ho anche osservato problemi con queste funzioni in altri indicatori. Ma al momento è in ZigZag.

Si prega di chiarire.
 
Restituiscono il numero della barra che è la più alta e la più bassa su N barre dalla barra corrente alla parte posteriore della storia. In questo caso, se due valori sono uguali (due barre sono estremi su questo campione), viene sempre restituito il numero della barra che è venuta prima (è più vecchia).

L'algoritmo Zigzag (incluso in MT4 come standard) non tiene conto della situazione in cui una barra può essere sia un massimo che un minimo allo stesso tempo (una barra esterna).
 
Rosh, è comprensibile. Prova a inserire le linee che ho dato nel thread sull'analisi delle onde nel testo a zig zag. E vedere cosa si ottiene. E si ottiene la spazzatura. Questo è il motivo per cui è sorta la domanda.

Tutto è chiaro con la teoria finché non comincia a divergere dalla pratica. Se ci sono errori, bisogna andare fino in fondo. E scoprite da dove vengono gli errori.
 
Rosh, è comprensibile. Prova a inserire le linee che ho dato nel thread sull'analisi delle onde nel testo a zig zag. E vedere cosa si ottiene. E si ottiene la spazzatura. Ecco perché vi ho fatto questa domanda. <br / translate="no">


Ho guardato quella pagina su onyx e ho aperto lo Zigzag standard per confrontare. I codici sono diversi, devi trovare la tua variante di Zigzag, smontarla a fondo e solo allora potrai dire qualcosa. Ecco perché non posso rispondere.

Ma sì, ci sono alcune differenze nella registrazione dei valori nel codice, che è mostrato nella tua pagina, ma forse dovrebbe essere così, è difficile da dire. Ho fatto tali indicatori con valori di crawl, sembra un canale, ma almeno non mente sulla storia.
 
Rosh, ecco il codice a zig zag da codebase.mql.com

//+------------------------------------------------------------------+
//| Media mobile personalizzata.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp.
//| https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link "https://www.metaquotes.net/

#proprietà indicator_chart_window
#proprietà indicator_buffers 1
#property indicator_color1 Red
//---- parametri dell'indicatore
extern intDepth=12;
extern inttern ExtDeviation=5;
extern inttern ExtBackstep=3;
//---- buffer degli indicatori
doppio ExtMapBuffer[];
doppio ExtMapBuffer2[];

//+------------------------------------------------------------------+
//| funzione di inizializzazione dell'indicatore personalizzato
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(2);
//---- impostazioni di disegno
SetIndexStyle(0,DRAW_SECTION);
//---- mappatura dei buffer degli indicatori
SetIndexBuffer(0,ExtMapBuffer);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(0,0.0);
//---- nome corto dell'indicatore
IndicatoreNomeCorto("ZigZag("+ExtDepth+", "+ExtDeviation+", "+ExtBackstep+")");
//---- inizializzazione fatta
ritorno(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
int shift, back, lasthighpos, lastlowpos;
doppio val,res;
doppio curlow, curhigh, lasthigh, lastlow;

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


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

Gli asterischi indicano i luoghi che ho citato a pagina 77 del mio ramo sull'analisi delle onde. In che modo questo codice è diverso da quello che ho citato? Questo è un codice standard.

Ora cito le tue parole del secondo post di questo thread

Rosh 18.10.06 10:14

Restituisce il numero della barra che è la più alta e la più bassa entro N barre da quella corrente nelle profondità della storia. Così facendo, se due valori sono uguali (due barre sono estremi su quel campione), restituiscono sempre il numero della barra che è venuta prima (è la più vecchia).

L'algoritmo Zigzag (incluso in MT4 come standard) non tiene conto della situazione in cui una barra può essere un massimo e un minimo allo stesso tempo (outer bar).
======================
C'è una linea nel codice: val=High[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)];
Le parentesi quadre contengono il numero della barra... Bene, la tua risposta dice che cos'è questo numero di barra

Poi nella linea: ExtMapBuffer[shift]=val; - cosa abbiamo? C'è bisogno di ulteriori spiegazioni?

Innanzitutto, l'indice del buffer dell'indicatore deve essere uguale all'indice della barra, da cui prendiamo il valore val. Altrimenti, ci sarà una discrepanza. Quello che abbiamo in realtà, quando vediamo che lo zigzag ha una pausa nell'aria.

Rosh, non farti distrarre. La tua idea è uno zigzag. Andiamo in fondo a questa storia. Ci sono molti errori nel codice. Se analizzi attentamente quello che scrivo, vedrai degli errori evidenti.

Ma non è nemmeno la cosa principale. Se si trattasse solo di questi errori, non avrei fatto la domanda, che è il titolo di questo thread.
 
Di nuovo sulle funzioni più basse e più alte.

Nel post precedente ho scritto di un errore nel codice zigzag.

L'errore principale.

In un tratto di barre ExtDepth si cerca la barra con il massimo più alto o il minimo più basso. La ricerca viene eseguita dalla barra SHIFT. Roche ha dato la seguente definizione della funzione: restituisce il numero della barra più alta e più bassa entro N barre della barra corrente nella sezione della storia. Ma non c'è una definizione di cosa sia la barra attuale. La barra attuale è una barra zero o una barra con numero di spostamento. A giudicare dal codice dato dello zigzag, la barra attuale dovrebbe essere intesa come una barra con numero di spostamento.

Supponiamo di aver trovato il numero della barra nella sezione ExtDepth delle barre, contando dalla barra con numero di spostamento. E quella barra non avrebbe necessariamente un numero di turno. Ma il valore dell'estremo della barra che abbiamo trovato e che differisce dalla barra con il numero di shift viene messo nel buffer dell'indicatore con il numero di shift: ExtMapBuffer[shift]=val. Da qui ci sono delle pause nello zigzag appeso nell'aria. Tutti quelli che hanno provato a lavorare con lo zigzag da MT l'hanno visto.

Questo è un grave errore. Ma questo errore è facile da correggere. E non valeva la pena di parlarne.

Quando si comincia a cancellare questo errore, si chiederà: sulla barra con quale numero le funzioni Lowest e Highest hanno trovato l'estremo che stiamo cercando? Nessuna logica aiuta qui. Per quanto mi sforzassi di capire il numero di questa barra, non funzionava.

Ecco perché la domanda era rivolta agli sviluppatori.

Ma sono stato contento che la domanda abbia avuto una risposta da Rosh. È dopo le sue modifiche che abbiamo usato lo zigzag incluso con MT per molto tempo.

Cari sviluppatori, prestate attenzione alle domande poste. Le domande sono serie. Molti indicatori usano lo zigzag che è incluso nel MT. Non posso contare il numero di lamentele sul lavoro dello zigzag.
Ho dato una descrizione degli errori. In buona misura, gli errori devono essere corretti. Ignorare la correzione degli errori danneggia la reputazione dell'azienda. E questo non è buono. Nessuno vuole questo.
 
...la domanda sorge spontanea, su quale barra le funzioni Lowest e Highest hanno trovato l'estremo che stiamo cercando? Nessuna logica aiuta qui. Per quanto mi sforzassi di calcolare il numero della barra, non funzionava.
Secondo l'idea, indice della barra = Highest(NULL,0,MODE_HIGH,ExtDepth,shift)

Cioè dovrebbe essere ExtMapBuffer2[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)]=val;
 
nen, ora ho cercato l'algoritmo standard Zig-Zag - c'è un altro algoritmo, diverso da quello che hai dato:

//+------------------------------------------------------------------+
//|                                                       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;
        }
     }
  }
//+------------------------------------------------------------------+



Tutto sembra essere corretto qui - sia l'indice viene salvato e il valore viene scritto nell'elemento desiderato dell'array. Partiamo da questo algoritmo.

 
nen, scusami, ma non sarebbe più facile scrivere un breve codice che trova questi Lowest e Highest? Semplicemente non ho mai usato queste funzioni, proprio perché i dati di cui ho bisogno per gli estremi si ottengono con un semplice codice breve, perché sicuramente funziona più velocemente delle funzioni standard. Mi sembra che abbia senso usarli solo quando è necessario ottenere dati da un altro periodo di tempo.
 
komposter, proprio così. Poi guardate dove è scritto. Nel buffer dell'indicatore con quale indice.
Vladislav, il codice è da codebase.mql.com ed è esattamente lo stesso. Cercherò di mettere il vostro codice. Vedrò cosa può succedere.
Candido, sono d'accordo che può essere più semplice. Ma avrò bisogno di queste funzioni per lavorare con un altro lasso di tempo.