English Русский 中文 Español Deutsch 日本語
preview
Automação de estratégias de trading em MQL5 (Parte 27): Identificação e Visualização do Padrão Harmônico "Crab" com Base em Price Action

Automação de estratégias de trading em MQL5 (Parte 27): Identificação e Visualização do Padrão Harmônico "Crab" com Base em Price Action

MetaTrader 5 — Sistemas de negociação |
24 8
Allan Munene Mutiiria
Allan Munene Mutiiria

Introdução

No artigo anterior (Parte 26), desenvolvemos um sistema de ajuste do preço médio baseado em pin bars na linguagem MetaQuotes Language 5 (MQL5). Esse sistema utiliza padrões de candles do tipo pin bar para abrir operações e gerenciar múltiplas posições por meio de uma estratégia de preço médio, além de contar com um dashboard dinâmico para monitoramento em tempo real. Na Parte 27, desenvolveremos um sistema capaz de identificar padrões harmônicos "Crab" de alta e de baixa com base em pontos de reversão e níveis de Fibonacci, automatizando as operações com níveis precisos de entrada, stop-loss e take-profit. O sistema também contará com recursos de visualização, como triângulos e linhas de tendência, para representar claramente os padrões no gráfico. Neste artigo, abordaremos os seguintes tópicos:

  1. Estudo da estrutura do padrão harmônico "Crab"
  2. Implementação em MQL5
  3. Backtesting
  4. Conclusão

Ao final, você terá uma estratégia de trading baseada em padrões harmônicos, cuidadosamente desenvolvida em MQL5 e pronta para ser ajustada às suas necessidades. Vamos à implementação!


Estudo da estrutura do padrão harmônico "Crab"

O padrão "Crab" é uma formação harmônica utilizada no trading, definida por cinco pontos principais de reversão do preço, identificados como X, A, B, C e D. Ele apresenta duas variantes: uma de alta e outra de baixa. No padrão "Crab" de alta, a estrutura segue a sequência "fundo-topo-fundo-topo-fundo". O ponto X corresponde a um swing low, o ponto A a um swing high, o ponto B a um swing low (retração de 0,618 do movimento XA), o ponto C a um swing high (extensão entre 0,382 e 0,886 do movimento AB) e o ponto D a um swing low (extensão de 1,618 do movimento XA, situado abaixo de X). Já o padrão "Crab" de baixa apresenta a sequência inversa, "topo-fundo-topo-fundo-topo". Nesse caso, o ponto X corresponde a um swing high, o ponto A a um swing low, o ponto B a um swing high, o ponto C a um swing low e o ponto D a um swing high (extensão de 1,618 do movimento XA, situado acima de X). A seguir, apresentamos as representações visuais das duas variantes.

Padrão harmônico "Crab" de alta:

BULLISH CRAB HARMONIC PATTERN

Padrão harmônico "Crab" de baixa:

BEARISH CRAB HARMONIC PATTERN

Para identificar esses padrões, adotaremos a seguinte abordagem estruturada:

  • Definição do segmento XA: O movimento impulsivo inicial do ponto X até o ponto A estabelece a base do padrão, definindo sua direção (para baixo no caso da tendência de alta e para cima no caso da tendência de baixa) e servindo como referência para os cálculos de Fibonacci.
  • Formação do segmento AB: O movimento até o ponto B deve representar uma retração de aproximadamente 0,618 do comprimento de XA, confirmando a correção sem uma reversão excessivamente acentuada em relação ao movimento inicial.
  • Análise do segmento BC: O comprimento do segmento BC deve ficar entre 0,382 e 0,886 vezes o comprimento de AB, formando um movimento acentuado em sentido contrário que prepara a extensão final.
  • Definição do segmento CD: O segmento final deve atingir uma extensão de 1,618 do comprimento de XA, delimitando a zona potencial de reversão no ponto D, onde o padrão se completa e gera um sinal de negociação.

Com base nesses critérios geométricos e nas proporções de Fibonacci, nosso sistema de trading identificará de forma sistemática padrões "Crab" válidos nos dados de preços. Após a identificação, o sistema representará a formação no gráfico por meio de triângulos, linhas de tendência, rótulos para os pontos X, A, B, C e D, além de linhas tracejadas para indicar os níveis de entrada e take-profit. Essa configuração permitirá automatizar a abertura de operações no ponto D, com stop-loss calculado e múltiplos níveis de take-profit, aproveitando a alta probabilidade de reversão associada ao padrão para entrar no mercado em condições favoráveis. Vamos à implementação!


Implementação em MQL5

Para criar o programa em MQL5, abra o MetaEditor, acesse o Navegador, localize a pasta "Indicadores" (Indicators), selecione "Novo" (New) e siga as instruções para criar o arquivo. Após essa etapa, precisaremos declarar algumas variáveis globais no ambiente de desenvolvimento, que serão utilizadas ao longo do programa.

//+------------------------------------------------------------------+
//|                                             Crab Pattern EA.mq5. |
//|                        Copyright 2025, Forex Algo-Trader, Allan. |
//|                                 "https://t.me/Forex_Algo_Trader" |
//+------------------------------------------------------------------+
#property copyright   "Forex Algo-Trader, Allan"
#property link        "https://t.me/Forex_Algo_Trader"
#property version     "1.00"
#property description "This EA trades based on Crab Strategy"
#property strict

#include <Trade\Trade.mqh>                         //--- Include Trade library for order management
CTrade obj_Trade;                                  //--- Instantiate trade object for executing orders

//--- Input parameters for user configuration
input int    PivotLeft = 5;                        // Number of bars to the left for pivot identification
input int    PivotRight = 5;                       // Number of bars to the right for pivot identification
input double Tolerance = 0.10;                     // Allowed deviation for Fibonacci levels (10% of XA move)
input double LotSize = 0.01;                       // Lot size for opening new trade positions
input bool   AllowTrading = true;                  // Enable or disable automated trading functionality

//---------------------------------------------------------------------------
//--- Crab pattern definition:
//--- Bullish Crab:
//--- Pivots (X-A-B-C-D): X swing low, A swing high, B swing low, C swing high, D swing low.
//--- Normally XA > 0; Ideal B = A - 0.5*(A-X); Legs within specified ranges.
//--- Bearish Crab:
//--- Pivots (X-A-B-C-D): X swing high, A swing low, B swing high, C swing low, D swing high.
//--- Normally XA > 0; Ideal B = A + 0.5*(X-A); Legs within specified ranges.
//---------------------------------------------------------------------------

struct Pivot {                                     //--- Define structure for pivot points
   datetime time;                                  //--- Store time of pivot bar
   double   price;                                 //--- Store price (high for swing high, low for swing low)
   bool     isHigh;                                //--- Indicate true for swing high, false for swing low
};

Pivot pivots[];                                    //--- Declare array to store pivot points
int      g_patternFormationBar = -1;               //--- Store bar index of pattern formation (-1 if none)
datetime g_lockedPatternX = 0;                     //--- Store X pivot time for locked pattern

Começaremos a implementação do padrão "Crab" incluindo a biblioteca "<Trade\Trade.mqh>" e criando uma instância da classe CTrade chamada "obj_Trade", para facilitar o gerenciamento de ordens, como o envio de solicitações de compra e venda. Em seguida, definiremos cinco parâmetros de entrada que permitirão personalizar o sistema: "PivotLeft" e "PivotRight", ambos com valor 5, estabelecem a quantidade de barras consideradas na identificação dos pivôs de máxima e mínima; "Tolerance", com valor 0,10, define a tolerância para desvios em relação aos níveis de Fibonacci; "LotSize", com valor 0,01, determina o volume das operações; e "AllowTrading", definido como true, habilita a abertura automática de operações.

Na sequência, definiremos a estrutura "Pivot", com os campos "time" (datetime), "price" (double) e "isHigh" (bool), para armazenar os pontos de reversão. Também declararemos "pivots" como um array de elementos do tipo "Pivot" e inicializaremos duas variáveis globais: "g_patternFormationBar", com valor -1, para acompanhar as barras em que os padrões se formam, e "g_lockedPatternX", com valor 0, para armazenar a marca de tempo do pivô X utilizada na confirmação. Com isso, teremos a base necessária para identificar os padrões. Para a visualização, poderemos utilizar funções que desenham linhas, rótulos e triângulos.

//+------------------------------------------------------------------+
//| Draw filled triangle on chart                                    |
//+------------------------------------------------------------------+
void DrawTriangle(string name, datetime t1, double p1, datetime t2, double p2, datetime t3, double p3, color cl, int width, bool fill, bool back) {
   if (ObjectCreate(0, name, OBJ_TRIANGLE, 0, t1, p1, t2, p2, t3, p3)) { //--- Create triangle with three points
      ObjectSetInteger(0, name, OBJPROP_COLOR, cl); //--- Set triangle color
      ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID); //--- Set solid line style
      ObjectSetInteger(0, name, OBJPROP_WIDTH, width); //--- Set line width
      ObjectSetInteger(0, name, OBJPROP_FILL, fill); //--- Enable or disable fill
      ObjectSetInteger(0, name, OBJPROP_BACK, back); //--- Set background or foreground
   }
}

//+------------------------------------------------------------------+
//| Draw trend line on chart                                         |
//+------------------------------------------------------------------+
void DrawTrendLine(string name, datetime t1, double p1, datetime t2, double p2, color cl, int width, int style) {
   if (ObjectCreate(0, name, OBJ_TREND, 0, t1, p1, t2, p2)) { //--- Create trend line between two points
      ObjectSetInteger(0, name, OBJPROP_COLOR, cl); //--- Set line color
      ObjectSetInteger(0, name, OBJPROP_STYLE, style); //--- Set line style (solid, dotted, etc.)
      ObjectSetInteger(0, name, OBJPROP_WIDTH, width); //--- Set line width
   }
}

//+------------------------------------------------------------------+
//| Draw dotted horizontal line on chart                             |
//+------------------------------------------------------------------+
void DrawDottedLine(string name, datetime t1, double p, datetime t2, color lineColor) {
   if (ObjectCreate(0, name, OBJ_TREND, 0, t1, p, t2, p)) { //--- Create horizontal dotted line
      ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor); //--- Set line color
      ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT); //--- Set dotted style
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 1); //--- Set line width to 1
   }
}

//+------------------------------------------------------------------+
//| Draw anchored text label for pivots                              |
//+------------------------------------------------------------------+
void DrawTextEx(string name, string text, datetime t, double p, color cl, int fontsize, bool isHigh) {
   if (ObjectCreate(0, name, OBJ_TEXT, 0, t, p)) { //--- Create text label at specified coordinates
      ObjectSetString(0, name, OBJPROP_TEXT, text); //--- Set label text content
      ObjectSetInteger(0, name, OBJPROP_COLOR, cl); //--- Set text color
      ObjectSetInteger(0, name, OBJPROP_FONTSIZE, fontsize); //--- Set font size
      ObjectSetString(0, name, OBJPROP_FONT, "Arial Bold"); //--- Set font to Arial Bold
      if (isHigh) {                                //--- Check if pivot is swing high
         ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_BOTTOM); //--- Anchor label above pivot
      } else {                                     //--- Handle swing low
         ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_TOP); //--- Anchor label below pivot
      }
      ObjectSetInteger(0, name, OBJPROP_ALIGN, ALIGN_CENTER); //--- Center-align text
   }
}

Nesta etapa, implementaremos as funções de visualização do programa, responsáveis por desenhar os objetos gráficos que representam o padrão harmônico "Crab" e seus níveis operacionais. Primeiro, criaremos a função "DrawTriangle", que utiliza ObjectCreate para desenhar um triângulo preenchido (OBJ_TRIANGLE), definido por três pontos com coordenadas de tempo ("t1", "t2", "t3") e preço ("p1", "p2", "p3"). Usaremos a função ObjectSetInteger para configurar as propriedades: OBJPROP_COLOR receberá a cor especificada; "OBJPROP_STYLE" será definido como "STYLE_SOLID"; "OBJPROP_WIDTH" receberá a largura desejada; "OBJPROP_FILL" permitirá ativar ou desativar o preenchimento; e "OBJPROP_BACK" determinará se o objeto será exibido em segundo plano ou em primeiro plano.

Em seguida, implementaremos a função "DrawTrendLine", que utiliza ObjectCreate para desenhar uma linha de tendência (OBJ_TREND) entre dois pontos. Com ObjectSetInteger, configuraremos as propriedades OBJPROP_COLOR, OBJPROP_STYLE (linha contínua, tracejada etc.) e OBJPROP_WIDTH, permitindo personalizar a aparência da linha. Depois, desenvolveremos a função "DrawDottedLine", que segue a mesma lógica para desenhar uma linha horizontal tracejada (OBJ_TREND) em um nível de preço especificado, entre os pontos temporais "t1" e "t2". Por fim, implementaremos a função "DrawTextEx", que utiliza ObjectCreate para inserir um rótulo de texto (OBJ_TEXT) nas coordenadas de tempo e preço ("t", "p"), seguindo o mesmo padrão de configuração das funções anteriores. Com esses recursos, poderemos representar claramente o padrão "Crab" e seus níveis operacionais no gráfico. Agora, podemos avançar para o manipulador de eventos OnTick e identificar os pivôs que serão utilizados posteriormente no reconhecimento dos padrões. A seguir, veremos a lógica adotada para isso.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
   static datetime lastBarTime = 0;               //--- Store time of last processed bar
   datetime currentBarTime = iTime(_Symbol, _Period, 1); //--- Get time of current confirmed bar
   if (currentBarTime == lastBarTime) return;     //--- Exit if no new bar
   lastBarTime = currentBarTime;                  //--- Update last processed bar time
   ArrayResize(pivots, 0);                        //--- Clear pivot array for fresh analysis
   int barsCount = Bars(_Symbol, _Period);        //--- Retrieve total number of bars
   int start = PivotLeft;                         //--- Set starting index for pivot detection
   int end = barsCount - PivotRight;              //--- Set ending index for pivot detection
   for (int i = end - 1; i >= start; i--) {       //--- Iterate through bars to identify pivots
      bool isPivotHigh = true;                    //--- Assume bar is a swing high
      bool isPivotLow = true;                     //--- Assume bar is a swing low
      double currentHigh = iHigh(_Symbol, _Period, i); //--- Get current bar high price
      double currentLow = iLow(_Symbol, _Period, i); //--- Get current bar low price
      for (int j = i - PivotLeft; j <= i + PivotRight; j++) { //--- Check surrounding bars
         if (j < 0 || j >= barsCount) continue;   //--- Skip out-of-bounds indices
         if (j == i) continue;                    //--- Skip current bar
         if (iHigh(_Symbol, _Period, j) > currentHigh) isPivotHigh = false; //--- Invalidate swing high
         if (iLow(_Symbol, _Period, j) < currentLow) isPivotLow = false; //--- Invalidate swing low
      }
      if (isPivotHigh || isPivotLow) {            //--- Check if bar is a pivot
         Pivot p;                                 //--- Create new pivot structure
         p.time = iTime(_Symbol, _Period, i);     //--- Set pivot bar time
         p.price = isPivotHigh ? currentHigh : currentLow; //--- Set pivot price
         p.isHigh = isPivotHigh;                  //--- Set pivot type
         int size = ArraySize(pivots);            //--- Get current pivot array size
         ArrayResize(pivots, size + 1);           //--- Resize pivot array
         pivots[size] = p;                        //--- Add pivot to array
      }
   }
}

Começaremos implementando a lógica inicial do manipulador OnTick, responsável por detectar pivôs de máxima e mínima que servirão de base para a identificação dos padrões harmônicos "Crab". Primeiro, verificaremos se uma nova barra foi formada, comparando "lastBarTime", uma variável estática inicializada com zero, com "currentBarTime", obtido pela função iTime com deslocamento 1. Dessa forma, evitaremos utilizar a barra atual, ainda em formação, do ativo e período gráfico em análise. Se não houver uma nova barra, encerraremos a execução da função. Caso contrário, atualizaremos "lastBarTime" e limparemos o array "pivots" com ArrayResize, preparando-o para uma nova análise. Em seguida, obteremos o número total de barras com Bars e definiremos os limites da busca por pivôs: "start", igual a "PivotLeft", e "end", igual ao número total de barras menos "PivotRight". Percorreremos então as barras de "end - 1" até "start".

Para cada barra, consideraremos inicialmente que ela pode ser tanto um pivô de máxima ("isPivotHigh" igual a true) quanto um pivô de mínima ("isPivotLow" igual a true). Obteremos seus preços máximo e mínimo com iHigh e iLow e examinaremos as barras vizinhas nos intervalos definidos por "PivotLeft" e "PivotRight". Se alguma dessas barras apresentar uma máxima superior ou uma mínima inferior, descartaremos a respectiva condição de pivô. Se a barra continuar atendendo aos critérios de pivô de máxima ou mínima, criaremos uma estrutura "Pivot" e preencheremos seus campos: "time" receberá a marca de tempo obtida com iTime; "price" receberá o preço máximo ou mínimo, conforme o valor de "isPivotHigh"; e "isHigh" indicará se o pivô corresponde a uma máxima. Em seguida, ampliaremos o array "pivots" com ArrayResize e armazenaremos o novo elemento. Ao exibir os dados do array na tela, obteremos o seguinte resultado.

PIVOTS DATA

Com esses dados, podemos identificar os pontos de reversão do preço e, quando houver pivôs suficientes, analisar sua sequência para detectar os padrões. A seguir, apresentaremos a lógica que implementaremos para isso.

int pivotCount = ArraySize(pivots);            //--- Get total number of pivots
if (pivotCount < 5) {                          //--- Check if insufficient pivots
   g_patternFormationBar = -1;                 //--- Reset pattern formation bar
   g_lockedPatternX = 0;                       //--- Reset locked X pivot
   return;                                     //--- Exit function
}
Pivot X = pivots[pivotCount - 5];              //--- Extract X pivot (earliest)
Pivot A = pivots[pivotCount - 4];              //--- Extract A pivot
Pivot B = pivots[pivotCount - 3];              //--- Extract B pivot
Pivot C = pivots[pivotCount - 2];              //--- Extract C pivot
Pivot D = pivots[pivotCount - 1];              //--- Extract D pivot (latest)
bool patternFound = false;                     //--- Initialize pattern detection flag
if (X.isHigh && !A.isHigh && B.isHigh && !C.isHigh && D.isHigh) { //--- Check bearish Crab pattern
   double diff = X.price - A.price;            //--- Calculate XA leg difference
   if (diff > 0) {                             //--- Ensure positive XA move
      double idealB = A.price + 0.618 * diff;  //--- Compute ideal B (0.618 retracement)
      if (MathAbs(B.price - idealB) <= Tolerance * diff) { //--- Verify B within tolerance
         double AB = B.price - A.price;        //--- Calculate AB leg length
         double BC = B.price - C.price;        //--- Calculate BC leg length
         if (BC >= 0.382 * AB && BC <= 0.886 * AB) { //--- Check BC within Fibonacci range
            double extension = D.price - A.price; //--- Calculate AD extension
            if (MathAbs(extension - 1.618 * diff) <= Tolerance * diff && D.price > X.price) { //--- Verify 1.618 extension and D > X
               patternFound = true;            //--- Confirm bearish pattern
            }
         }
      }
   }
}
if (!X.isHigh && A.isHigh && !B.isHigh && C.isHigh && !D.isHigh) { //--- Check bullish Crab pattern
   double diff = A.price - X.price;            //--- Calculate XA leg difference
   if (diff > 0) {                             //--- Ensure positive XA move
      double idealB = A.price - 0.618 * diff;  //--- Compute ideal B (0.618 retracement)
      if (MathAbs(B.price - idealB) <= Tolerance * diff) { //--- Verify B within tolerance
         double AB = A.price - B.price;        //--- Calculate AB leg length
         double BC = C.price - B.price;        //--- Calculate BC leg length
         if (BC >= 0.382 * AB && BC <= 0.886 * AB) { //--- Check BC within Fibonacci range
            double extension = A.price - D.price; //--- Calculate AD extension
            if (MathAbs(extension - 1.618 * diff) <= Tolerance * diff && D.price < X.price) { //--- Verify 1.618 extension and D < X
               patternFound = true;            //--- Confirm bullish pattern
            }
         }
      }
   }
}

