English Русский 中文 Español Deutsch 日本語
preview
Desenvolvimento de ferramentas para análise de Price Action (Parte 31): Módulo de reconhecimento de padrões de candles em Python (I): reconhecimento manual

Desenvolvimento de ferramentas para análise de Price Action (Parte 31): Módulo de reconhecimento de padrões de candles em Python (I): reconhecimento manual

MetaTrader 5 — Integração |
49 0
Christian Benjamin
Christian Benjamin

Sumário



Introdução

Os gráficos de candles são uma ferramenta essencial para analistas financeiros e traders visualizarem e interpretarem os movimentos de preço ao longo do tempo. Criados há séculos por comerciantes japoneses de arroz, esses gráficos se tornaram parte fundamental da análise técnica em diversos mercados financeiros, incluindo ações, Forex e futuros.

Padrões

Cada candle fornece informações importantes sobre o sentimento do mercado, apresentando dados essenciais, como os preços de abertura, fechamento, máxima e mínima dentro de um determinado período gráfico. A estrutura única de cada candle permite compreender a psicologia do mercado e pode servir como um possível sinal operacional.

Neste artigo, vamos explorar o desenvolvimento de um sistema abrangente de reconhecimento de padrões de candles que utiliza os recursos do MQL5 e do Python. Começaremos pela implementação de métodos de reconhecimento manual e criaremos um script que recebe dados do MQL5 e atribui nomes aos padrões com base em critérios definidos. Embora esse reconhecimento possa ser implementado integralmente em MQL5, optamos por dividir as funções entre MQL5 e Python para aproveitar os pontos fortes de cada linguagem e garantir maior flexibilidade e confiabilidade.

No próximo artigo, ampliaremos esse sistema com bibliotecas Python que oferecem recursos mais avançados de reconhecimento de padrões de candles, aumentando tanto a precisão quanto a variedade dos padrões identificados. Vamos explorar os detalhes do reconhecimento de padrões de candles e entender como essa abordagem integrada aprimora a análise de negociação. A seguir, apresentamos o plano de trabalho.

  • Análise de cada padrão: examinaremos cada padrão de candles individualmente e explicaremos como seu reconhecimento foi implementado em Python.
  • Análise da integração entre MQL5 e Python: examinaremos como o Expert Advisor MQL5 se comunica com o servidor Python, incluindo o processo de troca de dados e a estrutura geral dessa interação.
  • Avaliação dos resultados e conclusões: por fim, avaliaremos os resultados do sistema, discutiremos sua eficácia e apresentaremos conclusões sobre possíveis melhorias.


Análise dos padrões de candles

A parte principal do candle é chamada de corpo e representa a diferença entre os preços de abertura e fechamento em determinado período. Um corpo preenchido geralmente indica que o preço de fechamento ficou abaixo do preço de abertura, caracterizando um movimento de baixa. Por outro lado, um corpo sem preenchimento ou exibido em outra cor indica que o preço de fechamento ficou acima do preço de abertura, caracterizando um movimento de alta.

As sombras, também chamadas de pavios, se estendem a partir do corpo do candle e indicam os preços máximo e mínimo registrados durante o período de negociação. O comprimento e a posição dessas sombras ajudam a avaliar a volatilidade do mercado e o sentimento dos participantes, mostrando como o preço oscilou em relação aos níveis de abertura e fechamento.

Os padrões de candles refletem a psicologia coletiva dos participantes do mercado, suas reações emocionais e expectativas. Os analistas técnicos utilizam esses sinais visuais para identificar possíveis pontos de entrada e saída. Os gráficos de candles surgiram no Japão do século XVIII, quando comerciantes de arroz utilizavam esse método para acompanhar os preços do produto. Atualmente, continuam sendo uma ferramenta versátil para analisar ativos líquidos, como ações, pares de moedas e futuros.

Candles de alta e de baixa

  • Candles de alta:

Um candle é considerado de alta quando o preço de fechamento fica acima do preço de abertura. Normalmente, é representado em branco ou verde, indicando um impulso de alta. Esses candles mostram que os compradores dominaram o mercado durante o período. Candles de alta com corpos longos ganham maior relevância quando aparecem próximos a níveis importantes de suporte, pois indicam forte demanda.

  • Candles de baixa:

Um candle de baixa, por sua vez, se forma quando o preço de fechamento fica abaixo do preço de abertura. Normalmente, é representado em preto ou vermelho, indicando pressão vendedora e movimento de queda dos preços. Candles de baixa com corpos longos costumam sinalizar forte atuação dos vendedores e uma possível continuidade da queda.

  • Convenções de cores

