Lo que devuelven las funciones Lowest y Highest

 
¡Estimados desarrolladores de Metatrader!

¿Qué devuelven las funciones Mínimo y Máximo?
¿Por qué hago esta pregunta? La descripción de estas funciones es confusa. Al analizar por qué ZigZag incluido en MetaTrader no funciona correctamente, me enfrenté al hecho de que no está claro lo que devuelven las funciones anteriores. ¿O tal vez debido a la confusa descripción no se están aplicando correctamente? Describí este problema en la página 77 de este foro en la sección "Estrategia de trading basada en la teoría de la onda de Elliot". Estoy tratando de entender, tal vez ZigZag algoritmo está mal. Pero todo depende de cómo funcionen estas funciones.

También he observado problemas con estas funciones en otros indicadores. Pero de momento está en ZigZag.

Por favor, aclárese.
 
Devuelven el número de la barra que es la más alta y la más baja a lo largo de N barras desde la barra actual hasta el final del historial. En este caso, si dos valores son iguales (dos barras son extremas en esta muestra), siempre se devuelve el número de la barra que llegó antes (es más antigua).

El algoritmo Zigzag (incluido en MT4 como estándar) no tiene en cuenta la situación en la que una barra puede ser un máximo y un mínimo al mismo tiempo (una barra exterior).
 
Rosh, es comprensible. Prueba a insertar esas líneas que di en el hilo de análisis de ondas en el texto del zigzag. Y mira lo que obtienes. Y se obtiene basura. Por eso surgió la pregunta.

Todo está claro con la teoría hasta que empieza a divergir de la práctica. Si se producen errores, hay que llegar hasta el final. Y averigüe de dónde provienen los errores.
 
Rosh, es comprensible. Prueba a insertar esas líneas que di en el hilo de análisis de ondas en el texto del zigzag. Y mira lo que obtienes. Y se obtiene basura. Por eso le he hecho esta pregunta. <br / translate="no">


He mirado esa página en onyx y he abierto el Zigzag estándar para comparar. Los códigos son diferentes, tienes que encontrar tu versión de Zigzag para entenderla, desmontarla a fondo y sólo entonces podrás decir algo. Por eso no puedo responder.

Pero sí, hay alguna diferencia en el registro de valores en el código, que se muestra en su página, pero tal vez debería ser así, es difícil de decir. He estado haciendo este tipo de indicadores con valores de arrastre, parece un canal, pero al menos no miente en la historia.
 
Rosh, aquí está el código en zigzag de codebase.mql.com

//+------------------------------------------------------------------+
//| Media móvil personalizada.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp.
//| https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#enlace de la propiedad "https://www.metaquotes.net/

#propiedad ventana_del_gráfica_del_indicador
#property indicator_buffers 1
#property indicator_color1 Rojo
//---- parámetros del indicador
extern intDepth=12;
extern inttern ExtDeviation=5;
extern inttern ExtBackstep=3;
//---- búferes indicadores
doble ExtMapBuffer[];
doble ExtMapBuffer2[];

