Mira cómo descargar robots gratis
¡Búscanos en Facebook!
Pon "Me gusta" y sigue las noticias
¿Es interesante este script?
Deje un enlace a él, ¡qué los demás también lo valoren!
¿Le ha gustado el script?
Evalúe su trabajo en el terminal MetaTrader 5
Visualizaciones:
62
Ranking:
(6)
Publicado:
2025.06.14 11:57
fiboZigZag.mq5 (13.54 KB) ver
MQL5 Freelance ¿Necesita un robot o indicador basado en este código? Solicítelo en la bolsa freelance Pasar a la bolsa

El montaje

Necesitaremos :

  • 1 gráfico en zigzag
  • 2 buffers de datos para los máximos y los mínimos
  • parámetros de entrada
  • un conjunto continuo de variables del sistema que se reinician cada vez que el indicador recalcula

#property indicator_buffers 2
#property indicator_plots 1
input double retracement=23.6;//cantidad de retroceso
input double minSizeInAtrUnits=0.0;//tamaño de las ondas en unidades atr
input int rollingAtrPeriod=14;//periodo atr
input color Color=clrDodgerBlue;//color de onda
input int Width=3;//anchura de onda
input ENUM_LINE_STYLE Style=STYLE_SOLID;//estilo wave
//+------------------------------------------------------------------+




//| Función de inicialización del indicador personalizada |
//+------------------------------------------------------------------+
//--- up waves and the downwaves
  double upWaves[],dwWaves[];

El array upWaves almacenará los máximos y el array dwWaves almacenará los mínimos

Variables del sistema :

necesitamos saber el tipo de la última onda, donde empezó, donde terminó, la distancia en barras desde el inicio y el final.

Luego necesitamos una variable local alta y una local baja así como las distancias en barras desde cada punto.

//--- siguiendo el zigzag
  //--- el tipo de onda que tenemos [0] ninguna [1] arriba [2] abajo
    int wave_type=0;
  //--- el precio desde de la onda (precio inicial) 
    double wave_start_price=0.0;
  //--- el precio hasta de la onda (precio final)
    double wave_end_price=0.0;
  //--- la distancia en barras desde el precio inicial
    int wave_start_distance=0;
  //--- la distancia en barras desde el precio final
    int wave_end_distance=0;
  //--- alto precio de seguimiento
    double high_mem=0.0;
    int distance_from_high=0;
  //--- seguimiento de precios bajos
    double low_mem=0.0;
    int distance_from_low=0;
  //--- rolling atr
    double rollingAtr=0.0;
       int rollingAtrs=0;

Finalmente la unidad rolling atr y cuantas se han calculado

Luego creamos una función de reinicio del sistema:

void resetSystem(){
ArrayFill(upWaves,0,ArraySize(upWaves),0.0);
ArrayFill(dwWaves,0,ArraySize(dwWaves),0.0);
wave_type=0;
wave_start_price=0.0;
wave_end_price=0.0;
wave_start_distance=0;
wave_end_distance=0;
high_mem=0.0;
low_mem=0.0;
distance_from_high=0;
distance_from_low=0;
rollingAtr=0.0;
rollingAtrs=0;
}

Lo normal, llenar las matrices con ceros y restablecer las variables del sistema.

Oninit configuramos los buffers , el plot , y llamamos a reset por primera vez :

  SetIndexBuffer(0,upWaves,INDICATOR_DATA);
  SetIndexBuffer(1,dwWaves,INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Color);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,Width);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,Style);
  resetSystem();

Así que vamos a saltar a la derecha en el cálculo.

Lo primero que tenemos que tener en cuenta es el rolling atr.

Hasta que no hayamos recogido mas barras que el periodo atr no haremos nada mas.

La parte que gestiona el rolling atr es la siguiente :

  • si no hemos recogido mas que el periodo seguimos sumando el rango de las barras encontradas a una suma
  • una vez alcanzado el periodo realizamos la primera división (media)
  • A continuación, recortamos una parte de la media móvil, que es media/periodo, y añadimos una nueva parte que es rango de barras/periodo.
