
Creación de un modelo de restricción de tendencia de velas (Parte 4): Personalización del estilo de visualización para cada onda de tendencias
Contenido
- Introducción
- Recapitulemos
- Estilos de visualización MQL5
- Implementación del estilo DRAW_LINE en nuestro sistema
- Mi estado de la vela D1
- Comprender las funciones y variables de My_D1_Candlestatus.mq5
- Otras alternativas a los estilos de dibujo MQL5
- Conclusión
Introducción
Los estilos de dibujo personalizados pueden mejorar el atractivo visual de los gráficos, haciéndolos más atractivos y fáciles de leer. Un gráfico bien diseñado puede mejorar la experiencia del usuario y reducir la fatiga visual durante largas sesiones de negociación. Al adaptar los estilos de dibujo a las necesidades específicas, los operadores pueden crear configuraciones de negociación más eficientes y eficaces. Por ejemplo, el uso de histogramas para representar los datos de volumen o de líneas para las medias móviles puede facilitar la interpretación de estos indicadores de un vistazo. Los estilos de dibujo, como flechas o símbolos, pueden utilizarse para marcar eventos o señales específicas en el gráfico, como puntos de compra/venta, lo que facilita la detección de oportunidades de negociación.
MQL5 cuenta con una variedad de estilos de dibujo para los indicadores en MetaTrader 5. Estos elementos visuales proporcionan a los operadores una ventaja analítica cuando se muestran en el gráfico de MetaTrader 5, ayudando a una rápida adaptación al sentimiento del mercado. La incorporación de estos diversos estilos de dibujo no sólo mejora el atractivo estético de los gráficos, sino que también permite a los operadores tomar decisiones informadas basadas en un análisis exhaustivo de la dinámica del mercado. Los operadores pueden interpretar eficazmente los movimientos de los precios, identificar tendencias y anticipar posibles retrocesos con mayor precisión. MQL5 cuenta con 18 tipos de gráficos. En este artículo, queremos profundizar y explorar cómo implementar uno de estos estilos de visualización en nuestro modelo.
En lugar de simplemente dibujar una flecha para nuestra alerta, queremos crear un visual más avanzado en el gráfico para hacerlo aún más fácil. Recuerde que en esta serie nuestro objetivo es refinar nuestro modelo Trend Constraint para que se adhiera al sentimiento de nuestra forma de vela D1, así como presentar señales visuales completas en el gráfico. Los estilos de dibujo de MQL5 se pueden personalizar en términos de color, grosor y estilo (por ejemplo, líneas discontinuas o sólidas), lo que ayuda a los operadores a personalizar sus gráficos según sus preferencias y mejorar la legibilidad. Los diferentes estilos de dibujo permiten a los operadores representar los datos de forma más clara y precisa. Por ejemplo, el uso de líneas, histogramas o velas puede facilitar la interpretación de los movimientos de los precios y las tendencias del mercado.
Los distintos estilos de dibujo disponibles en MQL5 ofrecen a los operadores numerosas ventajas. Sirven para mejorar la claridad, precisión y personalización de la visualización de datos. Estos diversos estilos amplían las posibilidades del análisis técnico, permitiendo la utilización de técnicas avanzadas de elaboración de gráficos y facilitando actualizaciones dinámicas en tiempo real. Además, la adaptabilidad y el ingenio inherentes a los estilos de dibujo de MQL5 permiten a los operadores crear indicadores e instrumentos de análisis únicos, ampliando así sus estrategias de negociación y su comprensión del panorama del mercado. Para una comprensión completa de este tema, profundice en el 'Manual de referencia de MQL5' para una exploración en profundidad de los estilos de dibujo.
Recapitulemos
En los artículos anteriores de esta serie (Parte 1, Parte 2, y Parte 3) el objetivo era confinar cada señal al sentimiento de la vela D1. El concepto es que si la vela D1 es alcista, normalmente la tendencia general del día será alcista en plazos inferiores. Mediante el empleo de métodos analíticos avanzados en plazos inferiores, podemos identificar puntos de entrada y generar señales que se alineen con la tendencia actual. Con cada fase, hemos mejorado nuestro código fuente, incorporando nuevas funciones y perfeccionando nuestro modelo. En la serie de artículos, utilizamos flechas como elemento de diseño para cada iteración de nuestro indicador, explorando la utilización de la fuente Wingdings para elementos de visualización opcionales.
Añadimos medias móviles de 200 y 100 a un activo en el gráfico MQL5 para elaborar estrategias. Analizando el comportamiento de estos indicadores incorporados, identificamos un importante evento de cruce periódico. Posteriormente, se creó un indicador de cruce personalizado con un sistema de alerta para notificarnos tales sucesos, que indican un posible cambio de tendencia. Ajustar los valores de la media móvil a niveles más altos puede ayudar a filtrar las señales durante las fluctuaciones del mercado. En la Parte 3, refiné aún más el enfoque mediante la introducción de un período de MA personalizable para explorar varios valores de período y determinar la configuración óptima para las inversiones de tendencia.
input int Slow_MA_period = 200; input int Fast_MA_period = 100;
El software permite ajustar al instante las configuraciones de entrada que aparecen en la representación visual. Para modificar sus atributos, utilice la combinación de teclas Ctrl + I mientras visualiza el gráfico de MetaTrader 5 o simplemente haga clic con el botón derecho del ratón para mostrar el menú del indicador y busque Trend Constraint V1.03.
Fig. 1: Optimización del periodo de la MA para obtener la mejor configuración de reversión de tendencia.
Después de compilar el programa utilizando estas configuraciones de entrada, descubrirá el documento fuente adjunto justo debajo de la conclusión de este artículo. A continuación se presenta el código más reciente de Trend Constraint V1.03:
/// Program after adding Moving Average optimization feature for reversals ///Indicator Name: Trend Constraint #property copyright "Clemence Benjamin" #property link "https://mql5.com" #property version "1.03" #property description "A model that seek to produce sell signal when D1 candle is Bearish only and buy signal when it is Bullish" //--- indicator settings #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 #property indicator_type1 DRAW_ARROW #property indicator_width1 5 #property indicator_color1 0xFF3C00 #property indicator_label1 "Buy" #property indicator_type2 DRAW_ARROW #property indicator_width2 5 #property indicator_color2 0x0000FF #property indicator_label2 "Sell" #property indicator_type3 DRAW_ARROW #property indicator_width3 1 #property indicator_color3 0x04CC04 #property indicator_label3 "Buy Reversal" #property indicator_type4 DRAW_ARROW #property indicator_width4 1 #property indicator_color4 0xE81AC6 #property indicator_label4 "Sell Reversal" #define PLOT_MAXIMUM_BARS_BACK 5000 #define OMIT_OLDEST_BARS 50 //--- indicator buffers double Buffer1[]; double Buffer2[]; double Buffer3[]; double Buffer4[]; input double Oversold = 30; input double Overbought = 70; input int Slow_MA_period = 200; input int Fast_MA_period = 100; datetime time_alert; //used when sending alert input bool Audible_Alerts = true; input bool Push_Notifications = true; double myPoint; //initialized in OnInit int RSI_handle; double RSI[]; double Open[]; double Close[]; int MA_handle; double MA[]; int MA_handle2; double MA2[]; int MA_handle3; double MA3[]; int MA_handle4; double MA4[]; double Low[]; double High[]; void myAlert(string type, string message) { if(type == "print") Print(message); else if(type == "error") { Print(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); } else if(type == "order") { } else if(type == "modify") { } else if(type == "indicator") { if(Audible_Alerts) Alert(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); if(Push_Notifications) SendNotification(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); } } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, Buffer1); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(0, PLOT_ARROW, 241); SetIndexBuffer(1, Buffer2); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(1, PLOT_ARROW, 242); SetIndexBuffer(2, Buffer3); PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(2, PLOT_ARROW, 236); SetIndexBuffer(3, Buffer4); PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(3, PLOT_ARROW, 238); //initialize myPoint myPoint = Point(); if(Digits() == 5 || Digits() == 3) { myPoint *= 10; } RSI_handle = iRSI(NULL, PERIOD_CURRENT, 14, PRICE_CLOSE); if(RSI_handle < 0) { Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, PRICE_CLOSE); if(MA_handle < 0) { Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle2 = iMA(NULL, PERIOD_CURRENT, 400, 0, MODE_SMA, PRICE_CLOSE); if(MA_handle2 < 0) { Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle3 = iMA(NULL, PERIOD_CURRENT, Fast_MA_period, 0, MODE_EMA, PRICE_CLOSE); if(MA_handle3 < 0) { Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle4 = iMA(NULL, PERIOD_CURRENT, Slow_MA_period, 0, MODE_SMA, PRICE_CLOSE); if(MA_handle4 < 0) { Print("The creation of iMA has failed: MA_handle4=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime& time[], const double& open[], const double& high[], const double& low[], const double& close[], const long& tick_volume[], const long& volume[], const int& spread[]) { int limit = rates_total - prev_calculated; //--- counting from 0 to rates_total ArraySetAsSeries(Buffer1, true); ArraySetAsSeries(Buffer2, true); ArraySetAsSeries(Buffer3, true); ArraySetAsSeries(Buffer4, true); //--- initial zero if(prev_calculated < 1) { ArrayInitialize(Buffer1, EMPTY_VALUE); ArrayInitialize(Buffer2, EMPTY_VALUE); ArrayInitialize(Buffer3, EMPTY_VALUE); ArrayInitialize(Buffer4, EMPTY_VALUE); } else limit++; datetime Time[]; datetime TimeShift[]; if(CopyTime(Symbol(), PERIOD_CURRENT, 0, rates_total, TimeShift) <= 0) return(rates_total); ArraySetAsSeries(TimeShift, true); int barshift_M1[]; ArrayResize(barshift_M1, rates_total); int barshift_D1[]; ArrayResize(barshift_D1, rates_total); for(int i = 0; i < rates_total; i++) { barshift_M1[i] = iBarShift(Symbol(), PERIOD_M1, TimeShift[i]); barshift_D1[i] = iBarShift(Symbol(), PERIOD_D1, TimeShift[i]); } if(BarsCalculated(RSI_handle) <= 0) return(0); if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) <= 0) return(rates_total); ArraySetAsSeries(RSI, true); if(CopyOpen(Symbol(), PERIOD_M1, 0, rates_total, Open) <= 0) return(rates_total); ArraySetAsSeries(Open, true); if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close) <= 0) return(rates_total); ArraySetAsSeries(Close, true); if(BarsCalculated(MA_handle) <= 0) return(0); if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total); ArraySetAsSeries(MA, true); if(BarsCalculated(MA_handle2) <= 0) return(0); if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total); ArraySetAsSeries(MA2, true); if(BarsCalculated(MA_handle3) <= 0) return(0); if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) <= 0) return(rates_total); ArraySetAsSeries(MA3, true); if(BarsCalculated(MA_handle4) <= 0) return(0); if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) <= 0) return(rates_total); ArraySetAsSeries(MA4, true); if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total); ArraySetAsSeries(Low, true); if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total); ArraySetAsSeries(High, true); if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total); ArraySetAsSeries(Time, true); //--- main loop for(int i = limit-1; i >= 0; i--) { if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation if(barshift_M1[i] < 0 || barshift_M1[i] >= rates_total) continue; if(barshift_D1[i] < 0 || barshift_D1[i] >= rates_total) continue; //Indicator Buffer 1 if(RSI[i] < Oversold && RSI[i+1] > Oversold //Relative Strength Index crosses below fixed value && Open[barshift_M1[i]] >= Close[1+barshift_D1[i]] //Candlestick Open >= Candlestick Close && MA[i] > MA2[i] //Moving Average > Moving Average && MA3[i] > MA4[i] //Moving Average > Moving Average ) { Buffer1[i] = Low[1+i]; //Set indicator value at Candlestick Low if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open time_alert = Time[1]; } else { Buffer1[i] = EMPTY_VALUE; } //Indicator Buffer 2 if(RSI[i] > Overbought && RSI[i+1] < Overbought //Relative Strength Index crosses above fixed value && Open[barshift_M1[i]] <= Close[1+barshift_D1[i]] //Candlestick Open <= Candlestick Close && MA[i] < MA2[i] //Moving Average < Moving Average && MA3[i] < MA4[i] //Moving Average < Moving Average ) { Buffer2[i] = High[1+i]; //Set indicator value at Candlestick High if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open time_alert = Time[1]; } else { Buffer2[i] = EMPTY_VALUE; } //Indicator Buffer 3 if(MA3[i] > MA4[i] && MA3[i+1] < MA4[i+1] //Moving Average crosses above Moving Average ) { Buffer3[i] = Low[i]; //Set indicator value at Candlestick Low if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Reversal"); //Alert on next bar open time_alert = Time[1]; } else { Buffer3[i] = EMPTY_VALUE; } //Indicator Buffer 4 if(MA3[i] < MA4[i] && MA3[i+1] > MA4[i+1] //Moving Average crosses below Moving Average ) { Buffer4[i] = High[i]; //Set indicator value at Candlestick High if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Reversal"); //Alert on next bar open time_alert = Time[1]; } else { Buffer4[i] = EMPTY_VALUE; } } return(rates_total); } //Thank you, friend. You have reached this stage and you can do more+
Estilos de visualización MQL5
MQL5 proporciona una amplia gama de estilos de dibujo para indicadores. Al desarrollar indicadores, el objetivo principal suele ser diseñar sistemas que puedan notificar a los usuarios mediante señales tanto sonoras como visuales. Esto ayuda a agilizar las operaciones comerciales al reducir la necesidad de que los operadores observen constantemente los gráficos, ya que la computadora se encarga de esta responsabilidad. Permítame brindarle una breve descripción general de algunos estilos de dibujo que se pueden utilizar en MQL5, como DRAW_ARROW, DRAW_LINE, DRAW_HISTOGRAM, DRAW_FILLING y DRAW_NONE. Consulte la tabla que se presenta a continuación para obtener un resumen conciso. Consulte el Manual de referencia de MQL5 para obtener información detallada sobre los estilos de dibujo.
ESTILO DE DIBUJO | DESCRIPCIÓN |
---|---|
DRAW_ARROW | Dibuja flechas en puntos específicos. A menudo se utiliza para resaltar señales de compra/venta u otros eventos importantes. |
DRAW_LINE | Se utiliza para dibujar una línea que conecta puntos de datos. Ideal para promedios móviles, líneas de tendencia y otros indicadores basados en líneas. |
DRAW_HISTOGRAM | Muestra datos como barras o histogramas. Útil para volumen, histogramas MACD y otros indicadores de tipo barra. |
DRAW_FILLING | Se utiliza para rellenar el área entre dos líneas en un gráfico, lo que proporciona una forma visualmente intuitiva de representar rangos de datos, distribuciones o diferencias entre dos indicadores. |
DRAW_NONE | Se utiliza para definir un indicador que no dibuja ninguna representación visual en el gráfico. |
Implementando el estilo DRAW_LINE en nuestro sistema
Utilicemos la función DRAW_LINE para mostrar nuestras tendencias de una manera distintiva en el gráfico de MetaTrader 5. En el pasado, logramos configurar nuestro indicador de manera efectiva para reconocer cambios de tendencia a través de cruces de promedios móviles de períodos superiores. Nuestro objetivo ahora es mejorar la forma en que presentamos la información visualmente sin saturar el gráfico con demasiados elementos. Esta nueva incorporación nos permitirá esbozar una línea única que marca tendencias y cambia automáticamente su color con cada nueva dirección. Con nuestros 4 buffers actuales, buscamos ampliar nuestras capacidades introduciendo el buffer 5 y el buffer 6 para la versión 1.04.
- Buffer 5: Para dibujar una línea azul cuando la MA de 100 está por encima de la MA de 200.
///properties #property indicator_type5 DRAW_LINE #property indicator_style5 STYLE_SOLID #property indicator_width5 2 #property indicator_color5 0xFFAA00 #property indicator_label5 "Buy Trend"
- Buffer 6: Para dibujar una línea roja cuando la MA de 100 está por debajo de la MA de 200.
#property indicator_type6 DRAW_LINE #property indicator_style6 STYLE_SOLID #property indicator_width6 2 #property indicator_color6 0x0000FF #property indicator_label6 "Sell Trend"
Código principal de Trend Constraint v1.04:
///Indicator Name: Trend Constraint #property copyright "Clemence Benjamin" #property link "https://mql5.com" #property version "1.04" #property description "A model that seek to produce sell signal when D1 candle is Bearish only and buy signal when it is Bullish" //--- indicator settings #property indicator_chart_window #property indicator_buffers 6 #property indicator_plots 6 #property indicator_type1 DRAW_ARROW #property indicator_width1 5 #property indicator_color1 0xFF3C00 #property indicator_label1 "Buy" #property indicator_type2 DRAW_ARROW #property indicator_width2 5 #property indicator_color2 0x0000FF #property indicator_label2 "Sell" #property indicator_type3 DRAW_ARROW #property indicator_width3 2 #property indicator_color3 0xE8351A #property indicator_label3 "Buy Reversal" #property indicator_type4 DRAW_ARROW #property indicator_width4 2 #property indicator_color4 0x1A1AE8 #property indicator_label4 "Sell Reversal" #property indicator_type5 DRAW_LINE #property indicator_style5 STYLE_SOLID #property indicator_width5 2 #property indicator_color5 0xFFAA00 #property indicator_label5 "Buy Trend" #property indicator_type6 DRAW_LINE #property indicator_style6 STYLE_SOLID #property indicator_width6 2 #property indicator_color6 0x0000FF #property indicator_label6 "Sell Trend" #define PLOT_MAXIMUM_BARS_BACK 5000 #define OMIT_OLDEST_BARS 50 //--- indicator buffers double Buffer1[]; double Buffer2[]; double Buffer3[]; double Buffer4[]; double Buffer5[]; double Buffer6[]; input double Oversold = 30; input double Overbought = 70; input int Slow_MA_period = 200; input int Fast_MA_period = 100; datetime time_alert; //used when sending alert input bool Audible_Alerts = true; input bool Push_Notifications = true; double myPoint; //initialized in OnInit int RSI_handle; double RSI[]; double Open[]; double Close[]; int MA_handle; double MA[]; int MA_handle2; double MA2[]; int MA_handle3; double MA3[]; int MA_handle4; double MA4[]; double Low[]; double High[]; int MA_handle5; double MA5[]; int MA_handle6; double MA6[]; void myAlert(string type, string message) { if(type == "print") Print(message); else if(type == "error") { Print(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); } else if(type == "order") { } else if(type == "modify") { } else if(type == "indicator") { if(Audible_Alerts) Alert(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); if(Push_Notifications) SendNotification(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); } } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, Buffer1); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(0, PLOT_ARROW, 241); SetIndexBuffer(1, Buffer2); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(1, PLOT_ARROW, 242); SetIndexBuffer(2, Buffer3); PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(2, PLOT_ARROW, 236); SetIndexBuffer(3, Buffer4); PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); PlotIndexSetInteger(3, PLOT_ARROW, 238); SetIndexBuffer(4, Buffer5); PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(4, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); SetIndexBuffer(5, Buffer6); PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(5, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1)); //initialize myPoint myPoint = Point(); if(Digits() == 5 || Digits() == 3) { myPoint *= 10; } RSI_handle = iRSI(NULL, PERIOD_CURRENT, 14, PRICE_CLOSE); if(RSI_handle < 0) { Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, PRICE_CLOSE); if(MA_handle < 0) { Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle2 = iMA(NULL, PERIOD_CURRENT, 400, 0, MODE_SMA, PRICE_CLOSE); if(MA_handle2 < 0) { Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle3 = iMA(NULL, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE); if(MA_handle3 < 0) { Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle4 = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_SMA, PRICE_CLOSE); if(MA_handle4 < 0) { Print("The creation of iMA has failed: MA_handle4=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle5 = iMA(NULL, PERIOD_CURRENT, Fast_MA_period, 0, MODE_SMA, PRICE_CLOSE); if(MA_handle5 < 0) { Print("The creation of iMA has failed: MA_handle5=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } MA_handle6 = iMA(NULL, PERIOD_CURRENT, Slow_MA_period, 0, MODE_SMA, PRICE_CLOSE); if(MA_handle6 < 0) { Print("The creation of iMA has failed: MA_handle6=", INVALID_HANDLE); Print("Runtime error = ", GetLastError()); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime& time[], const double& open[], const double& high[], const double& low[], const double& close[], const long& tick_volume[], const long& volume[], const int& spread[]) { int limit = rates_total - prev_calculated; //--- counting from 0 to rates_total ArraySetAsSeries(Buffer1, true); ArraySetAsSeries(Buffer2, true); ArraySetAsSeries(Buffer3, true); ArraySetAsSeries(Buffer4, true); ArraySetAsSeries(Buffer5, true); ArraySetAsSeries(Buffer6, true); //--- initial zero if(prev_calculated < 1) { ArrayInitialize(Buffer1, EMPTY_VALUE); ArrayInitialize(Buffer2, EMPTY_VALUE); ArrayInitialize(Buffer3, EMPTY_VALUE); ArrayInitialize(Buffer4, EMPTY_VALUE); ArrayInitialize(Buffer5, EMPTY_VALUE); ArrayInitialize(Buffer6, EMPTY_VALUE); } else limit++; datetime Time[]; datetime TimeShift[]; if(CopyTime(Symbol(), PERIOD_CURRENT, 0, rates_total, TimeShift) <= 0) return(rates_total); ArraySetAsSeries(TimeShift, true); int barshift_M1[]; ArrayResize(barshift_M1, rates_total); int barshift_D1[]; ArrayResize(barshift_D1, rates_total); for(int i = 0; i < rates_total; i++) { barshift_M1[i] = iBarShift(Symbol(), PERIOD_M1, TimeShift[i]); barshift_D1[i] = iBarShift(Symbol(), PERIOD_D1, TimeShift[i]); } if(BarsCalculated(RSI_handle) <= 0) return(0); if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) <= 0) return(rates_total); ArraySetAsSeries(RSI, true); if(CopyOpen(Symbol(), PERIOD_M1, 0, rates_total, Open) <= 0) return(rates_total); ArraySetAsSeries(Open, true); if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close) <= 0) return(rates_total); ArraySetAsSeries(Close, true); if(BarsCalculated(MA_handle) <= 0) return(0); if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total); ArraySetAsSeries(MA, true); if(BarsCalculated(MA_handle2) <= 0) return(0); if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total); ArraySetAsSeries(MA2, true); if(BarsCalculated(MA_handle3) <= 0) return(0); if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) <= 0) return(rates_total); ArraySetAsSeries(MA3, true); if(BarsCalculated(MA_handle4) <= 0) return(0); if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) <= 0) return(rates_total); ArraySetAsSeries(MA4, true); if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total); ArraySetAsSeries(Low, true); if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total); ArraySetAsSeries(High, true); if(BarsCalculated(MA_handle5) <= 0) return(0); if(CopyBuffer(MA_handle5, 0, 0, rates_total, MA5) <= 0) return(rates_total); ArraySetAsSeries(MA5, true); if(BarsCalculated(MA_handle6) <= 0) return(0); if(CopyBuffer(MA_handle6, 0, 0, rates_total, MA6) <= 0) return(rates_total); ArraySetAsSeries(MA6, true); if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total); ArraySetAsSeries(Time, true); //--- main loop for(int i = limit-1; i >= 0; i--) { if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation if(barshift_M1[i] < 0 || barshift_M1[i] >= rates_total) continue; if(barshift_D1[i] < 0 || barshift_D1[i] >= rates_total) continue; //Indicator Buffer 1 if(RSI[i] < Oversold && RSI[i+1] > Oversold //Relative Strength Index crosses below fixed value && Open[barshift_M1[i]] >= Close[1+barshift_D1[i]] //Candlestick Open >= Candlestick Close && MA[i] > MA2[i] //Moving Average > Moving Average && MA3[i] > MA4[i] //Moving Average > Moving Average ) { Buffer1[i] = Low[1+i]; //Set indicator value at Candlestick Low if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open time_alert = Time[1]; } else { Buffer1[i] = EMPTY_VALUE; } //Indicator Buffer 2 if(RSI[i] > Overbought && RSI[i+1] < Overbought //Relative Strength Index crosses above fixed value && Open[barshift_M1[i]] <= Close[1+barshift_D1[i]] //Candlestick Open <= Candlestick Close && MA[i] < MA2[i] //Moving Average < Moving Average && MA3[i] < MA4[i] //Moving Average < Moving Average ) { Buffer2[i] = High[1+i]; //Set indicator value at Candlestick High if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open time_alert = Time[1]; } else { Buffer2[i] = EMPTY_VALUE; } //Indicator Buffer 3 if(MA5[i] > MA6[i] && MA5[i+1] < MA6[i+1] //Moving Average crosses above Moving Average ) { Buffer3[i] = Low[i]; //Set indicator value at Candlestick Low if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Reversal"); //Alert on next bar open time_alert = Time[1]; } else { Buffer3[i] = EMPTY_VALUE; } //Indicator Buffer 4 if(MA5[i] < MA6[i] && MA5[i+1] > MA6[i+1] //Moving Average crosses below Moving Average ) { Buffer4[i] = High[i]; //Set indicator value at Candlestick High if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Reversal"); //Alert on next bar open time_alert = Time[1]; } else { Buffer4[i] = EMPTY_VALUE; } //Indicator Buffer 5 if(MA5[i] > MA6[i] //Moving Average > Moving Average ) { Buffer5[i] = MA6[i]; //Set indicator value at Moving Average if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Trend"); //Alert on next bar open time_alert = Time[1]; } else { Buffer5[i] = EMPTY_VALUE; } //Indicator Buffer 6 if(MA5[i] < MA6[i] //Moving Average < Moving Average ) { Buffer6[i] = MA6[i]; //Set indicator value at Moving Average if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Trend"); //Alert on next bar open time_alert = Time[1]; } else { Buffer6[i] = EMPTY_VALUE; } } return(rates_total); } //You are the best coder
Nuestro innovador programa ahora demuestra capacidades avanzadas al ajustar el color de una sola línea cada vez que se establece un nuevo curso. Esta funcionalidad agiliza el gráfico al incorporar color, mejorando así el sistema de señalización junto con otras notificaciones que son de naturaleza tanto visual como auditiva. Las imágenes a continuación proporcionan una representación visual del impacto de esta última característica.
Fig. 2: Trend Constraint V1.04 en USDJPY.
Fig. 3: Trend Constraint V1.04 en el índice Boom 500.
Mi estado de la vela D1
Para agregar una nueva característica a nuestro modelo, queremos verificar rápidamente el estado de la vela D1 tan pronto como cambiemos a MetaTrader 5 y comencemos a usar nuestro modelo. He decidido incorporar un script aquí que muestra el estado de la vela D1 en el gráfico, incluso si el gráfico está en períodos de tiempo distintos de D1. Esta mejora ayuda a identificar rápidamente el estado de la vela, especialmente cuando se trabaja en períodos de tiempo M1, donde los separadores de períodos D1 pueden no ser visibles en ciertos niveles de zoom. Ahora, examinemos el código del script MQL5 que se muestra a continuación:
//My_D1_candlestatus.mql5 //Author: Clemence Benjamin //Link: https://www.mql5.com/en/users/billionaire2024/seller #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property script_show_inputs #property strict //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- Get the opening and closing prices of the current D1 candle double openPrice = iOpen(NULL, PERIOD_D1, 0); double closePrice = iClose(NULL, PERIOD_D1, 0); //--- Determine if the candle is bullish or bearish string candleStatus; if(closePrice > openPrice) { candleStatus = " D1 candle is bullish."; } else if(closePrice < openPrice) { candleStatus = " D1 candle is bearish."; } else { candleStatus = " D1 candle is neutral.";// when open price is equal to close price } //--- Print the status on the chart Comment(candleStatus); //--- Also print the status in the Experts tab for logging Print(candleStatus); } //+------------------------------------------------------------------+
Comprensión de las funciones y variables del script My_D1_Candlestatus.mq5
Funciones y variables | Descripción |
---|---|
OnStart() | Esta es la función principal del script que se ejecuta cuando se ejecuta el script. Recupera los precios de apertura y cierre de la vela D1 actual, determina si la vela es alcista, bajista o neutral y luego muestra esta información en el gráfico usando Comment(). |
iOpen() y iClose() | Estas funciones recuperan los precios de apertura y cierre de la vela D1 actual. |
candleStatus | Una variable string para almacenar el mensaje de estado de la vela D1 actual. |
Comment() | Esta función muestra el mensaje de estado en el gráfico. |
Print() | Esta función registra el mensaje de estado en la pestaña "Expertos" para un registro adicional. |
Una vez que hayas terminado de compilar el código, podrás localizar el script y ejecutarlo siguiendo las instrucciones proporcionadas en la ilustración. El script mostrará un comentario que indica el estado de la vela del día actual.
Fig. 4: Ejecución del script My_D1_candlestatus.mq5.
Otras alternativas a los estilos de dibujo de MQL5
MetaTrader 5 viene con una amplia gama de ayudas de dibujo para la evaluación práctica del mercado, como líneas, canales y figuras, todos convenientemente ubicados en la plataforma Meta Trader. Al profundizar en el conocimiento del lenguaje de programación orientado a objetos MQL5 y sus conexiones con Python y C++, los operadores tienen la capacidad de idear ayudas y ampliaciones personalizadas. Los operadores pueden aprovechar estas herramientas para mejorar sus capacidades de análisis técnico y tomar decisiones de negociación más informadas. Con la flexibilidad y las opciones de personalización disponibles en MetaTrader 5, los operadores tienen la oportunidad de adaptar su experiencia de trading a sus preferencias y estrategias.
Conclusión
Hemos integrado con éxito una nueva función en nuestro programa, obteniendo resultados positivos que tienen el potencial de influir en la próxima versión a medida que pasemos de un indicador a un EA en artículos posteriores. Los estilos de dibujo de MQL5 presentan notables ventajas para los operadores, ya que mejoran la claridad, la precisión y la personalización de la visualización de datos. Estos estilos refuerzan las capacidades de análisis técnico, facilitan técnicas avanzadas de elaboración de gráficos y admiten actualizaciones interactivas en tiempo real. Además, la flexibilidad y creatividad que ofrecen los estilos de dibujo de MQL5 permiten a los operadores crear indicadores y herramientas analíticas distintivos, enriqueciendo sus planteamientos de negociación y su comprensión general del mercado.
Nuestro modelo evoluciona con refinada precisión, ofreciendo perspectivas visuales instantáneas con sólo pulsar un botón. El script transmite rápidamente el estado de la vela D1, mientras que la función DRAW_LINE acentúa las tendencias en un marco temporal inferior de forma comprensible. He incluido los archivos fuente de todas las funciones que se tratan aquí. Confío en que sigan los progresos y adquieran nuevos conocimientos; no duden en compartir sus comentarios y participar en los debates.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/14899





- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso