Pon "Me gusta" y sigue las noticias
Deje un enlace a él, ¡qué los demás también lo valoren!
Evalúe su trabajo en el terminal MetaTrader 5
- Visualizaciones:
- 62
- Ranking:
- Publicado:
- 2025.06.14 11:57
-
¿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.
//--- 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 :
- 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.
- 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

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.

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.

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.

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.