Para identificar os padrões, utilizaremos critérios baseados nas proporções de Fibonacci. Primeiro, obteremos o número total de pivôs com "arraySize(pivots)" e armazenaremos esse valor em "pivotCount". Se houver menos de cinco pivôs, definiremos "g_patternFormationBar" como -1 e "g_lockedPatternX" como 0 e encerraremos a execução da função, pois o padrão "Crab" exige cinco pontos: X, A, B, C e D. Em seguida, extrairemos os cinco pivôs mais recentes do array "pivots" e os identificaremos como X (o mais antigo), A, B, C e D (o mais recente), formando a estrutura do padrão.

Começaremos verificando a presença de um padrão "Crab" de baixa, cuja sequência deve ser: máxima em X, mínima em A, máxima em B, mínima em C e máxima em D. Calcularemos o comprimento do segmento XA pela diferença "X.price - A.price" e verificaremos se o resultado é positivo. Em seguida, calcularemos o nível ideal do ponto B como "A.price + 0.618 * diff" e utilizaremos MathAbs para confirmar se o desvio de B em relação a esse nível está dentro da tolerância "Tolerance * diff". Depois, verificaremos se o comprimento de BC corresponde a 38,2% a 88,6% do comprimento de AB e se a extensão AD atinge 161,8% de XA, com D situado acima de X. Se todas as condições forem atendidas, definiremos "patternFound" como true. Na sequência, verificaremos a presença de um padrão "Crab" de alta, com a sequência inversa: mínima em X, máxima em A, mínima em B, máxima em C e mínima em D. Calcularemos o comprimento de XA como "A.price - X.price" e confirmaremos que o resultado é positivo. Também verificaremos se B está no nível de retração de 61,8%, se BC corresponde a 38,2% a 88,6% do comprimento de AB e se AD atinge uma extensão de 161,8% de XA, com D abaixo de X. Se o padrão atender a todos os critérios, definiremos "patternFound" como true. Após identificar um padrão válido, poderemos representá-lo no gráfico.

string patternType = "";                                                //--- Initialize pattern type
if (patternFound) {                                                     //--- Check if pattern detected
   if (D.price > X.price) patternType = "Bearish";                      //--- Set bearish pattern (sell signal)
   else if (D.price < X.price) patternType = "Bullish";                 //--- Set bullish pattern (buy signal)
}
if (patternFound) {                                                     //--- Process valid Crab pattern
   Print(patternType, " Crab pattern detected at ", TimeToString(D.time, TIME_DATE|TIME_MINUTES|TIME_SECONDS)); //--- Log pattern detection
   string signalPrefix = "CR_" + IntegerToString(X.time);               //--- Generate unique prefix for objects
   color triangleColor = (patternType == "Bullish") ? clrBlue : clrRed; //--- Set triangle color based on pattern
   DrawTriangle(signalPrefix + "_Triangle1", X.time, X.price, A.time, A.price, B.time, B.price, triangleColor, 2, true, true); //--- Draw XAB triangle
   DrawTriangle(signalPrefix + "_Triangle2", B.time, B.price, C.time, C.price, D.time, D.price, triangleColor, 2, true, true); //--- Draw BCD triangle
}

Para classificar e visualizar os padrões identificados, inicializaremos a variável "patternType" com uma string vazia, que posteriormente indicará se o padrão é de alta ou de baixa. Se "patternFound" for true, determinaremos o tipo comparando "D.price" com "X.price". Quando D estiver acima de X, definiremos "patternType" como "Bearish", indicando um sinal de venda. Quando D estiver abaixo de X, atribuiremos o valor "Bullish", indicando um sinal de compra. Após confirmar a validade do padrão "Crab", registraremos sua identificação com a função Print, exibindo o valor de "patternType" e a marca de tempo do pivô D, formatada com TimeToString para apresentar a data e o horário com precisão de segundos.

Por fim, criaremos um identificador exclusivo chamado "signalPrefix", concatenando o prefixo "CR_" com o valor de "X.time" convertido em string. Definiremos "triangleColor" como azul para padrões de alta e vermelho para padrões de baixa. Em seguida, chamaremos "DrawTriangle" duas vezes para representar a estrutura do padrão: primeiro, desenharemos o triângulo XAB, conectando os pontos X, A e B; depois, o triângulo BCD, conectando B, C e D. Utilizaremos "signalPrefix" com os sufixos "_Triangle1" e "_Triangle2", respectivamente, além das coordenadas de tempo e preço dos pivôs correspondentes, da cor definida em "triangleColor" e da largura 2. Também ativaremos o preenchimento dos triângulos e sua exibição em segundo plano, facilitando a identificação visual dos padrões "Crab" e a análise dos sinais para a tomada de decisões de trading. Com isso, concluímos mais uma etapa da implementação.

PATTERN WITH TRIANGLES

A imagem mostra que conseguimos representar corretamente o padrão identificado no gráfico. Agora, precisamos adicionar as linhas de tendência para delinear toda a sua estrutura e adicionar rótulos que facilitem a identificação dos níveis do padrão.

DrawTrendLine(signalPrefix + "_TL_XA", X.time, X.price, A.time, A.price, clrBlack, 2, STYLE_SOLID); //--- Draw XA trend line
DrawTrendLine(signalPrefix + "_TL_AB", A.time, A.price, B.time, B.price, clrBlack, 2, STYLE_SOLID); //--- Draw AB trend line
DrawTrendLine(signalPrefix + "_TL_BC", B.time, B.price, C.time, C.price, clrBlack, 2, STYLE_SOLID); //--- Draw BC trend line
DrawTrendLine(signalPrefix + "_TL_CD", C.time, C.price, D.time, D.price, clrBlack, 2, STYLE_SOLID); //--- Draw CD trend line
DrawTrendLine(signalPrefix + "_TL_XB", X.time, X.price, B.time, B.price, clrBlack, 2, STYLE_SOLID); //--- Draw XB trend line
DrawTrendLine(signalPrefix + "_TL_BD", B.time, B.price, D.time, D.price, clrBlack, 2, STYLE_SOLID); //--- Draw BD trend line
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); //--- Retrieve symbol point size
double offset = 15 * point;                    //--- Calculate label offset (15 points)
double textY_X = X.isHigh ? X.price + offset : X.price - offset; //--- Set X label Y coordinate
double textY_A = A.isHigh ? A.price + offset : A.price - offset; //--- Set A label Y coordinate
double textY_B = B.isHigh ? B.price + offset : B.price - offset; //--- Set B label Y coordinate
double textY_C = C.isHigh ? C.price + offset : C.price - offset; //--- Set C label Y coordinate
double textY_D = D.isHigh ? D.price + offset : D.price - offset; //--- Set D label Y coordinate
DrawTextEx(signalPrefix + "_Text_X", "X", X.time, textY_X, clrBlack, 11, X.isHigh); //--- Draw X pivot label
DrawTextEx(signalPrefix + "_Text_A", "A", A.time, textY_A, clrBlack, 11, A.isHigh); //--- Draw A pivot label
DrawTextEx(signalPrefix + "_Text_B", "B", B.time, textY_B, clrBlack, 11, B.isHigh); //--- Draw B pivot label
DrawTextEx(signalPrefix + "_Text_C", "C", C.time, textY_C, clrBlack, 11, C.isHigh); //--- Draw C pivot label
DrawTextEx(signalPrefix + "_Text_D", "D", D.time, textY_D, clrBlack, 11, D.isHigh); //--- Draw D pivot label
datetime centralTime = (X.time + B.time) / 2;                                       //--- Calculate central label time
double centralPrice = D.price;                                                      //--- Set central label price
if (ObjectCreate(0, signalPrefix + "_Text_Center", OBJ_TEXT, 0, centralTime, centralPrice)) { //--- Create central pattern label
   ObjectSetString(0, signalPrefix + "_Text_Center", OBJPROP_TEXT, patternType == "Bullish" ? "Bullish Crab" : "Bearish Crab"); //--- Set pattern name
   ObjectSetInteger(0, signalPrefix + "_Text_Center", OBJPROP_COLOR, clrBlack);     //--- Set text color
   ObjectSetInteger(0, signalPrefix + "_Text_Center", OBJPROP_FONTSIZE, 11);        //--- Set font size
   ObjectSetString(0, signalPrefix + "_Text_Center", OBJPROP_FONT, "Arial Bold");   //--- Set font type
   ObjectSetInteger(0, signalPrefix + "_Text_Center", OBJPROP_ALIGN, ALIGN_CENTER); //--- Center-align text
}

Para completar a representação do padrão, adicionaremos linhas e rótulos. Primeiro, utilizaremos a função "DrawTrendLine" para desenhar seis linhas de tendência, identificadas pelo prefixo exclusivo "signalPrefix", conectando os principais pontos de reversão. Os segmentos XA, AB, BC, CD, XB e BD terão suas extremidades definidas pelas coordenadas de tempo e preço dos respectivos pivôs, como "X.time" e "X.price". Todas as linhas utilizarão a cor "clrBlack", largura 2 e estilo STYLE_SOLID, delineando a estrutura XABCD e os segmentos auxiliares. Em seguida, calcularemos o deslocamento dos rótulos obtendo o tamanho de um ponto do ativo com "SymbolInfoDouble(_Symbol, SYMBOL_POINT)" e multiplicando esse valor por 15. Com esse deslocamento, determinaremos as coordenadas verticais dos rótulos ("textY_X", "textY_A", "textY_B", "textY_C", "textY_D"), somando ou subtraindo o valor conforme cada pivô represente uma máxima ("isHigh" igual a true) ou uma mínima. Assim, os rótulos aparecerão acima das máximas e abaixo das mínimas.

Em seguida, utilizaremos "DrawTextEx" para criar os rótulos dos pivôs X, A, B, C e D. Cada objeto será identificado por "signalPrefix" combinado com um sufixo correspondente, como "_Text_X", e exibirá a letra do respectivo pivô. Os rótulos serão posicionados na marca de tempo de cada pivô, com a coordenada vertical ajustada pelo deslocamento calculado. Utilizaremos a cor "clrBlack", tamanho de fonte 11 e o valor de "isHigh" para definir a ancoragem do texto. Por fim, calcularemos a posição do rótulo central, definindo "centralTime" como o ponto médio entre "X.time" e "B.time" e "centralPrice" como "D.price". Criaremos então um objeto de texto com ObjectCreate, utilizando o nome "signalPrefix + '_Text_Center'". A propriedade OBJPROP_TEXT receberá o texto "Bullish Crab" ou "Bearish Crab", conforme o valor de "patternType". Também configuraremos "OBJPROP_COLOR" como "clrBlack", "OBJPROP_FONTSIZE" como 11, "OBJPROP_FONT" como "Arial Bold" e "OBJPROP_ALIGN" como "ALIGN_CENTER", utilizando ObjectSetString e ObjectSetInteger. Com isso, teremos uma representação completa da estrutura e do tipo do padrão "Crab" no gráfico. Ao executar o programa, obteremos o seguinte resultado.

CRAB PATTERN WITH EDGES AND LABELS

A imagem mostra que adicionamos as linhas de contorno e os rótulos ao padrão, tornando sua estrutura mais fácil de identificar. O próximo passo será definir os níveis operacionais correspondentes.

datetime lineStart = D.time;                                     //--- Set start time for trade level lines
datetime lineEnd = D.time + PeriodSeconds(_Period) * 2;          //--- Set end time for trade level lines
double entryPriceLevel, TP1Level, TP2Level, TP3Level, tradeDiff; //--- Declare trade level variables
if (patternType == "Bullish") {                                  //--- Handle bullish trade levels
   entryPriceLevel = SymbolInfoDouble(_Symbol, SYMBOL_ASK);      //--- Set entry at ask price
   TP3Level = C.price;                                           //--- Set TP3 at C pivot price
   tradeDiff = TP3Level - entryPriceLevel;                       //--- Calculate total trade distance
   TP1Level = entryPriceLevel + tradeDiff / 3;                   //--- Set TP1 at 1/3 of distance
   TP2Level = entryPriceLevel + 2 * tradeDiff / 3;               //--- Set TP2 at 2/3 of distance
} else {                                                         //--- Handle bearish trade levels
   entryPriceLevel = SymbolInfoDouble(_Symbol, SYMBOL_BID);      //--- Set entry at bid price
   TP3Level = C.price;                                           //--- Set TP3 at C pivot price
   tradeDiff = entryPriceLevel - TP3Level;                       //--- Calculate total trade distance
   TP1Level = entryPriceLevel - tradeDiff / 3;                   //--- Set TP1 at 1/3 of distance
   TP2Level = entryPriceLevel - 2 * tradeDiff / 3;               //--- Set TP2 at 2/3 of distance
}
DrawDottedLine(signalPrefix + "_EntryLine", lineStart, entryPriceLevel, lineEnd, clrMagenta);  //--- Draw entry level line
DrawDottedLine(signalPrefix + "_TP1Line", lineStart, TP1Level, lineEnd, clrForestGreen);       //--- Draw TP1 level line
DrawDottedLine(signalPrefix + "_TP2Line", lineStart, TP2Level, lineEnd, clrGreen);             //--- Draw TP2 level line
DrawDottedLine(signalPrefix + "_TP3Line", lineStart, TP3Level, lineEnd, clrDarkGreen);         //--- Draw TP3 level line
datetime labelTime = lineEnd + PeriodSeconds(_Period) / 2;                                     //--- Set time for trade level labels
string entryLabel = patternType == "Bullish" ? "BUY (" : "SELL (";                             //--- Start entry label text
entryLabel += DoubleToString(entryPriceLevel, _Digits) + ")";                                  //--- Append entry price
DrawTextEx(signalPrefix + "_EntryLabel", entryLabel, labelTime, entryPriceLevel, clrMagenta, 11, true); //--- Draw entry label
string tp1Label = "TP1 (" + DoubleToString(TP1Level, _Digits) + ")";                           //--- Create TP1 label text
DrawTextEx(signalPrefix + "_TP1Label", tp1Label, labelTime, TP1Level, clrForestGreen, 11, true); //--- Draw TP1 label
string tp2Label = "TP2 (" + DoubleToString(TP2Level, _Digits) + ")";                           //--- Create TP2 label text
DrawTextEx(signalPrefix + "_TP2Label", tp2Label, labelTime, TP2Level, clrGreen, 11, true);     //--- Draw TP2 label
string tp3Label = "TP3 (" + DoubleToString(TP3Level, _Digits) + ")";                           //--- Create TP3 label text
DrawTextEx(signalPrefix + "_TP3Label", tp3Label, labelTime, TP3Level, clrDarkGreen, 11, true); //--- Draw TP3 label

Nesta etapa, continuaremos com o cálculo e a visualização dos níveis operacionais do padrão identificado. Primeiro, definiremos "lineStart" com a marca de tempo do pivô D ("D.time") e "lineEnd" com um instante correspondente a dois períodos gráficos após esse pivô, calculado com "PeriodSeconds(_Period) * 2". Em seguida, declararemos as variáveis "entryPriceLevel", "TP1Level", "TP2Level", "TP3Level" e "tradeDiff", que serão utilizadas nos cálculos das operações. Para um padrão de alta ("patternType == 'Bullish'"), definiremos "entryPriceLevel" com o preço Ask atual, obtido por meio de SymbolInfoDouble, e "TP3Level" com o preço do pivô C. Calcularemos "tradeDiff" como "TP3Level - entryPriceLevel" e determinaremos "TP1Level" e "TP2Level" acrescentando ao preço de entrada, respectivamente, um terço e dois terços de "tradeDiff". Para um padrão de baixa, utilizaremos o preço Bid como nível de entrada e definiremos "TP3Level" com o preço do ponto C. Nesse caso, calcularemos "tradeDiff" como "entryPriceLevel - TP3Level" e determinaremos "TP1Level" e "TP2Level" subtraindo do preço de entrada, respectivamente, um terço e dois terços dessa diferença.

Em seguida, utilizaremos a função "DrawDottedLine" para desenhar quatro linhas horizontais tracejadas, desde "lineStart" até "lineEnd": uma linha de entrada no nível "entryPriceLevel", na cor magenta, e três linhas de take-profit nos níveis "TP1Level" (verde-floresta intenso), "TP2Level" (verde) e "TP3Level" (verde-escuro). Por fim, definiremos "labelTime" como "lineEnd" acrescido de metade de um período gráfico e criaremos rótulos com os preços formatados por DoubleToString, como "BUY (price)" ou "SELL (price)" para a entrada e "TP1 (price)", entre outros, para os níveis de take-profit. Utilizaremos "DrawTextEx" para posicionar esses rótulos em "labelTime", com as cores correspondentes, tamanho de fonte 11 e ancoragem acima dos respectivos níveis de preço. Após compilar o programa, obteremos o seguinte resultado.

Padrão de baixa:

BEARISH

Padrão de alta:

BULLISH

As imagens mostram que os níveis operacionais foram representados corretamente no gráfico. Agora, resta implementar a abertura das posições reais de trading.