Embora muitas plataformas de negociação utilizem tradicionalmente branco ou verde para representar candles de alta e preto ou vermelho para candles de baixa, essas cores podem ser personalizadas. O fundamental é compreender a relação entre os preços de abertura e fechamento, sem depender de uma combinação específica de cores. Para interpretar corretamente o sentimento do mercado, devemos sempre observar a posição do preço de fechamento em relação ao de abertura.

Diante da grande variedade de padrões de candles, nosso sistema se concentra em um conjunto reduzido de formações importantes. A seguir, examinaremos as características visuais de cada padrão e veremos como identificá-los usando Python.

Martelo

O padrão "martelo" se forma quando os preços de abertura, máxima e fechamento estão próximos uns dos outros, formando um corpo pequeno. Sua principal característica é uma sombra inferior bastante longa, indicando que os vendedores tentaram pressionar o preço para baixo, mas os compradores conseguiram reverter esse movimento. Essa formação sugere o possível início de um impulso de alta e reflete um sentimento de alta subjacente. A seguir, apresentamos um trecho de código Python para identificar o padrão "martelo".

# inside detect_patterns(df: pd.DataFrame)
for i, _ in enumerate(df.index):
    o,h,l,c = df.iloc[i][["OPEN","HIGH","LOW","CLOSE"]]
    body = abs(c - o)
    lower = min(o,c) - l
    upper = h - max(o,c)
    
    if lower >= 2*body and upper <= body:
        pats[i] = "hammer"
        continue

  • O tamanho do corpo do candle é calculado como abs(close - open).
  • A sombra inferior deve ter pelo menos o dobro do comprimento do corpo.
  • A sombra superior deve ser curta, com comprimento no máximo igual ao do corpo.
  • Quando essas condições são atendidas, o padrão é identificado como "hammer" no array pats[].

Estrela cadente

O padrão "estrela cadente" se forma quando os preços de abertura, mínima e fechamento ficam aproximadamente no mesmo nível, resultando em um candle com corpo muito pequeno e uma longa sombra superior. Frequentemente considerado o equivalente de baixa do "martelo", esse padrão sinaliza uma possível reversão ou enfraquecimento do impulso de alta. Na análise técnica, costuma-se exigir que a sombra superior tenha pelo menos o dobro do comprimento do corpo para confirmar a relevância do padrão.

# inside detect_patterns(df: pd.DataFrame)
for i, _ in enumerate(df.index):
    o,h,l,c = df.iloc[i][["OPEN","HIGH","LOW","CLOSE"]]
    body = abs(c - o)
    lower = min(o,c) - l
    upper = h - max(o,c)
    
    if upper >= 2*body and lower <= body:
        pats[i] = "shootingstar"
        continue

  • O corpo corresponde à diferença entre open e close.
  • A sombra superior deve ter pelo menos o dobro do comprimento do corpo. A sombra inferior deve ser curta, com comprimento menor ou igual ao do corpo.
  • Quando essas condições são atendidas, o padrão é identificado como "shootingstar".

Engolfo (de alta e de baixa)

O padrão de engolfo de alta ocorre quando um candle vermelho (de baixa) com corpo pequeno é seguido por um candle verde (de alta) maior, cujo corpo cobre completamente o do candle anterior. Esse padrão indica uma possível reversão da tendência de baixa para alta, pois a pressão compradora superou a pressão vendedora.

# Bullish Engulfing: small red followed by large green that engulfs it
if i >= 1:
    prev_o, prev_c = df.iloc[i-1][["OPEN", "CLOSE"]]
    curr_o, curr_c = o, c
    if (prev_c < prev_o and curr_c > curr_o and  # red candle then green
        curr_o < prev_c and curr_c > prev_o):    # body engulfs previous
        pats[i] = "bullishengulfing"
        continue

O padrão de engolfo de baixa apresenta a formação oposta. Ele ocorre quando um candle verde (de alta) com corpo pequeno é seguido por um candle vermelho (de baixa) maior, cujo corpo cobre completamente o do candle anterior. Esse padrão indica uma possível reversão da tendência de alta para baixa, refletindo o fortalecimento da pressão vendedora.

# Bearish Engulfing: small green followed by large red that engulfs it
if i >= 1:
    prev_o, prev_c = df.iloc[i-1][["OPEN", "CLOSE"]]
    curr_o, curr_c = o, c
    if (prev_c > prev_o and curr_c < curr_o and  # green candle then red
        curr_o > prev_c and curr_c < prev_o):    # body engulfs previous
        pats[i] = "bearishengulfing"
        continue

Doji

O doji é um candle que se forma quando os preços de abertura e fechamento são praticamente iguais, resultando em um corpo muito pequeno ou até mesmo inexistente. Esse padrão indica indecisão no mercado, pois nem compradores nem vendedores conseguiram assumir o controle durante o período de negociação.

# Doji: very small or no real body
if abs(c - o) <= (h - l) * 0.1:
    pats[i] = "doji"
    continue

  • abs(c - o): tamanho do corpo do candle, calculado pela diferença absoluta entre close e open.
  • (h - l): amplitude total do candle, calculada pela diferença entre a máxima e a mínima. Se o corpo representar 10% ou menos da amplitude total, o candle será classificado como doji.

Harami (de alta e de baixa)

O padrão "harami", cujo nome vem de uma palavra japonesa que significa "grávida", é uma formação bastante conhecida na análise técnica e pode sinalizar uma possível reversão ou continuação da tendência. Ele é composto por dois candles: o primeiro, maior, costuma ser chamado de "candle-mãe", enquanto o segundo é menor e fica contido entre a máxima e a mínima do primeiro. Para que o padrão seja considerado válido, o segundo candle deve fechar dentro do corpo do candle anterior, indicando uma possível pausa no impulso predominante ou sua reversão.

O padrão "harami" pode sinalizar uma reversão de baixa quando aparece após uma tendência de alta, indicando o enfraquecimento da pressão compradora e uma possível queda dos preços. Por outro lado, quando surge após uma tendência de baixa, pode funcionar como um sinal de alta, sugerindo uma possível correção de alta ou reversão da tendência.

if i >= 1:
    prev_o, prev_c = df.iloc[i-1][["OPEN", "CLOSE"]]
    curr_o, curr_c = o, c

    # Previous candle: large body (engulfing candle)
    prev_body = abs(prev_c - prev_o)
    curr_body = abs(curr_c - curr_o)

    if prev_body > 0 and curr_body > 0:
        # Bullish Harami
        if prev_o > prev_c and curr_o < curr_c:  # bearish → bullish
            if curr_o > prev_c and curr_c < prev_o:
                pats[i] = "bullishharami"
                continue

        # Bearish Harami
        if prev_o < prev_c and curr_o > curr_c:  # bullish → bearish
            if curr_o < prev_c and curr_c > prev_o:
                pats[i] = "bearishharami"
                continue

Estrela da manhã

O padrão "estrela da manhã" é uma importante formação de reversão de alta que costuma aparecer após uma tendência de baixa, sinalizando uma possível mudança no sentimento do mercado, de baixa para alta. Ele é composto por três candles: o primeiro é um candle de baixa com corpo longo, indicando forte pressão vendedora; o segundo tem corpo pequeno, podendo ser de alta ou de baixa, e apresenta um gap em relação ao primeiro, refletindo indecisão ou uma pausa no impulso predominante; o terceiro é um candle de alta com corpo longo, que fecha bem dentro do corpo do primeiro e confirma o surgimento de um impulso de alta.

Esse padrão indica que os vendedores estão perdendo o controle enquanto os compradores ganham força, o que, após a confirmação, frequentemente resulta em um movimento de alta sustentado. A estrela da manhã é amplamente utilizada pelos traders para identificar possíveis pontos de entrada em posições compradas, especialmente quando surge após uma queda prolongada.

if i >= 2:
    o1, c1 = df.iloc[i-2][["OPEN", "CLOSE"]]  # First candle
    o2, c2 = df.iloc[i-1][["OPEN", "CLOSE"]]  # Second (small) candle
    o3, c3 = df.iloc[i][["OPEN", "CLOSE"]]    # Third candle

    # Candle directions
    is_bearish1 = c1 < o1
    is_small2 = abs(c2 - o2) < abs(c1 - o1) * 0.5
    is_bullish3 = c3 > o3

    # Morning Star Logic
    if is_bearish1 and is_small2 and c3 > ((o1 + c1) / 2) and c3 > o3:
        if min(o2, c2) < c1 and max(o2, c2) > c1:  # small gap
            pats[i] = "morningstar"
            continue

  • Candle 1: candle de baixa com corpo longo.
  • Candle 2: candle com corpo pequeno (pode ser de alta ou de baixa).
  • Candle 3: candle de alta forte, que fecha acima do ponto médio do candle 1.

Essa formação de reversão composta por três candles geralmente sinaliza o possível fim de uma tendência de baixa.

Estrela da noite

