Desenvolvimento de um conjunto de ferramentas de Análise de Price Action (Parte 18): Introduzindo a Teoria dos Quarters (III) — Quarters Board
Conteúdo
Introdução
Em nossa introdução à Teoria dos Quarters, começamos com o script Quarters Drawer, que é seu primeiro componente. Este script automatiza o desenho dos níveis de quarter em um gráfico e apresenta alternâncias Booleanas para controlar a visibilidade de cada nível.
input bool DrawLargeQuarters = true; // Draw intermediate large quarter lines. input bool DrawSmallQuarters = false; // Draw small quarter lines. input bool DrawOvershootAreas = true; // Mark overshoot/undershoot areas for large quarter lines.
Por exemplo, definir DrawSmallQuarters como true exibe as linhas de quarter menores, enquanto definir DrawLargeQuarters como false oculta as linhas de quarters maiores. A mesma abordagem se aplica aos níveis de Overshoots and Undershoots. Essa funcionalidade permite que você se concentre em níveis específicos, mantendo o gráfico limpo e sem poluição visual. Se você quiser visualizar todos os níveis, basta habilitar todas as alternâncias.
Você já achou tedioso precisar voltar repetidamente ao código apenas para alternar uma configuração? Neste artigo, apresentamos o Quarters Board, uma ferramenta aprimorada que permite alternar automaticamente sinalizadores bookleanos para ligado ou desligado com um único clique de botão no gráfico em tempo real. Em vez de editar o código para alterar a flag DrawSmallQuarters, agora você pode fazer ajustes diretamente no gráfico, simplificando o processo para qualquer trader. Por exemplo, se você quiser visualizar apenas os quarters maiores, isso pode ser feito com um simples clique sem qualquer complicação.
Visão Geral
Como mencionado na introdução, esta ferramenta permite alternar quais níveis aparecem no gráfico sem a necessidade de retornar ao código para editar um sinalizador booleano. O Quarter Board é um expert advisor que apresenta quatro botões: Large Quarters, Small Quarters, Overshoot/Undershoot e Trend Direction. Ao pressionar qualquer botão, o nível correspondente é alternado: o texto do botão fica verde quando o nível está ativo e vermelho quando está desativado.
O botão Trend Direction é um recurso adicional que fornece sinais de mercado em tempo real. Com apenas um clique, ele calcula uma média móvel simples de 50 períodos e a compara com o preço atual do mercado, ajudando você a determinar rapidamente se o mercado está em tendência de alta, baixa ou se está se movendo lateralmente. O botão até muda de cor para indicar seu status ativo, fornecendo um método claro e amigável para monitorar tendências de mercado diretamente no seu gráfico. Vejamos a seção seguinte para entender a lógica central por trás da funcionalidade do nosso EA.
Lógica
Este EA foi projetado para ser ao mesmo tempo fácil de usar e altamente adaptável. As configurações facilitam a personalização, a interface é limpa e bem organizada, e os controles baseados em botões garantem uma interação fluida. Ao lidar automaticamente com a adição e remoção das linhas de quarter, o EA mantém o gráfico organizado e focado em níveis de preço relevantes. O comentário de tendência em tempo real adiciona outra camada de sinais, ajudando os traders a avaliar rapidamente a direção do mercado sem poluir a tela. Com ferramentas visuais e analíticas trabalhando juntas, este EA simplifica as decisões de negociação enquanto mantém tudo intuitivo e eficiente.
Configuração e estrutura globais
O EA começa definindo parâmetros-chave que determinam como os níveis de preço e os elementos do gráfico serão exibidos. Configurações de entrada permitem que os traders personalizem valores como o espaçamento entre níveis principais de preço e as cores usadas para diferentes linhas. Essas configurações fornecem flexibilidade, permitindo que os usuários modifiquem a aparência do EA sem alterar sua lógica central. O código também inclui várias variáveis booleanas globais que atuam como interruptores, habilitando ou desabilitando recursos específicos como linhas de quarter maiores ou comentários de tendência. Macros são usadas para atribuir nomes consistentes aos objetos do gráfico, garantindo que cada elemento seja referenciado de forma uniforme em todo o script. Organizar essas configurações em um único local facilita o ajuste de parâmetros e a resolução de problemas sem precisar procurar em várias seções do código.#property copyright "Christian Benjamin" #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict //---- Input parameters for drawing levels ---------------------------- input double MajorStep = 0.1000; // Difference between major whole numbers //---- Color settings --------------------------------------------------- input color MajorColor = 0x2F4F4F; // Dark Slate Gray for major lines. input color LargeQuarterColor = 0x8B0000; // Dark Red for large quarter lines. input color SmallQuarterColor = 0x00008B; // Dark Blue for small quarter lines. input color OvershootColor = clrRed; // Red for overshoot/undershoot lines. //---- Line styles and thickness settings ----------------------------- input ENUM_LINE_STYLE MajorLineStyle = STYLE_SOLID; input int MajorLineWidth = 4; input ENUM_LINE_STYLE LargeQuarterLineStyle = STYLE_DOT; input int LargeQuarterLineWidth = 3; input ENUM_LINE_STYLE OvershootLineStyle = STYLE_DASH; input int OvershootLineWidth = 1; input ENUM_LINE_STYLE SmallQuarterLineStyle = STYLE_SOLID; input int SmallQuarterLineWidth = 1; //---- Panel and button settings -------------------------------------- input int PanelX = 10; input int PanelY = 10; input int PanelWidth = 250; input int ButtonHeight = 30; input int ButtonSpacing= 5; //---- Global toggle variables ---------------------------------------- bool g_DrawLargeQuarters = true; bool g_DrawSmallQuarters = false; bool g_DrawOvershootAreas = true; bool g_DrawTrendDirection = false; //---- Object names for panel and buttons ----------------------------- #define PANEL_NAME "LevelsPanel" #define BUTTON_LARGE "btnLargeQuarters" #define BUTTON_SMALL "btnSmallQuarters" #define BUTTON_OVERSHOOT "btnOvershoot" #define BUTTON_TREND "btnTrendDirection" #define TREND_LABEL "TrendDirectionLabel"
Inicialização de Painel e Botão
Uma vez definida a configuração, o EA constrói a interface do usuário. Um painel de fundo é criado para agrupar todos os botões, proporcionando um layout estruturado. O painel é simulado usando um rótulo retangular, com suas dimensões ajustadas por meio da modificação das propriedades de texto. Os botões são então posicionados em relação ao painel, garantindo espaçamento e alinhamento adequados.
Esses botões permitem que os traders alternem recursos como quarters maiores, quarters menores, áreas de overshoot e comentários de direção de tendência. Cada botão recebe uma largura e altura consistentes, criando uma aparência limpa e organizada. A configuração facilita a interação dos usuários com o EA, pois eles podem ativar ou desativar elementos específicos com um único clique. Ao manter um layout uniforme, o EA garante que todos os controles sejam facilmente acessíveis e visualmente distintos.
void CreatePanel() { if(ObjectCreate(0, PANEL_NAME, OBJ_RECTANGLE_LABEL, 0, 0, 0)) { ObjectSetInteger(0, PANEL_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, PANEL_NAME, OBJPROP_XDISTANCE, PanelX); ObjectSetInteger(0, PANEL_NAME, OBJPROP_YDISTANCE, PanelY); ObjectSetInteger(0, PANEL_NAME, OBJPROP_COLOR, clrDarkGray); ObjectSetString(0, PANEL_NAME, OBJPROP_TEXT, "\n\n\n\n"); ObjectSetInteger(0, PANEL_NAME, OBJPROP_BORDER_TYPE, BORDER_RAISED); } }
Tratamento de Interações do Usuário
A interação do usuário é um aspecto crucial do EA, gerenciada por meio de um sistema de tratamento de eventos. O script escuta eventos do gráfico, verificando especificamente se um botão foi clicado. Quando um botão é pressionado, o sistema identifica qual função deve ser ativada ao corresponder o nome do botão. Uma vez identificado, o recurso correspondente é ativado ou desativado. Por exemplo, pressionar o botão de quarters large alterna entre mostrar e ocultar esses níveis de preço.
Para melhorar a experiência do usuário, as cores dos botões são atualizadas imediatamente, fornecendo feedback visual claro—botões ativos podem ficar verdes, enquanto os inativos permanecem vermelhos. Esse sistema garante que cada recurso opere de forma independente, evitando conflitos e tornando a ferramenta responsiva à entrada do usuário em tempo real. Ao estruturar o tratamento de eventos de forma eficiente, o EA permanece estável e fácil de usar, mesmo em condições de mercado dinâmicas.
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { if(sparam == BUTTON_LARGE) { g_DrawLargeQuarters = !g_DrawLargeQuarters; UpdateButtonColors(); DrawQuarterLines(); } else if(sparam == BUTTON_TREND) { g_DrawTrendDirection = !g_DrawTrendDirection; UpdateButtonColors(); if(g_DrawTrendDirection) UpdateTrendComment(); else DeleteTrendComment(); } // Similar handling for other buttons... } }
Desenhando e Removendo Quarter Lines
Uma das funções principais do EA é plotar níveis de preço no gráfico. O processo começa determinando o preço atual do mercado e calculando os limites-chave de preço. Os níveis principais são sempre desenhados, enquanto níveis adicionais como quarters maiores, quarters menores e zonas de overshoot são exibidos apenas se seus respectivos botões estiverem habilitados. Para manter o gráfico limpo, o EA primeiro remove quaisquer linhas previamente desenhadas antes de posicionar novas.
Isso evita que linhas sobrepostas ou desatualizadas poluam a exibição. Cada método de divisão em quarters segue um cálculo estruturado, garantindo que os níveis de preço estejam corretamente alinhados. Se um recurso for desativado, o script remove as linhas correspondentes, dando aos traders controle total sobre o que é exibido. Essa abordagem garante que o gráfico permaneça organizado e forneça apenas as informações mais relevantes com base nas preferências do usuário.
void DrawQuarterLines() { DeleteQuarterLines(); double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double lowerMajor = MathFloor(currentPrice / MajorStep) * MajorStep; DrawHorizontalLine("MajorLower", lowerMajor, MajorColor, MajorLineWidth, MajorLineStyle); if(g_DrawLargeQuarters) { double LQIncrement = MajorStep / 4.0; for(int i = 1; i < 4; i++) { double level = lowerMajor + i * LQIncrement; DrawHorizontalLine("LargeQuarter_" + IntegerToString(i), level, LargeQuarterColor, LargeQuarterLineWidth, LargeQuarterLineStyle); // Overshoot/Undershoot handling... } } // Additional code for small quarters... }
Exibição de Comentário de Tendência
Além dos elementos gráficos, o EA também fornece aos traders uma análise textual das tendências do mercado. Ele calcula uma média móvel simples (SMA) ao longo de um período definido e a compara com o preço atual. Se o preço estiver acima da SMA, a tendência é considerada de alta; se estiver abaixo, a tendência é de baixa. Se houver pouca movimentação em torno da SMA, o mercado é classificado como neutro. Essa análise é exibida como um rótulo de texto no gráfico, posicionado logo abaixo do botão Trend Direction para garantir visibilidade sem interferir com outros elementos. O comentário é atualizado dinamicamente, fornecendo insights em tempo real à medida que as condições de mercado evoluem. Esse recurso complementa o sistema gráfico de divisão em quarters ao oferecer aos traders uma camada adicional de análise, ajudando-os a tomar decisões mais informadas.
void UpdateTrendComment() { double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double smaValue = 0.0; int handle = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_SMA, PRICE_CLOSE); if(handle != INVALID_HANDLE) { double buffer[]; if(CopyBuffer(handle, 0, 1, 1, buffer) > 0) smaValue = buffer[0]; IndicatorRelease(handle); } string trendComment = (currentPrice > smaValue) ? "Uptrend" : (currentPrice < smaValue) ? "Downtrend" : "Sideways"; int trendLabelY = PanelY + 10 + 3 * (ButtonHeight + ButtonSpacing) + ButtonHeight + ButtonSpacing; if(ObjectFind(0, TREND_LABEL) == -1) { ObjectCreate(0, TREND_LABEL, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, TREND_LABEL, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, TREND_LABEL, OBJPROP_XDISTANCE, PanelX + 10); ObjectSetInteger(0, TREND_LABEL, OBJPROP_YDISTANCE, trendLabelY); ObjectSetInteger(0, TREND_LABEL, OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, TREND_LABEL, OBJPROP_FONTSIZE, 14); } ObjectSetString(0, TREND_LABEL, OBJPROP_TEXT, "Trend Direction: " + trendComment); }
Código completo do EA
//+------------------------------------------------------------------+ //| Quarters Board EA.mq5| //| Copyright 2025, Christian Benjamin| //| https://www.mql5.com/en/users/lynnchris| //+------------------------------------------------------------------+ #property copyright "Christian Benjamin" #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict //---- Input parameters for drawing levels ---------------------------- input double MajorStep = 0.1000; // Difference between major whole numbers //---- Color settings --------------------------------------------------- input color MajorColor = 0x2F4F4F; // Dark Slate Gray for major lines. input color LargeQuarterColor = 0x8B0000; // Dark Red for large quarter lines. input color SmallQuarterColor = 0x00008B; // Dark Blue for small quarter lines. input color OvershootColor = clrRed; // Red for overshoot/undershoot lines. //---- Line styles and thickness settings ----------------------------- input ENUM_LINE_STYLE MajorLineStyle = STYLE_SOLID; input int MajorLineWidth = 4; input ENUM_LINE_STYLE LargeQuarterLineStyle = STYLE_DOT; input int LargeQuarterLineWidth = 3; input ENUM_LINE_STYLE OvershootLineStyle = STYLE_DASH; input int OvershootLineWidth = 1; input ENUM_LINE_STYLE SmallQuarterLineStyle = STYLE_SOLID; input int SmallQuarterLineWidth = 1; //---- Panel and button settings -------------------------------------- input int PanelX = 10; input int PanelY = 10; input int PanelWidth = 250; input int ButtonHeight = 30; input int ButtonSpacing= 5; //---- Global toggle variables ---------------------------------------- bool g_DrawLargeQuarters = true; bool g_DrawSmallQuarters = false; bool g_DrawOvershootAreas = true; bool g_DrawTrendDirection = false; //---- Object names for panel and buttons ----------------------------- #define PANEL_NAME "LevelsPanel" #define BUTTON_LARGE "btnLargeQuarters" #define BUTTON_SMALL "btnSmallQuarters" #define BUTTON_OVERSHOOT "btnOvershoot" #define BUTTON_TREND "btnTrendDirection" #define TREND_LABEL "TrendDirectionLabel" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Create panel background and buttons CreatePanel(); CreateButtons(); // Draw quarter lines initially DrawQuarterLines(); // If trend commentary is toggled on, update it if(g_DrawTrendDirection) UpdateTrendComment(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Delete panel, buttons, quarter lines, and trend commentary ObjectDelete(0, PANEL_NAME); ObjectDelete(0, BUTTON_LARGE); ObjectDelete(0, BUTTON_SMALL); ObjectDelete(0, BUTTON_OVERSHOOT); ObjectDelete(0, BUTTON_TREND); DeleteQuarterLines(); DeleteTrendComment(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Redraw quarter lines on every tick DrawQuarterLines(); // Update trend commentary if enabled if(g_DrawTrendDirection) UpdateTrendComment(); } //+------------------------------------------------------------------+ //| Chart event function to catch button clicks | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { if(sparam == BUTTON_LARGE) { g_DrawLargeQuarters = !g_DrawLargeQuarters; UpdateButtonColors(); DrawQuarterLines(); } else if(sparam == BUTTON_SMALL) { g_DrawSmallQuarters = !g_DrawSmallQuarters; UpdateButtonColors(); DrawQuarterLines(); } else if(sparam == BUTTON_OVERSHOOT) { g_DrawOvershootAreas = !g_DrawOvershootAreas; UpdateButtonColors(); DrawQuarterLines(); } else if(sparam == BUTTON_TREND) { g_DrawTrendDirection = !g_DrawTrendDirection; UpdateButtonColors(); if(g_DrawTrendDirection) UpdateTrendComment(); else DeleteTrendComment(); } } } //+------------------------------------------------------------------+ //| Create panel background | //+------------------------------------------------------------------+ void CreatePanel() { if(ObjectCreate(0, PANEL_NAME, OBJ_RECTANGLE_LABEL, 0, 0, 0)) { ObjectSetInteger(0, PANEL_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, PANEL_NAME, OBJPROP_XDISTANCE, PanelX); ObjectSetInteger(0, PANEL_NAME, OBJPROP_YDISTANCE, PanelY); ObjectSetInteger(0, PANEL_NAME, OBJPROP_COLOR, clrDarkGray); // Simulate a larger panel using newlines in the text. string panelText = "\n\n\n\n"; ObjectSetString(0, PANEL_NAME, OBJPROP_TEXT, panelText); ObjectSetInteger(0, PANEL_NAME, OBJPROP_BORDER_TYPE, BORDER_RAISED); } } //+------------------------------------------------------------------+ //| Create buttons on the panel | //+------------------------------------------------------------------+ void CreateButtons() { int x = PanelX + 10; int y = PanelY + 10; int btnWidth = PanelWidth - 20; // Button for Large Quarters if(!ObjectCreate(0, BUTTON_LARGE, OBJ_BUTTON, 0, 0, 0)) Print("Failed to create button ", BUTTON_LARGE); else { ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_XSIZE, btnWidth); ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_YSIZE, ButtonHeight); ObjectSetString(0, BUTTON_LARGE, OBJPROP_TEXT, "Large Quarters"); } // Button for Smaller Quarters y += ButtonHeight + ButtonSpacing; if(!ObjectCreate(0, BUTTON_SMALL, OBJ_BUTTON, 0, 0, 0)) Print("Failed to create button ", BUTTON_SMALL); else { ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_XSIZE, btnWidth); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_YSIZE, ButtonHeight); ObjectSetString(0, BUTTON_SMALL, OBJPROP_TEXT, "Smaller Quarters"); } // Button for Overshoot/Undershoot y += ButtonHeight + ButtonSpacing; if(!ObjectCreate(0, BUTTON_OVERSHOOT, OBJ_BUTTON, 0, 0, 0)) Print("Failed to create button ", BUTTON_OVERSHOOT); else { ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_XSIZE, btnWidth); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_YSIZE, ButtonHeight); ObjectSetString(0, BUTTON_OVERSHOOT, OBJPROP_TEXT, "Overshoot/Undershoot"); } // Button for Trend Direction y += ButtonHeight + ButtonSpacing; if(!ObjectCreate(0, BUTTON_TREND, OBJ_BUTTON, 0, 0, 0)) Print("Failed to create button ", BUTTON_TREND); else { ObjectSetInteger(0, BUTTON_TREND, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_XSIZE, btnWidth); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_YSIZE, ButtonHeight); ObjectSetString(0, BUTTON_TREND, OBJPROP_TEXT, "Trend Direction"); } UpdateButtonColors(); } //+------------------------------------------------------------------+ //| Update button colors based on toggle state | //+------------------------------------------------------------------+ void UpdateButtonColors() { color onColor = clrGreen; color offColor = clrRed; ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_COLOR, g_DrawLargeQuarters ? onColor : offColor); ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_COLOR, g_DrawSmallQuarters ? onColor : offColor); ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_COLOR, g_DrawOvershootAreas ? onColor : offColor); ObjectSetInteger(0, BUTTON_TREND, OBJPROP_COLOR, g_DrawTrendDirection ? onColor : offColor); } //+------------------------------------------------------------------+ //| Delete quarter lines | //+------------------------------------------------------------------+ void DeleteQuarterLines() { ObjectDelete(0, "MajorLower"); ObjectDelete(0, "MajorUpper"); for(int i = 1; i < 4; i++) { ObjectDelete(0, "LargeQuarter_" + IntegerToString(i)); ObjectDelete(0, "Overshoot_" + IntegerToString(i) + "_up"); ObjectDelete(0, "Undershoot_" + IntegerToString(i) + "_down"); } for(int seg = 0; seg < 10; seg++) { for(int j = 1; j < 4; j++) { ObjectDelete(0, "SmallQuarter_" + IntegerToString(seg) + "_" + IntegerToString(j)); } } } //+------------------------------------------------------------------+ //| Delete trend commentary | //+------------------------------------------------------------------+ void DeleteTrendComment() { ObjectDelete(0, TREND_LABEL); } //+------------------------------------------------------------------+ //| Update trend commentary | //+------------------------------------------------------------------+ void UpdateTrendComment() { double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); if(currentPrice == 0) return; double smaValue = 0.0; double buffer[]; int handle = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_SMA, PRICE_CLOSE); if(handle != INVALID_HANDLE) { if(CopyBuffer(handle, 0, 1, 1, buffer) > 0) smaValue = buffer[0]; IndicatorRelease(handle); } string trendComment; if(currentPrice > smaValue) trendComment = "Uptrend"; else if(currentPrice < smaValue) trendComment = "Downtrend"; else trendComment = "Sideways"; // Calculate the position for the commentary label below the Trend Direction button int trendButtonY = PanelY + 10 + 3 * (ButtonHeight + ButtonSpacing); int trendLabelY = trendButtonY + ButtonHeight + ButtonSpacing; int trendLabelX = PanelX + 10; if(ObjectFind(0, TREND_LABEL) == -1) { ObjectCreate(0, TREND_LABEL, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, TREND_LABEL, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, TREND_LABEL, OBJPROP_XDISTANCE, trendLabelX); ObjectSetInteger(0, TREND_LABEL, OBJPROP_YDISTANCE, trendLabelY); ObjectSetInteger(0, TREND_LABEL, OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, TREND_LABEL, OBJPROP_FONTSIZE, 14); } string txt = "Trend Direction: " + trendComment; ObjectSetString(0, TREND_LABEL, OBJPROP_TEXT, txt); } //+------------------------------------------------------------------+ //| Draw horizontal line utility | //+------------------------------------------------------------------+ void DrawHorizontalLine(string name, double price, color lineColor, int width, ENUM_LINE_STYLE style) { if(ObjectFind(0, name) != -1) ObjectDelete(0, name); if(!ObjectCreate(0, name, OBJ_HLINE, 0, 0, price)) { Print("Failed to create line: ", name); return; } ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor); ObjectSetInteger(0, name, OBJPROP_STYLE, style); ObjectSetInteger(0, name, OBJPROP_WIDTH, width); ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true); } //+------------------------------------------------------------------+ //| Draw quarter lines based on toggle settings | //+------------------------------------------------------------------+ void DrawQuarterLines() { DeleteQuarterLines(); double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); if(currentPrice == 0) return; double lowerMajor = MathFloor(currentPrice / MajorStep) * MajorStep; double upperMajor = lowerMajor + MajorStep; DrawHorizontalLine("MajorLower", lowerMajor, MajorColor, MajorLineWidth, MajorLineStyle); DrawHorizontalLine("MajorUpper", upperMajor, MajorColor, MajorLineWidth, MajorLineStyle); if(g_DrawLargeQuarters) { double LQIncrement = MajorStep / 4.0; for(int i = 1; i < 4; i++) { double level = lowerMajor + i * LQIncrement; string objName = "LargeQuarter_" + IntegerToString(i); DrawHorizontalLine(objName, level, LargeQuarterColor, LargeQuarterLineWidth, LargeQuarterLineStyle); if(g_DrawOvershootAreas) { double smallQuarter = MajorStep / 40.0; DrawHorizontalLine("Overshoot_" + IntegerToString(i) + "_up", level + smallQuarter, OvershootColor, OvershootLineWidth, OvershootLineStyle); DrawHorizontalLine("Undershoot_" + IntegerToString(i) + "_down", level - smallQuarter, OvershootColor, OvershootLineWidth, OvershootLineStyle); } } } if(g_DrawSmallQuarters) { double segStep = MajorStep / 10.0; double smallQuarter = segStep / 4.0; for(int seg = 0; seg < 10; seg++) { double segStart = lowerMajor + seg * segStep; for(int j = 1; j < 4; j++) { double level = segStart + j * smallQuarter; string objName = "SmallQuarter_" + IntegerToString(seg) + "_" + IntegerToString(j); DrawHorizontalLine(objName, level, SmallQuarterColor, SmallQuarterLineWidth, SmallQuarterLineStyle); } } } } //+------------------------------------------------------------------+
Resultados
Nesta seção, examinamos os resultados e o desempenho do nosso EA. Abaixo está um diagrama em GIF que ilustra seu comportamento. Quando você arrasta o EA para um gráfico EURUSD, um painel com botões aparece. Inicialmente, os botões "Larger Quarter" e "Overshoot/Undershoot" exibem texto verde, indicando que estão ativados. Em contraste, os botões "Smaller Quarters" e "Trend Direction" mostram texto vermelho, o que significa que esses níveis estão desativados. Quando cada botão é pressionado, você pode ver os níveis correspondentes aparecerem no gráfico quando ativados, ou serem removidos quando desativados. Notavelmente, após ativar o botão Trend Direction, o comentário de tendência é atualizado para exibir "Uptrend", refletindo com precisão a condição atual do mercado no gráfico.

Abaixo está um diagrama que exibe claramente os resultados dos testes do nosso EA. Podemos ver que os níveis de large quarters, representados por linhas sólidas azuis, e os níveis de overshoot/undershoot, representados por linhas tracejadas vermelhas, estão ativos, evidenciado tanto pelas linhas no gráfico quanto pela cor do texto dos botões. Além disso, a direção da tendência está ativa, conforme mostrado pelo comentário visível no gráfico. Em contraste, o botão de small quarters aparece em vermelho, indicando que esses níveis não estão ativos.

Conclusão
Tendo introduzido o artigo com o objetivo de criar um painel com botões que alterna os níveis necessários no gráfico com um único clique, ativando-os ou desativando-os, alcançamos com sucesso esse objetivo. Isso representa mais um avanço no tratamento dos níveis de quarters de acordo com as necessidades dos traders. A melhoria fornece uma interface amigável: às vezes você pode querer focar apenas nos large quarters sem interferência de outros níveis, enquanto em outros momentos pode preferir exibir todos os níveis. Além disso, essa ferramenta oferece análises de direção de tendência para ajudá-lo a entender o que realmente está acontecendo no mercado com base no preço atual.
| Data | Nome da Ferramenta | Descrição | Versão | Atualizações | Notas |
|---|---|---|---|---|---|
| 01/10/24 | Projetor de Gráfico | Script para sobrepor a ação de preço do dia anterior com efeito fantasma. | 1.0 | Lançamento Inicial | Ferramenta número 1 |
| 18/11/24 | Comentário Analítico | Fornece informações do dia anterior em formato tabular, bem como antecipa a direção futura do mercado. | 1.0 | Lançamento Inicial | Ferramenta número 2 |
| 27/11/24 | Mestre Analítico | Atualização regular das métricas de mercado a cada duas horas | 1.01 | Segundo Lançamento | Ferramenta número 3 |
| 02/12/24 | Previsor Analítico | Atualização regular das métricas de mercado a cada duas horas com integração ao telegram | 1.1 | Terceira Edição | Ferramenta número 4 |
| 09/12/24 | Navegador de Volatilidade | O EA analisa as condições de mercado usando os indicadores Bandas de Bollinger, RSI e ATR | 1.0 | Lançamento Inicial | Ferramenta número 5 |
| 19/12/24 | Coletor de Sinais de Reversão à Média | Analisa o mercado usando estratégia de reversão à média e fornece sinal | 1.0 | Lançamento Inicial | Ferramenta número 6 |
| 9/01/25 | Pulso de Sinais | Analisador de múltiplos timeframes | 1.0 | Lançamento Inicial | Ferramenta número 7 |
| 17/01/25 | Painel de Métricas | Painel com botão para análise | 1.0 | Lançamento Inicial | Ferramenta número 8 |
| 21/01/25 | Fluxo Externo | Análises por meio de bibliotecas externas | 1.0 | Lançamento Inicial | Ferramenta número 9 |
| 27/01/25 | VWAP | Preço Médio Ponderado por Volume | 1.3 | Lançamento Inicial | Ferramenta número 10 |
| 02/02/25 | Heikin Ashi | Suavização de tendência e identificação de sinais de reversão | 1.0 | Lançamento Inicial | Ferramenta número 11 |
| 04/02/25 | FibVWAP | Geração de sinais por meio de análise em python | 1.0 | Lançamento Inicial | Ferramenta número 12 |
| 14/02/25 | DIVERGÊNCIA RSI | Ação de preço versus divergências do RSI | 1.0 | Lançamento Inicial | Ferramenta número 13 |
| 17/02/25 | Parabolic Stop and Reverse (PSAR) | Automatização da estratégia PSAR | 1.0 | Lançamento Inicial | Ferramenta número 14 |
| 20/02/25 | Script Quarters Drawer | Desenho de níveis de quarters no gráfico | 1.0 | Lançamento Inicial | Ferramenta número 15 |
| 27/02/25 | Detector de Intrusão | Detecta e alerta quando o preço atinge níveis de quarters | 1.0 | Lançamento Inicial | Ferramenta número 16 |
| 27/02/25 | Ferramenta TrendLoom | Painel de análise multi timeframe | 1.0 | Lançamento Inicial | Ferramenta número 17 |
| 11/03/25 | O Quarter Board | Painel com botões para ativar ou desativar níveis de quarters | 1.0 | Lançamento Inicial | Ferramenta número 18 |
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/17442
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.
Ciência de Dados e ML (Parte 35): NumPy em MQL5 – A Arte de Desenvolver Algoritmos Complexos com Menos Código
Do iniciante ao especialista: criação de um EA animado para notícias em MQL5 (VI): Estratégia de trading pós-notícia
Do iniciante ao especialista: Criação de um EA animado para notícias em MQL5 (VIII): botões de negociação rápida para trading de notícias
Desenvolvimento de um sistema personalizado de detecção do regime de mercado em MQL5 (Parte 2): Expert Advisor
- 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