int currentBarIndex = Bars(_Symbol, _Period) - 1;       //--- Retrieve current bar index
if (g_patternFormationBar == -1) {                      //--- Check if no pattern is locked
   g_patternFormationBar = currentBarIndex;             //--- Lock current bar as formation bar
   g_lockedPatternX = X.time;                           //--- Lock X pivot time
   Print("Pattern detected on bar ", currentBarIndex, ". Waiting for confirmation on next bar."); //--- Log detection
   return;                                              //--- Exit function
}
if (currentBarIndex == g_patternFormationBar) {         //--- Check if still on formation bar
   Print("Pattern is repainting; still on locked formation bar ", currentBarIndex, ". No trade yet."); //--- Log repainting
   return;                                              //--- Exit function
}
if (currentBarIndex > g_patternFormationBar) {          //--- Check if new bar after formation
   if (g_lockedPatternX == X.time) {                    //--- Verify same X pivot for confirmation
      Print("Confirmed pattern (locked on bar ", g_patternFormationBar, "). Opening trade on bar ", currentBarIndex, "."); //--- Log confirmed pattern
      g_patternFormationBar = currentBarIndex;          //--- Update formation bar to current
      if (AllowTrading && !PositionSelect(_Symbol)) {   //--- Check trading allowed and no open position
         double entryPriceTrade = 0, stopLoss = 0, takeProfit = 0; //--- Declare trade parameters
         point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); //--- Update point value
         bool tradeResult = false;                      //--- Initialize trade result flag
         if (patternType == "Bullish") {                //--- Process bullish trade
            entryPriceTrade = SymbolInfoDouble(_Symbol, SYMBOL_ASK); //--- Set entry at ask price
            double diffTrade = TP2Level - entryPriceTrade; //--- Calculate trade distance
            stopLoss = entryPriceTrade - diffTrade * 3; //--- Set stop loss (3x distance)
            takeProfit = TP2Level;                      //--- Set take profit at TP2
            tradeResult = obj_Trade.Buy(LotSize, _Symbol, entryPriceTrade, stopLoss, takeProfit, "Crab Signal"); //--- Execute buy trade
            if (tradeResult) {                          //--- Check trade success
               Print("Buy order opened successfully."); //--- Log successful buy
            } else {                                    //--- Handle trade failure
               Print("Buy order failed: ", obj_Trade.ResultRetcodeDescription()); //--- Log failure reason
            }
         } else if (patternType == "Bearish") {         //--- Process bearish trade
            entryPriceTrade = SymbolInfoDouble(_Symbol, SYMBOL_BID); //--- Set entry at bid price
            double diffTrade = entryPriceTrade - TP2Level; //--- Calculate trade distance
            stopLoss = entryPriceTrade + diffTrade * 3; //--- Set stop loss (3x distance)
            takeProfit = TP2Level;                      //--- Set take profit at TP2
            tradeResult = obj_Trade.Sell(LotSize, _Symbol, entryPriceTrade, stopLoss, takeProfit, "Crab Signal"); //--- Execute sell trade
            if (tradeResult) {                          //--- Check trade success
               Print("Sell order opened successfully."); //--- Log successful sell
            } else {                                    //--- Handle trade failure
               Print("Sell order failed: ", obj_Trade.ResultRetcodeDescription()); //--- Log failure reason
            }
         }
      } else {                                          //--- Trading not allowed or position exists
         Print("A position is already open for ", _Symbol, ". No new trade executed."); //--- Log no trade
      }
   } else {                                            //--- Pattern has changed
      g_patternFormationBar = currentBarIndex;         //--- Update formation bar
      g_lockedPatternX = X.time;                       //--- Update locked X pivot
      Print("Pattern has changed; updating lock on bar ", currentBarIndex, ". Waiting for confirmation."); //--- Log pattern change
      return;                                          //--- Exit function
   }
}
} else {                                               //--- No valid pattern detected
   g_patternFormationBar = -1;                         //--- Reset formation bar
   g_lockedPatternX = 0;                               //--- Reset locked X pivot
}

Primeiro, obteremos o índice da barra atual com "Bars(_Symbol, _Period) - 1" e armazenaremos o resultado em "currentBarIndex". Em seguida, se não houver nenhum padrão bloqueado ("g_patternFormationBar == -1"), definiremos "g_patternFormationBar" como "currentBarIndex" e armazenaremos a marca de tempo do pivô X em "g_lockedPatternX", utilizando "X.time". Também registraremos uma mensagem informando que o padrão foi identificado e aguarda confirmação, encerrando a execução da função. Se o padrão ainda estiver na mesma barra em que foi detectado ("currentBarIndex == g_patternFormationBar"), registraremos que o padrão está passando por repainting e encerraremos a execução, evitando a abertura prematura de operações.

Quando uma nova barra for formada ("currentBarIndex > g_patternFormationBar") e o pivô X corresponder ao valor armazenado em "g_lockedPatternX", confirmaremos o padrão e fixaremos seu estado, atualizando "g_patternFormationBar". Em seguida, verificaremos se a negociação está habilitada por "AllowTrading" e se não existem posições abertas, utilizando PositionSelect. Para um padrão de alta, definiremos "entryPriceTrade" com o preço Ask e calcularemos "diffTrade" como "TP2Level - entryPriceTrade". O "stopLoss" será posicionado abaixo do preço de entrada, a uma distância equivalente a três vezes "diffTrade", enquanto "takeProfit" receberá o valor de "TP2Level". Abriremos então uma posição de compra com "obj_Trade.Buy", utilizando o volume definido em "LotSize" e o comentário "Crab Signal", e registraremos se a operação foi executada com sucesso ou se houve falha. Para um padrão de baixa, utilizaremos o preço Bid e posicionaremos o "stopLoss" acima do preço de entrada, a uma distância equivalente a três vezes a diferença calculada para a operação. Em seguida, abriremos uma posição de venda com "obj_Trade.Sell". Se a negociação estiver desabilitada ou já existir uma posição aberta, nenhuma nova operação será executada. Caso o padrão mude, atualizaremos os valores armazenados e aguardaremos uma nova confirmação. Se nenhum padrão for identificado, redefiniremos "g_patternFormationBar" e "g_lockedPatternX" para seus valores iniciais. Dessa forma, somente padrões "Crab" confirmados poderão gerar operações, com níveis definidos para o gerenciamento de risco. Por fim, precisaremos apenas implementar a remoção dos objetos gráficos dos padrões quando o programa for retirado do gráfico.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   ObjectsDeleteAll(0, "CR_");                    //--- Remove all chart objects with "CR_" prefix
   ArrayResize(pivots, 0);                        //--- Clear pivots array
   g_patternFormationBar = -1;                    //--- Reset pattern formation bar index
   g_lockedPatternX = 0;                          //--- Reset locked pattern X pivot time
   ChartRedraw(0);                                //--- Redraw chart to reflect changes
}

Nesta etapa, implementaremos o manipulador de eventos OnDeinit para executar a limpeza necessária quando o EA for removido do gráfico. Primeiro, utilizaremos ObjectsDeleteAll para excluir todos os objetos gráficos com o prefixo "CR_", removendo os elementos visuais associados aos padrões "Crab", como triângulos, linhas de tendência e rótulos. Em seguida, utilizaremos ArrayResize para reduzir o tamanho do array "pivots" a zero, eliminando os dados armazenados dos pivôs. Também redefiniremos "g_patternFormationBar" como -1 e "g_lockedPatternX" como 0, reinicializando as variáveis de acompanhamento dos padrões. Por fim, chamaremos ChartRedraw para atualizar o gráfico e refletir a remoção dos objetos. Essa limpeza libera os recursos utilizados e evita que elementos gráficos permaneçam no gráfico após a remoção do EA. Após compilar o programa, obteremos o seguinte resultado.

Sinal de baixa:

BEARISH SIGNAL

Sinal de alta:

BULLISH SIGNAL

A imagem mostra que conseguimos representar graficamente o padrão harmônico e que o sistema também permite executar operações com base nele assim que houver confirmação. Com isso, alcançamos nosso objetivo de identificar, visualizar e negociar o padrão "Crab". Resta apenas realizar o backtesting do programa, que será apresentado na próxima seção.