//+------------------------------------------------------------------+
//| Función de inicialización de indicadores personalizada |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(2);
//---- ajustes de dibujo
SetIndexStyle(0,DRAW_SECTION);
//---- asignación de topes indicadores
SetIndexBuffer(0,ExtMapBuffer);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(0,0.0);
//---- nombre corto del indicador
IndicatorShortName("ZigZag("+ExtDepth+", "+ExtDeviation+", "+ExtBackstep+")";
//---- inicialización realizada
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int inicio()
{
int cambio,atrás,última posición alta,última posición baja;
doble val,res;
doble curlow,curhigh,lastthigh,lastlow;

for(shift=Bars-ExtDepth; shift>=0; shift--)
{
val=Low[Lowest(NULL,0,MODE_LOW,ExtDepth,shift)];
if(val==lastlow) val=0,0;
si no
{
lastlow=val;
if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
si no
{
for(back=1; back<=ExtBackstep; back++)
{
res=ExtMapBuffer[shift+back];
if((res!=0)&&(res>val)) ExtMapBuffer[shift+back]=0.0;
}
}
}
****** ExtMapBuffer[shift]=val;
//--- alto
val=Alto[Máximo(NULL,0,MODE_HIGH,ExtDepth,shift)];
if(val==lasthigh) val=0,0;
si no
{
último muslo=val;
if((val-High[shift])>(ExtDeviation*Point)) val=0.0;
si no
{
for(back=1; back<=ExtBackstep; back++)
{
res=BufferExtMap2[shift+back];
if((res!=0)&&(res<val)) ExtMapBuffer2[shift+back]=0.0;
}
}
}
***** ExtMapBuffer2[shift]=val;
}


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

Los asteriscos indican los lugares que cité en la página 77 de mi rama sobre el análisis de ondas. ¿En qué se diferencia este código del que he citado? Este es un código estándar.

Ahora cito tus palabras del segundo post de este hilo

Rosh 18.10.06 10:14

Devuelve el número de la barra, que es la más alta y la más baja dentro de N barras desde la actual en la profundidad del historial. Al hacerlo, si dos valores son iguales (dos barras son extremas en esa muestra), siempre devuelven el número de la barra que llegó primero (es la más antigua).

El algoritmo Zigzag (incluido en MT4 como estándar) no tiene en cuenta la situación en la que una barra puede ser un máximo y un mínimo al mismo tiempo (barra exterior).
======================
Hay una línea en el código: val=High[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)];
Los corchetes contienen el número de barra... Bueno, su respuesta dice lo que es este número de barra

Luego en la línea: ExtMapBuffer[shift]=val; - ¿qué tenemos? ¿Necesitamos más explicaciones?

En primer lugar, el índice del buffer del indicador debe ser igual al índice de la barra, de la que tomamos el valor val. De lo contrario, habrá una discrepancia. Lo que tenemos en realidad, cuando vemos que el zigzag tiene una ruptura en el aire.

Rosh, no te desvíes. Tu idea es un zigzag. Vamos a llegar al fondo de esto. Hay muchos errores en el código. Si analizas cuidadosamente lo que escribo, verás errores evidentes.

Pero eso tampoco es lo principal. Si sólo se tratara de estos errores, no habría hecho la pregunta, que es el título de este hilo.
 
Nuevamente sobre las funciones más bajas y más altas.

En el post anterior escribí sobre un error en el código del zigzag.

El error principal.

En un tramo de barras ExtDepth se busca la barra con el máximo o el mínimo más alto. La búsqueda se realiza desde la barra SHIFT. Roche dio la siguiente definición de la función: devuelve el número de la barra más alta y más baja dentro de N barras de la barra actual en la sección de historia. Pero no hay una definición de lo que es el bar actual. La barra actual es una barra cero o una barra con número de desplazamiento. A juzgar por el código dado del zigzag, la barra actual debe entenderse como una barra con número de turno.

Supongamos que hemos encontrado el número de compás en la sección ExtDepth de los compases, contando desde el compás con número de turno. Y esa barra no tendría necesariamente un número de turno. Pero el valor del extremo de la barra que hemos encontrado que difiere de la barra con el número de desplazamiento se coloca en el buf fer del indicador con el número de desplazamiento: ExtMapBuffer[shift]=val. De ahí que se produzcan rupturas en el zigzag que cuelga en el aire. Todos los que han intentado trabajar con el zigzag de MT lo han visto.

Esto es un gran error. Pero este error es fácil de corregir. Y no valía la pena sacarlo a relucir.

Cuando se empiece a despejar este error, se preguntará: ¿en la barra con qué número las funciones Mínimo y Máximo encontraron el extremo que buscamos? La lógica no ayuda aquí. Por más que intenté averiguar el número de esta barra, no funcionó.

Por eso la pregunta se dirigió a los promotores.

Pero me alegré de que la pregunta fuera respondida por Rosh. Es después de sus ediciones que hemos estado utilizando el zigzag incluido con MT durante mucho tiempo.

Estimados desarrolladores, presten atención a las preguntas planteadas. Las preguntas son serias. Muchos indicadores utilizan el zigzag que se incluye en la MT. No puedo contar el número de quejas sobre el trabajo del zigzag.
He dado una descripción de los errores. En buena medida, los errores deben corregirse. Ignorar la corrección de errores daña la reputación de la empresa. Y eso no es bueno. Nadie quiere eso.
 
...la pregunta que surge es ¿en qué barra de las funciones más bajas y más altas se encuentra el extremo que buscamos? La lógica no ayuda aquí. Por más que intenté calcular el número de la barra, no funcionó.
Según la idea, índice de la barra = Highest(NULL,0,MODE_HIGH,ExtDepth,shift)

Es decir, debería ser ExtMapBuffer2[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)]=val;
 
nen, ahora miré en el algoritmo estándar Zig-Zag - hay otro algoritmo, diferente de lo que usted dio:

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



Todo parece correcto aquí - tanto el índice se guarda como el valor se escribe en el elemento del array deseado. Partamos de este algoritmo.

 
nen, perdona, pero ¿no sería más fácil escribir un código corto que encuentre estos Lowest y Highest? Sencillamente, nunca he utilizado estas funciones, precisamente porque obtengo los datos que necesito para los extremos mediante un simple código corto, ya que seguramente funcionará más rápido que las funciones estándar. Me parece que tiene sentido utilizarlos sólo cuando es necesario obtener datos de otro marco temporal.
 
komposter, así es. Entonces, mira dónde se escribe. En la memoria intermedia del indicador con qué índice.
Vladislav, el código es de codebase.mql.com y es exactamente el mismo. Intentaré poner tu código. Veré lo que puede pasar.
Candidato, estoy de acuerdo en que puede ser más sencillo. Pero necesitaré estas funciones para trabajar con otro marco temporal.
Razón de la queja: