
Construindo um Modelo de Restrição de Tendência de Candlestick (Parte 4): Personalizando o Estilo de Exibição para Cada Onda de Tendência
Conteúdo
- Introdução
- Recapitulação
- Estilos de Exibição do MQL5
- Implementando o estilo DRAW_LINE em nosso sistema.
- Status do Meu Candle D1
- Entendendo as funções e variáveis de My_D1_Candlestatus.mq5
- Outras alternativas para os estilos de exibição MQL5
- Conclusão
Introdução
Estilos de exibição personalizados podem melhorar o apelo visual dos gráficos, tornando-os mais atraentes e fáceis de ler. Um gráfico bem projetado pode melhorar a experiência do usuário e reduzir a fadiga ocular durante longas sessões de negociação. Ao adaptar os estilos de exibição para necessidades específicas, os traders podem criar configurações de negociação mais eficientes e eficazes. Por exemplo, usar histogramas para representar dados de volume ou linhas para médias móveis pode facilitar a interpretação desses indicadores de forma rápida. Estilos de exibição como setas ou símbolos podem ser usados para marcar eventos específicos ou sinais no gráfico, como pontos de compra/venda, tornando mais fácil identificar oportunidades de negociação.
O MQL5 possui uma variedade de estilos de desenho para indicadores no MetaTrader 5. Esses elementos visuais fornecem aos traders uma vantagem analítica quando apresentados no gráfico do MetaTrader 5, ajudando na rápida adaptação ao sentimento do mercado. Incorporar esses diversos estilos de desenho não apenas melhora o apelo estético dos gráficos, mas também permite que os traders tomem decisões informadas com base em uma análise abrangente da dinâmica do mercado. Os traders podem interpretar movimentos de preços, identificar tendências e antecipar possíveis reversões com maior precisão. O MQL5 é rico com 18 tipos de gráficos. Neste artigo, queremos nos aprofundar e explorar como implementar um desses estilos de exibição em nosso modelo.
Em vez de apenas desenhar uma seta para nosso alerta, queremos criar um visual mais avançado no gráfico para torná-lo ainda mais fácil de entender. Lembre-se de que, nesta série, nosso objetivo é refinar nosso modelo de Restrição de Tendência para que ele siga o sentimento da forma do nosso candlestick D1 e apresente sinais visuais abrangentes no gráfico. Os estilos de desenho do MQL5 podem ser personalizados em termos de cor, espessura e estilo (por exemplo, linhas tracejadas ou sólidas), ajudando os traders a personalizarem seus gráficos de acordo com suas preferências e melhorarem a legibilidade. Estilos de exibição diferentes permitem que os traders representem dados de forma mais clara e precisa. Por exemplo, usar linhas, histogramas ou candles pode facilitar a interpretação de movimentos de preços e tendências de mercado.
Os vários estilos de desenho disponíveis no MQL5 oferecem aos traders inúmeras vantagens. Eles ajudam a melhorar a clareza, precisão e personalização da visualização de dados. Esses estilos diversos expandem as capacidades da análise técnica, permitindo o uso de técnicas avançadas de criação de gráficos e facilitando atualizações dinâmicas em tempo real. Além disso, a adaptabilidade e engenhosidade inerentes aos estilos de desenho do MQL5 permitem que os traders criem indicadores e instrumentos de análise exclusivos, ampliando assim suas estratégias de negociação e a compreensão do cenário de mercado. Para um entendimento completo deste tópico, consulte a Referência MQL5 para uma exploração detalhada dos estilos de desenho.
Recapitulação
Nos artigos anteriores desta série (Parte 1, Parte 2 e Parte 3), o objetivo foi alinhar cada sinal ao sentimento do candle D1. O conceito é que, se o candle D1 for altista, normalmente a tendência geral do dia será de alta em prazos menores. Utilizando métodos analíticos avançados em prazos menores, podemos identificar pontos de entrada e gerar sinais que estejam alinhados com a tendência atual. Com cada fase, aprimoramos nosso código-fonte, incorporando novos recursos e melhorando nosso modelo. Na série de artigos, utilizamos setas como elemento de design para cada iteração do nosso indicador, explorando a utilização da fonte Wingdings para elementos de exibição opcionais.
Adicionamos médias móveis de 200 e 100 a um ativo no gráfico do MQL5 para traçar estratégias. Analisando o comportamento desses indicadores embutidos, identificamos um evento significativo de cruzamento periódico. Subsequentemente, foi criado um indicador de cruzamento personalizado com um sistema de alerta para nos notificar sobre essas ocorrências, indicando uma possível reversão de tendência. Ajustar os valores das MAs para níveis mais altos pode ajudar a filtrar sinais durante as flutuações do mercado. Na Parte 3, aperfeiçoei ainda mais a abordagem, introduzindo entrada de período MA personalizável para explorar vários valores de período e determinar a configuração ideal para reversões de tendência.
input int Slow_MA_period = 200; input int Fast_MA_period = 100;
O software oferece a capacidade de ajuste instantâneo das configurações de entrada exibidas na representação visual. Para modificar seus atributos, utilize a combinação de teclas Ctrl + I ao visualizar o gráfico do MetaTrader 5 ou simplesmente clique com o botão direito do mouse para revelar o menu do indicador e localize Trend Constraint V1.03.
Fig 1: Otimizando o período da MA para as melhores configurações de reversão de tendência.
Após compilar o programa usando essas configurações de entrada, você encontrará o documento-fonte anexado logo abaixo da conclusão deste artigo. A seguir, apresentamos o código mais recente para 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. Você chegou a este estágio e pode fazer mais+
Estilos de Exibição do MQL5
O MQL5 oferece uma ampla gama de estilos de desenho para indicadores. Ao desenvolver indicadores, o objetivo principal geralmente é projetar sistemas que possam notificar os usuários por meio de alertas sonoros e visuais. Isso ajuda a simplificar as operações de negociação, reduzindo a necessidade de os traders monitorarem constantemente os gráficos, pois o computador cuida dessa responsabilidade. Vou dar uma breve visão geral de alguns estilos de desenho que podem ser utilizados no MQL5, como DRAW_ARROW, DRAW_LINE, DRAW_HISTOGRAM, DRAW_FILLING e DRAW_NONE. Consulte a tabela apresentada abaixo para um resumo conciso. Consulte a Referência MQL5 para informações detalhadas sobre os estilos de desenho.
ESTILO DE DESENHO | DESCRIÇÃO |
---|---|
DRAW_ARROW | Desenha setas em pontos específicos. Frequentemente usado para destacar sinais de compra/venda ou outros eventos importantes. |
DRAW_LINE | Usado para desenhar uma linha conectando pontos de dados. Ideal para médias móveis, linhas de tendência e outros indicadores baseados em linhas. |
DRAW_HISTOGRAM | Exibe os dados como barras ou histogramas. Útil para volume, histogramas MACD e outros indicadores de tipo de barra. |
DRAW_FILLING | Usado para preencher a área entre duas linhas em um gráfico, fornecendo uma forma visualmente intuitiva de representar intervalos de dados, spread ou diferenças entre dois indicadores. |
DRAW_NONE | Usado para definir um indicador que não desenha nenhuma representação visual no gráfico. |
Implementando o estilo DRAW_LINE em nosso sistema.
Vamos utilizar a função DRAW_LINE para exibir nossas tendências de uma forma distinta no gráfico do MetaTrader 5. No passado, conseguimos configurar nosso indicador de forma eficaz para reconhecer reversões de tendência através dos cruzamentos de médias móveis de período mais alto. Nosso objetivo agora é melhorar a forma como apresentamos as informações visualmente, sem sobrecarregar o gráfico com muitos elementos. Essa nova adição nos permitirá desenhar uma linha única que mostra as tendências e altera automaticamente sua cor a cada nova direção. Com nossos atuais 4 buffers, estamos procurando ampliar nossas capacidades introduzindo o buffer 5 e o buffer 6 para a versão 1.04.
- Buffer 5: Para desenhar uma linha azul quando MA 100 está acima da MA 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 desenhar uma linha vermelha quando MA 100 está abaixo da MA 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 para 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
Nosso programa inovador agora demonstra capacidades avançadas, ajustando a cor de uma única linha sempre que um novo curso é estabelecido. Essa funcionalidade simplifica o gráfico ao incorporar cores, melhorando assim o sistema de sinalização juntamente com outras notificações que são visuais e sonoras. As imagens abaixo fornecem uma representação visual do impacto desse último recurso.
Fig 2: Trend Constraint V1.04 on USDJPY
Fig 3: Trend Constraint V1.04 on Boom 500 index
Status do Meu Candle D1
Para adicionar um novo recurso ao nosso modelo, queremos verificar rapidamente o status do candlestick D1 assim que mudarmos para o MetaTrader 5 e começarmos a usar nosso modelo. Decidi incluir um script aqui que mostra o status do candle D1 no gráfico, mesmo que o gráfico esteja em prazos diferentes de D1. Essa melhoria ajuda a identificar rapidamente o status do candle, especialmente ao trabalhar em prazos de M1, onde os separadores de período D1 podem não estar visíveis em certos níveis de zoom. Agora, vamos examinar o código do script MQL5 apresentado abaixo:
//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); } //+------------------------------------------------------------------+
Entendendo as funções e variáveis do Script My_D1_Candlestatus.mq5
Funções e Variáveis | Descrição |
---|---|
OnStart() | Esta é a função principal do script que é executada quando o script é acionado. Ela recupera os preços de abertura e fechamento do candle D1 atual, determina se o candle é altista, baixista ou neutro e, em seguida, exibe essa informação no gráfico usando Comment(). |
iOpen() and iClose() | Essas funções recuperam os preços de abertura e fechamento do candle D1 atual. |
candleStatus | Uma variável string para armazenar a mensagem de status do candle D1 atual. |
Comment() | Essa função exibe a mensagem de status no gráfico. |
Print() | Essa função registra a mensagem de status na aba "Experts" para log adicional. |
Após compilar o código, você poderá localizar o script e executá-lo seguindo as instruções fornecidas na ilustração. O script exibirá um comentário que mostra o status do candle do dia atual.
Fig 4: Executando o script My_D1_candlestatus.mq5
Outras alternativas para os estilos de desenho MQL5
O MetaTrader 5 vem com uma ampla variedade de ferramentas de esboço para avaliação prática do mercado, como linhas, canais e figuras, todas convenientemente localizadas na plataforma MetaTrader. Ao explorar um conhecimento profundo da linguagem de Programação Orientada a Objetos MQL5 e suas conexões com Python e C++, os traders têm a capacidade de criar ferramentas personalizadas e expansões Os traders podem aproveitar essas ferramentas para melhorar suas capacidades de análise técnica e tomar decisões de negociação mais informadas. Com as opções de flexibilidade e personalização disponíveis no MetaTrader 5, os traders têm a oportunidade de adaptar sua experiência de negociação para atender às suas preferências e estratégias.
Conclusão
Integrámos com sucesso um novo recurso em nosso programa, resultando em resultados positivos que têm o potencial de influenciar a próxima versão, à medida que progredimos de um indicador para um EA em artigos subsequentes. Os estilos de desenho no MQL5 apresentam benefícios notáveis para os traders, melhorando a clareza, precisão e personalização da visualização de dados. Esses estilos fortalecem as capacidades de análise técnica, facilitam técnicas avançadas de criação de gráficos e suportam atualizações interativas em tempo real. Além disso, a flexibilidade e a criatividade proporcionadas pelos estilos de desenho MQL5 permitem que os traders criem indicadores e ferramentas de análise distintas, enriquecendo suas abordagens de negociação e a compreensão geral do mercado.
Nosso modelo está evoluindo com precisão refinada, oferecendo percepções visuais instantâneas com o clique de um botão. O script transmite prontamente o status do candle D1, enquanto o recurso DRAW_LINE destaca as tendências em um prazo menor de forma compreensível. Incluí os arquivos de origem para todos os recursos discutidos aqui. Confio que você está acompanhando o progresso e adquirindo conhecimentos; sinta-se à vontade para compartilhar seus comentários e participar das discussões.
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/14899
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.





- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Confira o novo artigo: Construindo um modelo de restrição de tendência de candlestick (Parte 4): Personalização do estilo de exibição para cada onda de tendência.
Autor: Clemence Benjamin