Backtesting

Após realizar um backtesting detalhado, obtivemos os seguintes resultados.

Gráfico do backtesting:

Gráfico

Relatório do backtesting:

REPORT


Conclusão

Neste artigo, desenvolvemos um sistema de reconhecimento do padrão harmônico "Crab" em MQL5. O sistema utiliza os movimentos do preço para identificar padrões de alta e de baixa com base em níveis precisos de Fibonacci, automatizando as operações com pontos de entrada calculados, stop-loss e múltiplos níveis de take-profit. Esses elementos são representados no gráfico por meio de objetos gráficos dinâmicos, como triângulos e linhas de tendência.

Aviso de isenção de responsabilidade: O conteúdo deste artigo tem finalidade exclusivamente educacional. O trading envolve riscos financeiros significativos, e a volatilidade do mercado pode resultar em perdas. Antes de utilizar este programa em condições reais de mercado, é fundamental realizar um backtesting rigoroso e adotar práticas adequadas de gerenciamento de risco.

Com os conceitos e métodos de implementação apresentados, você poderá adaptar o sistema de reconhecimento do padrão "Crab" ao seu estilo de trading e aprimorar suas estratégias algorítmicas. Bons trades!

Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/19099

Arquivos anexados |
Crab_Pattern_EA.mq5 (47.93 KB)
Últimos Comentários | Ir para discussão (8)
Andrey F. Zelinsky
Andrey F. Zelinsky | 15 mai. 2026 em 13:17
Maxim Kuznetsov #:

absolutamente nada :-)

A saliência direita foi aumentada em 1,68, ou seja, é a mesma borboleta, mas com mais um nível de Fibonacci adicionado. Se for fazer isso, o código é o mesmo.

Qualquer padrão não tem a ver com o código, mas sim com o sinal.

Os tipos de sinais dos padrões são diferentes — isso significa que um padrão é adequado para uma situação, e outro padrão, para outra.

Vitaly Muzichenko
Vitaly Muzichenko | 15 mai. 2026 em 13:45
Andrey F. Zelinsky #:

Qualquer padrão não tem a ver com código, mas sim com um sinal.

Os tipos de sinais dos padrões são diferentes — isso significa que um padrão é adequado para uma situação, enquanto outro padrão é adequado para outra.

... e, mesmo assim, o resultado continua o mesmo = 50/50
Andrey F. Zelinsky
Andrey F. Zelinsky | 15 mai. 2026 em 13:59
Vitaly Muzichenko #:
... e, mesmo assim, o resultado continua o mesmo = 50/50

no artigo sobre o padrão, e não sobre a filosofia do sinal.

A filosofia do sinal já foi descrita há muito tempo, explorada e explicada de forma extremamente clara, por exemplo, no filme cult “O Lobo de Wall Street”, no diálogo entre Mark Hann e Jordan Belfort:

Vídeo com tradução para o russo aqui: https://www.youtube.com/watch?v=fRVwyZ6t7Fk&t=112s

Citação:“Ninguém sabe se o preço das ações vai subir, descer, ficar lateral ou girar em círculos — tudo isso é humera, quimera, só o humer vai entender”

Andrey F. Zelinsky
Andrey F. Zelinsky | 15 mai. 2026 em 14:16
Vitaly Muzichenko #:
... e, mesmo assim, o resultado continua o mesmo = 50/50

só que, além de um único sinal do padrão, há um conjunto de sinais de diferentes tipos (sinais de entrada/saída, de filtragem), há gestão de capital — e, no fim das contas, a probabilidade na saída está longe de ser 50/50

christian balsalobre de castro
christian balsalobre de castro | 6 out. 2026 em 08:43
Esse backtest exaustivo não é o que está publicado, né? Ora, com tão poucas operações, não entendo como isso pode ser um backtest exaustivo; é um pouco fraco.
Oscilador Parafrac: combinação dos indicadores Parabolic SAR e Fractals Oscilador Parafrac: combinação dos indicadores Parabolic SAR e Fractals
Neste artigo, veremos como combinar o Parabolic SAR e o indicador Fractals para criar um novo indicador do tipo oscilador. Ao aproveitar os pontos fortes de ambas as ferramentas, os traders podem desenvolver uma estratégia de negociação mais precisa e eficiente.
Desenvolvimento de ferramentas para análise de Price Action (Parte 36): Acesso direto do Python aos fluxos de dados de mercado do MetaTrader 5 Desenvolvimento de ferramentas para análise de Price Action (Parte 36): Acesso direto do Python aos fluxos de dados de mercado do MetaTrader 5
Aproveite ao máximo o potencial do terminal MetaTrader 5 com o ecossistema Python para análise de dados e a biblioteca cliente oficial MetaTrader 5. Neste artigo, mostramos como realizar a autenticação e armazenar diretamente ticks e barras de um minuto no formato Parquet, aplicar técnicas avançadas de engenharia de atributos com as bibliotecas ta e Prophet e treinar um modelo de gradient boosting que respeite a estrutura temporal dos dados. Em seguida, implementamos um serviço Flask leve que disponibiliza sinais de negociação em tempo real. Seja para desenvolver um sistema híbrido de trading quantitativo ou incorporar recursos de machine learning a um EA, ao final você terá um pipeline completo e confiável para negociação algorítmica orientada por dados.
Está chegando o novo MetaTrader 5 e MQL5 Está chegando o novo MetaTrader 5 e MQL5
Esta é apenas uma breve resenha do MetaTrader 5. Eu não posso descrever todos os novos recursos do sistema por um período tão curto de tempo - os testes começaram em 09.09.2009. Esta é uma data simbólica, e tenho certeza que será um número de sorte. Alguns dias passaram-se desde que eu obtive a versão beta do terminal MetaTrader 5 e MQL5. Eu ainda não consegui testar todos os seus recursos, mas já estou impressionado.
Automação de estratégias de negociação em MQL5 (Parte 26): Criação de um sistema de preço médio baseado em pin bars para negociação com múltiplas posições Automação de estratégias de negociação em MQL5 (Parte 26): Criação de um sistema de preço médio baseado em pin bars para negociação com múltiplas posições
Neste artigo, desenvolvemos em MQL5 um sistema de preço médio baseado em pin bars, que identifica esses padrões para abrir operações e utiliza uma estratégia de preço médio para gerenciar múltiplas posições, com recursos de trailing stop e ajuste do stop para o ponto de equilíbrio (breakeven). Também combinamos parâmetros configuráveis com um dashboard que permite monitorar as posições e os lucros em tempo real.