O padrão "estrela da noite" é uma importante formação de reversão de baixa que costuma aparecer após uma tendência de alta, indicando uma possível mudança no sentimento do mercado, de alta para baixa. Ele é composto por três candles: o primeiro é um candle de alta com corpo longo, refletindo forte pressão compradora; o segundo tem corpo pequeno, podendo ser de alta ou de baixa, e apresenta um gap em relação ao primeiro, indicando indecisão ou oscilações no mercado; o terceiro é um candle de baixa com corpo longo, que fecha bem dentro do corpo do primeiro e confirma a reversão.

Esse padrão indica que os compradores estão perdendo força enquanto os vendedores assumem o controle, o que frequentemente resulta em um movimento de queda ou uma correção. Os traders costumam utilizar a "estrela da noite" como sinal para considerar a abertura de posições vendidas ou o encerramento de posições compradas, especialmente quando aparece após uma alta prolongada.

if i >= 2:
    o1, c1 = df.iloc[i-2][["OPEN", "CLOSE"]]  # First candle
    o2, c2 = df.iloc[i-1][["OPEN", "CLOSE"]]  # Second (small) candle
    o3, c3 = df.iloc[i][["OPEN", "CLOSE"]]    # Third candle

    is_bullish1 = c1 > o1
    is_small2 = abs(c2 - o2) < abs(c1 - o1) * 0.5
    is_bearish3 = c3 < o3

    if is_bullish1 and is_small2 and c3 < ((o1 + c1) / 2) and c3 < o3:
        if max(o2, c2) > c1 and min(o2, c2) < c1:  # small gap possible
            pats[i] = "eveningstar"
            continue

  • Candle 1: candle de alta com corpo longo.
  • Candle 2: candle com corpo pequeno (indecisão).
  • Candle 3: candle de baixa forte, que fecha bem abaixo do ponto médio do candle 1.

Essa formação de três candles indica uma possível reversão da tendência de alta para baixa.


Integração entre MQL5 e Python

Na arquitetura do nosso sistema, a lógica principal de reconhecimento dos padrões de candles fica concentrada em um microsserviço Python, enquanto o EA desenvolvido em MQL5 é responsável pela coleta de dados, marcação dos padrões no gráfico e emissão de alertas. Sempre que uma nova barra é fechada, o EA coleta os dados OHLC das últimas 31 barras, envia essas informações em formato JSON para um servidor Flask local e, em seguida, marca no gráfico os padrões identificados pelo servidor. Tudo isso ocorre praticamente em tempo real. Vamos entender cada etapa desse funcionamento.

  • EA MQL5: coleta de dados
A cada nova barra, o EA registra, por meio da função OnTick, as marcas de tempo e os preços de abertura, máxima, mínima e fechamento das últimas 31 barras em arrays.
void OnTick()
{
   static datetime lastBar = 0;
   datetime bar = iTime(_Symbol, InpTF, 0);
   if(bar == lastBar) return;
   lastBar = bar;

   double o[ BARS ], h[ BARS ], l[ BARS ], c[ BARS ];
   long   t[ BARS ];
   for(int i=0; i<BARS; i++)
   {
      o[i] = iOpen(_Symbol, InpTF, i+1);
      h[i] = iHigh(_Symbol, InpTF, i+1);
      l[i] = iLow (_Symbol, InpTF, i+1);
      c[i] = iClose(_Symbol, InpTF, i+1);
      t[i] = (long)iTime(_Symbol, InpTF, i+1);
   }
   // …then build JSON…
}
  • EA MQL5: montagem do pacote JSON
Usando StringFormat, o EA reúne o símbolo, o período gráfico, as marcas de tempo e os arrays OHLC em uma única string JSON, pronta para envio.
string json = StringFormat(
  "{\"symbol\":\"%s\",\"timeframe\":%d,"
  "\"time\":[%s],\"open\":[%s],\"high\":[%s],"
  "\"low\":[%s],\"close\":[%s]}",
  _Symbol, InpTF,
  CSVInt(t), CSV(o), CSV(h), CSV(l), CSV(c)
);
  • EA MQL5: envio via HTTP POST
O EA envia uma requisição HTTP usando WebRequest("POST", …) para http://127.0.0.1:5000/patterns. Se ocorrer algum erro na requisição, ele registra o problema no log. Caso contrário, recebe a resposta JSON do servidor Python.
char body[];    StringToCharArray(json, body);
char reply[];   string hdr="Content-Type: application/json\r\n", respHdr;
int code = WebRequest("POST", InpURL, hdr, InpTimeout, body, reply, respHdr);
if(code == -1)
  Print("[CSLAB] WebRequest failed: ", GetLastError());
else
  string resp = CharArrayToString(reply, 0, -1, CP_UTF8);
  • Python: processamento no servidor Flask
