English Русский 中文 Español Deutsch 日本語
preview
Desenvolvimento de um conjunto de ferramentas de Análise de Price Action (Parte 18): Introduzindo a Teoria dos Quarters (III) — Quarters Board

Desenvolvimento de um conjunto de ferramentas de Análise de Price Action (Parte 18): Introduzindo a Teoria dos Quarters (III) — Quarters Board

MetaTrader 5Exemplos |
22 0
Christian Benjamin
Christian Benjamin

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.

O Quarter Board

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

Arquivos anexados |
Quarters_Board.mq5 (14.84 KB)
Ciência de Dados e ML (Parte 35): NumPy em MQL5 – A Arte de Desenvolver Algoritmos Complexos com Menos Código Ciência de Dados e ML (Parte 35): NumPy em MQL5 – A Arte de Desenvolver Algoritmos Complexos com Menos Código
A biblioteca NumPy está impulsionando praticamente todos os algoritmos de aprendizado de máquina (machine learning) em sua essência na linguagem de programação Python, neste artigo vamos implementar um módulo semelhante que possui uma coleção de todo o código complexo para nos auxiliar na construção de modelos e algoritmos sofisticados de qualquer tipo.
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 (VI): Estratégia de trading pós-notícia
Durante o primeiro minuto após a divulgação de notícias econômicas importantes, o risco de erro de avaliação é extremamente alto. Nesse curto intervalo, o movimento do preço pode ser errático e volátil, frequentemente levando ao acionamento de ordens pendentes dos dois lados do mercado. Pouco depois da publicação, geralmente dentro de um minuto, o mercado tende a se estabilizar, retomando ou corrigindo a tendência predominante em patamares mais normais de volatilidade. Nesta seção, examinaremos uma abordagem alternativa para o trading baseado em notícias, a fim de avaliar sua eficácia como um complemento valioso ao conjunto de ferramentas do trader. Continue lendo para acompanhar mais detalhes desta discussão.
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 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
Enquanto os sistemas algorítmicos de trading gerenciam operações automatizadas, muitos traders de notícias e scalpers preferem manter controle ativo durante eventos importantes de notícias e condições de mercado que mudam rapidamente, exigindo execução e gestão rápidas das ordens. Isso evidencia a necessidade de ferramentas de interface intuitivas que integrem feeds de notícias em tempo real, dados do calendário econômico, leituras dos indicadores, análises baseadas em IA e gestão adaptativa do trading.
Desenvolvimento de um sistema personalizado de detecção do regime de mercado em MQL5 (Parte 2): Expert Advisor Desenvolvimento de um sistema personalizado de detecção do regime de mercado em MQL5 (Parte 2): Expert Advisor
Este artigo descreve em detalhes a criação de um EA adaptativo (MarketRegimeEA) usando o detector de regimes da Parte 1. Ele alterna automaticamente estratégias de negociação e parâmetros de risco para mercados de tendência, mercados laterais ou mercados voláteis. O artigo também inclui otimização prática, tratamento das transições e um indicador para vários timeframes.