Colocamos la última parte primero porque sucederá más a menudo y no necesitaremos acceder a 2 sentencias if.

     //--- gestionar el atr
       rollingAtrs++;
       if(rollingAtrs>rollingAtrPeriod){
       double new_portion=((high[i]-low[i])/_Point)/((double)rollingAtrPeriod);
       //--- quitamos una porción vieja y añadimos una porción nueva
       rollingAtr=(rollingAtr)-(rollingAtr/((double)rollingAtrPeriod))+new_portion;
       }
       else if(rollingAtrs<=rollingAtrPeriod){
         rollingAtr+=(high[i]-low[i])/_Point;
         if(rollingAtrs==rollingAtrPeriod){
           rollingAtr/=((double)rollingAtrs);
           //--- iniciar la memoria para altas y bajas y el sistema
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
         }

Impresionante, ahora, hay otro problema.

La base de este zig zag es un retroceso.

Pero para que ocurra un retroceso debe haber al menos una onda.

¿Pero cual será el retroceso de la primera onda? xD

Por eso haremos lo siguiente :

  • en cuanto el atr se llene (atr recogido = periodo) , cogeremos el máximo y el mínimo en las variables de nuestro sistema
  • el lado que consiga formar una onda que tenga un tamaño válido en unidades atr , y forme un nuevo máximo (onda alcista) o un nuevo mínimo (onda bajista) gana

de esta manera no tenemos un retroceso como onda inicial , pero , tenemos que empezar la secuencia de alguna manera.

Tenga en cuenta que también podríamos haber optado por tener un enfoque fractal clásico aquí sólo para la primera onda y luego continuar con los retrocesos.

Esto es lo que hacemos siempre y cuando no tengamos una onda :

   //--- si aún no tenemos un tipo de onda
     else{
       //--- si rompimos el máximo y no el mínimo
         if(high[i]>high_mem&&low[i]>=low_mem){
         double new_wave_size_in_atr_units=((high[i]-low_mem)/_Point)/rollingAtr;
         //--- si el nuevo tamaño de onda es válido
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
           //--- iniciar una nueva onda ascendente 
             wave_type=1;
           //--- el precio inicial es el mem bajo 
             wave_start_price=low_mem;
             wave_start_distance=distance_from_low;
           //--- el precio final es el nuevo máximo
             wave_end_price=high[i];
             wave_end_distance=0;
           //--- dibuja la ola 
             dwWaves[i-wave_start_distance]=low_mem;
             upWaves[i]=high[i];
           //--- cambiar el alto
             high_mem=high[i];
             distance_from_high=0;
           //--- cambiar el bajo 
             low_mem=low[i];
             distance_from_low=0;
           }
           } 
       //--- si rompimos el mínimo y no el máximo
         else if(low[i]<low_mem&&high[i]<=high_mem){
         double new_wave_size_in_atr_units=((high_mem-low[i])/_Point)/rollingAtr;
         //--- si el nuevo tamaño de onda es válido
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){         
           //--- comienza una nueva onda descendente 
             wave_type=-1;
           //--- el precio inicial es la mem alta 
             wave_start_price=high_mem;
             wave_start_distance=distance_from_high;
           //--- el precio final es el nuevo mínimo
             wave_end_price=low[i];
             wave_end_distance=0;
           //--- dibuja la ola 
             upWaves[i-wave_start_distance]=high_mem;
             dwWaves[i]=low[i];
           //--- cambiar el alto
             high_mem=high[i];
             distance_from_high=0;
           //--- cambiar el bajo 
             low_mem=low[i];
             distance_from_low=0;
           }
           }
       //--- si rompemos ambos
         else if(low[i]<low_mem&&high[i]>high_mem){
           //--- cambiarlos
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
       }

Genial. Ahora la pieza final.

  • Si tenemos una onda alcista :
  1. Si se hace un nuevo máximo, movemos el zigzag desde la posición del máximo anterior a la posición del nuevo máximo, lo que podemos hacer ya que mantenemos las distancias de las barras. También actualizamos el mínimo y la distancia desde el mínimo. Hacemos esto para que podamos coger el mínimo más bajo desde el máximo y comprobar si retrocede lo suficiente para empezar un nuevo mínimo.
  2. si se hace un nuevo mínimo, o se establece un nuevo mínimo, calculamos la distancia desde el máximo hasta el mínimo y la dividimos por el tamaño de la onda. Así que si el tamaño de la onda es de 100 puntos y el retroceso es de 24 puntos obtenemos 24/100 0.24 , entonces x 100 24% . Si el tamaño de la nueva onda "sería" que retrocede a la anterior también es válido contra las unidades atr iniciamos una nueva onda descendente, establecemos los nuevos máximos y mínimos locales, establecemos las distancias de las barras.

aquí está el código relevante para lo anterior :

       //--- si tenemos una onda alcista 
         if(wave_type==1){
           //--- si la onda se expande hacia arriba 
             if(high[i]>wave_end_price){
               //--- elimina el precio final anterior de su posición en el array (0.0=vacío)
                upWaves[i-wave_end_distance]=0.0;
               //--- colocarlo en la nueva posición
                upWaves[i]=high[i];
                wave_end_price=high[i];
                wave_end_distance=0;
               //--- cambiar el alto
                high_mem=high[i];
                distance_from_high=0;
               //--- cambiar el bajo 
                low_mem=low[i];
                distance_from_low=0;
               }
           //--- comprueba el retroceso
             if(low[i]<low_mem||distance_from_low==0){
               low_mem=low[i];
               distance_from_low=0;
               double size_of_wave=(wave_end_price-wave_start_price)/_Point;
               double size_of_retracement=(wave_end_price-low_mem)/_Point;
               if(size_of_wave>0.0){
                 double retraced=(size_of_retracement/size_of_wave)*100.0;
                 double new_wave_size_in_atr_units=((wave_end_price-low_mem)/_Point)/rollingAtr;
               //--- si el nuevo tamaño de onda es válido
               if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
                 //--- si el retroceso es significativo , inicia una onda descendente
                   if(retraced>=retracement){
                    //--- comienza una nueva onda descendente 
                      wave_type=-1;
                    //--- el precio inicial es la mem alta 
                      wave_start_price=high[i-distance_from_high];
                      wave_start_distance=distance_from_high;
                    //--- el precio final es el nuevo mínimo
                      wave_end_price=low[i];
                      wave_end_distance=0;
                    //--- dibuja la ola 
                      upWaves[i-wave_start_distance]=high_mem;
                      dwWaves[i]=low[i];
                    //--- cambiar el alto
                      high_mem=high[i];
                      distance_from_high=0;
                    //--- cambiar el bajo 
                      low_mem=low[i];
                      distance_from_low=0;                     
                     }
                   }
                 }
               }
           }

Hacemos lo contrario cuando tenemos una onda bajista.

Y ya está, nuestro zig zag de retroceso está listo.

Aquí está el zigzag con 23.6% de retroceso y 0.0 min tamaño de las ondas en unidades atr


y aquí está el mismo zig zag con 3 min tamaño de las ondas en unidades atr






Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/code/56619

Exportador de informes comerciales Exportador de informes comerciales

El script TradeReportExporter está diseñado para exportar el historial de operaciones (trades) a un práctico archivo CSV. Recoge automáticamente los datos de todas las operaciones del último año para el instrumento en el que está instalado. El archivo incluye datos como fecha y hora, tipo de operación (compra/venta), precio, volumen, comisión y beneficio/pérdida. El resultado se guarda en un archivo que puede abrirse en Excel o en cualquier otro editor de hojas de cálculo.

Swaps Monitor for a Single Symbol Swaps Monitor for a Single Symbol

Una sencilla utilidad para supervisar los swaps largos y cortos de un mismo símbolo. Si los swaps de su agente de bolsa se especifican en puntos en lugar de en la divisa de la cuenta, esta utilidad convierte automáticamente los puntos en la divisa de la cuenta. Los swaps se triplican los miércoles. La alineación horizontal y vertical puede ajustarse en las entradas.

Autoscaling Zigzag Autoscaling Zigzag

Un indicador de zigzag que utiliza una sola entrada para ajustar el tamaño del paso y detectar los cambios de dirección de las olas.

Telegram integration made easy. Telegram integration made easy.

El objetivo es hacer la función fácilmente disponible para cualquier tarea de integración de Telegram en el desarrollo de MQL5. Añadiendo este archivo a tu CodeBase, puedes simplemente incluirlo en tus Asesores Expertos y llamar a la función directamente desde el módulo incluido. Esto elimina la necesidad de volver a desarrollar el código desde cero repetidamente, asegurando la reutilización a través de múltiples proyectos.