O serviço Python remove os caracteres excedentes do final da string, decodifica o JSON resultante em um dicionário e reconstrói um DataFrame do pandas, usando as marcas de tempo recebidas como índice.
@app.route("/patterns", methods=["POST"])
def patterns():
    raw = request.get_data(as_text=True)
    idx = raw.rfind("}")
    clean = raw[:idx+1] if idx != -1 else raw
    payload = json.loads(clean)   # may raise JSONDecodeError
    # …build DataFrame…

  • Python: construção do DataFrame

A função build_dataframe converte os arrays JSON de marcas de tempo e preços de abertura, máxima, mínima e fechamento em um DataFrame com índice temporal, facilitando a análise dos dados pelo nosso detector de padrões:

def build_dataframe(payload):
    times = [ datetime.fromtimestamp(int(t), timezone.utc)
              for t in payload["time"] ]
    df = pd.DataFrame({
      "OPEN":  payload["open"],
      "HIGH":  payload["high"],
      "LOW":   payload["low"],
      "CLOSE": payload["close"]
    }, index=times)
    df.index.name = "datetime"
    return df

  • Python: identificação manual dos padrões

Nossa função detect_patterns(df) analisa cada linha em busca de sinais correspondentes aos padrões doji, "martelo", "estrela cadente", engolfo, "harami", "estrela da manhã" e "estrela da noite", sem recorrer a bibliotecas externas de análise técnica.

def detect_patterns(df):
    pats = ["None"]*len(df)
    for i in range(len(df)):
        o,h,l,c = df.iloc[i][["OPEN","HIGH","LOW","CLOSE"]]
        body = abs(c-o); rng = max(h-l,1e-6)
        lower = min(o,c)-l; upper = h-max(o,c)
        # doji
        if body/rng <= 0.1:
            pats[i] = "doji"; continue
        # hammer
        if lower>=2*body and upper<=body:
            pats[i] = "hammer"; continue
        # shooting star
        if upper>=2*body and lower<=body:
            pats[i] = "shootingstar"; continue
        # bullish engulfing
        if i>0:
            po,pc = df.iloc[i-1][["OPEN","CLOSE"]]
            if pc<po and c>o and o<=pc and c>=po:
                pats[i] = "bullishengulfing"; continue
        # bearish engulfing
        if i>0:
            po,pc = df.iloc[i-1][["OPEN","CLOSE"]]
            if pc>po and c<o and o>=pc and c<=po:
                pats[i] = "bearishengulfing"; continue
        # harami
        if i>0:
            po,pc = df.iloc[i-1][["OPEN","CLOSE"]]
            if pc<po and o<c and o>pc and c<po:
                pats[i] = "bullishharami"; continue
            if pc>po and o>c and o<pc and c>po:
                pats[i] = "bearishharami"; continue
        # morning star
        if i>1:
            o1,c1 = df.iloc[i-2][["OPEN","CLOSE"]]
            o2,c2 = df.iloc[i-1][["OPEN","CLOSE"]]
            if c1<o1 and abs(c2-o2)<(df.iloc[i-1]["HIGH"]-df.iloc[i-1]["LOW"])*0.3 \
               and c>o2 and c>(o1+c1)/2:
                pats[i] = "morningstar"; continue
        # evening star
        if i>1:
            o1,c1 = df.iloc[i-2][["OPEN","CLOSE"]]
            o2,c2 = df.iloc[i-1][["OPEN","CLOSE"]]
            if c1>o1 and abs(c2-o2)<(df.iloc[i-1]["HIGH"]-df.iloc[i-1]["LOW"])*0.3 \
               and c<o2 and c<(o1+c1)/2:
                pats[i] = "eveningstar"; continue
    return pats
  • Python: geração da resposta

O servidor contabiliza todos os padrões identificados, desconsiderando os valores "None", e retorna uma estrutura JSON compacta:

pats = detect_patterns(df)
counts = Counter(pats)
log_lines = [f"{k}={v}" for k,v in counts.items() if k!="None"]
resp = {"patterns": pats, "log": log_lines, "ms": round((datetime.now(timezone.utc)-start).total_seconds()*1000,2)}
return make_response(json.dumps(resp), 200, {"Content-Type":"application/json"})
  • EA MQL5: processamento da resposta e ações do EA
De volta ao MQL5, extraímos o array "patterns", verificamos se ele contém 31 elementos e registramos no log todas as mensagens presentes no campo "log". Em seguida, para cada padrão efetivamente identificado, adicionamos um rótulo de texto acima da barra correspondente no gráfico e acionamos Alert().
// extract patterns array
string patTxt; ExtractArray(resp, "patterns", patTxt);
string patt[]; ParseArray(patTxt, patt);
// draw+alert
for(int i=0;i<BARS;i++)
   if(patt[i]!="None")
   {
      datetime tm=iTime(_Symbol,InpTF,i+1);
      ObjectCreate(0,"CS_"+i,OBJ_TEXT,0,tm,iHigh(_Symbol,InpTF,i+1));
      ObjectSetString(0,"CS_"+i,OBJPROP_TEXT,patt[i]);
      Alert(_Symbol, " ", patt[i], " at ", TimeToString(tm,TIME_DATE|TIME_MINUTES));
   }


Testes e resultados

Nesta seção, vamos testar o sistema e analisar os resultados obtidos. Antes de começar, veremos como instalar o Python e configurar o servidor para garantir que tudo funcione corretamente.

Baixe o Python

Primeiro, baixe e instale o Python pelo site oficial. Clique no botão amarelo "Download Python 3.x.x".

Execute o instalador

Clique duas vezes no arquivo baixado. Antes de selecionar "Install Now", marque a opção "Add Python to PATH". Isso permitirá executar o Python pelo prompt de comando a partir de qualquer diretório. Clique em "Install Now" e, quando a instalação terminar, em "Close".

Verifique a instalação

Pressione Win + R, digite cmd e pressione Enter. Na janela do prompt de comando, digite:

python --version

Você deverá ver algo como "Python 3.10.4". Se essa informação aparecer, significa que o Python foi instalado corretamente.

Com o Python instalado, a próxima etapa é criar nosso script.

Abra o Notepad++

Execute o Notepad++ ou qualquer outro editor de texto simples.

Crie um novo arquivo

Selecione File > New e, em seguida, Language > P > Python para ativar o destaque de sintaxe (opcional).

Insira o código do servidor

Copie todo o conteúdo de pattern_server.py, incluindo a aplicação Flask, a função detect_patterns(df) e o restante do código, e cole no novo arquivo.

Salve o arquivo

  • Acesse File > Save As...
  • Escolha uma pasta fácil de localizar, como "C:\PatternServer".
  • No campo "File name", digite pattern_server.py (a extensão .py é obrigatória).
  • Clique em "Save".

Instale as bibliotecas necessárias

Abra o prompt de comando

Primeiro, pressione Windows + R para abrir a janela "Run". Digite cmd no campo de entrada e pressione Enter ou clique em "OK" para abrir o prompt de comando. Nessa janela, você poderá navegar pelo sistema de arquivos e executar scripts.

Altere o diretório

Em seguida, acesse a pasta onde está localizado o seu script Python. No prompt de comando, utilize o comando cd (change directory), seguido do caminho da pasta que contém o script. Por exemplo:

cd path\to\your\script\folder
Substitua path\to\your\script\folder pelo caminho correspondente no seu sistema. Isso garante que a sessão atual do terminal esteja no diretório correto, permitindo executar o script sem problemas.

Instale o Flask e o pandas

pip install flask pandas

Esse comando instalará o Flask (nosso servidor web leve) e o pandas (para processamento de dados). Você verá algo parecido com isto:

* Serving Flask app "pattern_server"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Isso indica que o microsserviço está em execução e recebendo requisições. Em seguida, compile o EA em MQL5 e arraste-o para o gráfico. Com isso, o EA estabelece comunicação com o servidor Python em execução. A seguir, apresentamos os resultados e as observações obtidos após iniciar o sistema.

Teste no par EURUSD

Logs na aba "Experts" do MetaTrader 5

2025.07.09 22:25:42.248 Candlestick Label (EURUSD,M15)  [CSLAB] EA started – allow http://127.0.0.1:5000/patterns in Tools→Options→Expert Advisors→WebRequest
2025.07.09 22:25:42.790 Candlestick Label (EURUSD,M15)  [CSLAB] JSON-OUT: {"symbol":"EURUSD",
"timeframe":0,"time":[1752064200,1752065100,1752066000,1752066900,1752067800,1752068700,1752069600,
1752070500,1752071400,1752072300,1752073200,1752074100,1752075000,1752075900,1752076800,1752077700,
1752078600,1752079500,1752080400,1752081300,1752082200,1752083100,1752084000,1752084900,1752085800,
1752086700,1752087600,1752088500,1752089400,1752090300,1752091200],"open":[1.17051,1.17045,1.17153,
1.17167,1.17143,1.17096,1.17034,1.17152,1.17193,1.17194,1.17148,1.17095,1.1706

2025.07.09 22:25:42.790 Candlestick Label (EURUSD,M15)  [CSLAB] POST http://127.0.0.1:5000/patterns
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] HTTP 200 RESP: {"patterns": ["doji",
 "bullishengulfing", "None", "None", "eveningstar", "None", "bullishengulfing", "None", "doji", 
"bearishengulfing", "None", "None", "None", "None", "None", "bearishengulfing", "None", "None", 
"bullishengulfing", "doji", "bearishengulfing", "None", "None", "None", "None", "None", "None",
 "None", "hammer", "eveningstar", "None"], "log": ["doji=3", "bullishengulfing=3", "eveningstar=2",
 "bearishengulfing=3", "hammer=1", "total patterns=12"], "ms": 128.25}
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: doji=3
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: bullishengulfing=3
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: eveningstar=2
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: bearishengulfing=3
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: hammer=1
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: total patterns=12

Logs do Python no CMD

2025-07-09 22:25:42,806 [INFO] RAW BODY: {"symbol":"EURUSD","timeframe":0,"time":[1752064200,1752065100,1752066000,1752066900,1752067800,
1752068700,1752069600,1752070500,1752071400,1752072300,1752073200,1752074100,1752075000,1752075900,1752076800,1752077700,1752078600,
1752079500,1752080400,1752081300,1752082200,1752083100,1752084000,1752084900,1752085800,1752086700,1752087600,1752088500,1752089400,
1752090300,1752091200],"open":[1.17051,1.17045,1.17153,1.17167,1.17143,1.17096,1.17034,1.17152,1.17193,1.17194,1.17148,1.17095,1.17066,
1.17085,1.17060,1.17072,1.17015,1.17066,1.17050,1.17087,1.17088,1.17059,1.17086,1.17174,1.17160,1.17105,1.17134,1.17166,1.17216,1.17226,
1.17189],"high":[1.17091,1.17170,1.17206,1.17225,1.17186,1.17098,1.17160,1.17246,1.17223,1.17194,1.17163,1.17112,1.17098,1.17103,1.17091,
1.17088,1.17071,1.17073,1.17109,1.17104,1.17092,1.17102,1.17179,1.17176,1.17164,1.17147,1.17170,1.17222,1.17232,1.17232,1.17199],
"low":[1.17008,1.17036,1.17120,1.17109,1.17088,1.17005,1.17028,1.17152,1.17152,1.17131,1.17095,1.17050,1.17055,1.17050,1.17059,1.17009,1.17013,
1.17039,1.17039,1.17077,1.17043,1.17056,1.17051,1.17141,1.17091,1.17101,1.17130,1.17163,1.17188,1.17180,1.17163],"close":[1.17045,
1.17153,1.17170,1.17143,1.17096,1.17034,1.17152,1.17193,1.17194,1.17149,1.17096,1.17066,1.17086,1.17061,1.17072,1.17015,1.17067,
1.17050,1.17087,1.17088,1.17058,1.17087,1.17175,1.17160,1.17104,1.17133,1.17165,1.17216,1.17227,1.17189,1.17177]}
2025-07-09 22:25:42,934 [INFO] SEND: {'patterns': ['doji', 'bullishengulfing', 'None', 'None', 'eveningstar', 'None', 'bullishengulfing',
 'None', 'doji', 'bearishengulfing','None', 'None', 'None', 'None', 'None', 'bearishengulfing', 'None', 'None', 'bullishengulfing', 'doji',
 'bearishengulfing', 'None', 'None', 'None', 'None', 'None', 'None', 'None','hammer', 'eveningstar', 'None'], 'log': ['doji=3', 
'bullishengulfing=3', 'eveningstar=2', 'bearishengulfing=3', 'hammer=1', 'total patterns=12'], 'ms': 128.25}
2025-07-09 22:25:42,936 [INFO] 127.0.0.1 - - [09/Jul/2025 22:25:42] "POST /patterns HTTP/1.1" 200 -

Teste no Crash 1000


Conclusão

Em resumo, nossa arquitetura de dois componentes, formada por um EA em MQL5 e um servidor Python responsável pelo reconhecimento dos padrões, demonstrou ser rápida e confiável. O EA organiza os dados OHLC de cada nova barra em um pacote JSON, envia essas informações ao servidor e exibe corretamente no gráfico os rótulos dos padrões retornados. Por sua vez, o serviço Python recebe os dados JSON, processa-os usando nossa lógica de reconhecimento implementada manualmente e registra cada requisição e seu respectivo resultado no log, permitindo acompanhar todas as etapas do processamento. Juntos, os dois componentes formam um fluxo de processamento eficiente e de baixa latência: novas barras são recebidas, os padrões são identificados e o gráfico é atualizado quase instantaneamente. Os registros detalhados e estruturados, tanto no EA quanto no servidor Python, permitem acompanhar o funcionamento do sistema a qualquer momento e facilitam consideravelmente a identificação e a correção de problemas.

De modo geral, a integração se mostrou confiável, o desempenho permaneceu estável e o sistema fornece informações precisas sobre os padrões de candles praticamente em tempo real, conforme planejado. Se necessário, você também pode adicionar outros padrões de candles de acordo com suas necessidades. Como mencionado anteriormente, nos próximos artigos vamos explorar com mais detalhes o uso de bibliotecas Python para reconhecimento de padrões de candles, além de apresentar métodos e ferramentas mais avançados.





   
Chart Projector
Analytical Comment
Analytics Master
Analytics Forecaster
Volatility Navigator
Mean Reversion Signal Reaper
Signal Pulse
Metrics Board
External Flow
VWAP
Heikin Ashi FibVWAP
RSI DIVERGENCE
Parabolic Stop and Reverse (PSAR)
Script Quarters Drawer
Intrusion Detector
TrendLoom Tool Quarters Board
ZigZag Analyzer Correlation Pathfinder Market Structure Flip Detector Tool
Correlation Dashboard Currency Strength Meter
PAQ Analysis Tool
Dual EMA Fractal Breaker
Pin bar, Engulfing and RSI divergence
Liquidity Sweep Opening Range Breakout Tool Boom and Crash Interceptor CCI Zer-Line EA
Candlestick Recognition          

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

Arquivos anexados |
patterns.py (5.24 KB)
Ferramentas de negociação em MQL5 (Parte 4): Aprimorando o painel do scanner multitimeframe com posicionamento dinâmico e recursos de recolhimento e expansão Ferramentas de negociação em MQL5 (Parte 4): Aprimorando o painel do scanner multitimeframe com posicionamento dinâmico e recursos de recolhimento e expansão
Neste artigo, vamos aprimorar o painel do scanner multitimeframe em MQL5, adicionando recursos de movimentação e alternância entre modos de exibição. Implementaremos a possibilidade de arrastar o painel pelo gráfico e de recolhê-lo ou expandi-lo para aproveitar melhor o espaço disponível na tela. Também vamos testar esses aprimoramentos para proporcionar mais flexibilidade às operações de negociação.
Automatização de estratégias de negociação em MQL5 (Parte 23): Recuperação por zonas com trailing stop e lógica de cestas Automatização de estratégias de negociação em MQL5 (Parte 23): Recuperação por zonas com trailing stop e lógica de cestas
Neste artigo, vamos aprimorar nosso sistema de recuperação por zonas (Zone Recovery System) com a implementação de trailing stops e suporte à negociação com múltiplas cestas. Veremos como a arquitetura aprimorada utiliza trailing stops dinâmicos para proteger os lucros e um mecanismo de gerenciamento de cestas para processar com eficiência múltiplos sinais de negociação. Ao longo da implementação e dos testes com dados históricos, demonstraremos um sistema de negociação mais robusto, capaz de se adaptar às diferentes condições de mercado.
Implementação em MQL5 de módulos práticos de outras linguagens (Parte 02): criação de uma biblioteca REQUESTS como a do Python Implementação em MQL5 de módulos práticos de outras linguagens (Parte 02): criação de uma biblioteca REQUESTS como a do Python
Neste artigo, vamos apresentar a implementação de um módulo semelhante ao requests do Python, com o objetivo de simplificar o envio de requisições web e o recebimento de respostas no MetaTrader 5 usando MQL5.
Recursos do Assistente MQL5 que você precisa conhecer (Parte 74): Uso dos padrões Ichimoku e ADX-Wilder com aprendizado supervisionado Recursos do Assistente MQL5 que você precisa conhecer (Parte 74): Uso dos padrões Ichimoku e ADX-Wilder com aprendizado supervisionado
Dando continuidade ao artigo anterior, no qual apresentamos a combinação dos indicadores Ichimoku e ADX, vamos analisar como aprimorá-la por meio do aprendizado supervisionado. O Ichimoku e o ADX se complementam na identificação de níveis de suporte e resistência e na avaliação de tendências. Nossa abordagem de aprendizado supervisionado utiliza uma rede neural com um kernel profundo de mistura espectral (Deep Spectral Mixture Kernel) para refinar as previsões obtidas a partir dessa combinação de indicadores. Como de costume, essa implementação é feita em um arquivo personalizado que contém a classe de sinais (signal class), que se integra ao Assistente MQL5 para criar um EA.