English Русский 中文 Español Deutsch 日本語
preview
Integração de um modelo de IA a uma estratégia de trading existente em MQL5

Integração de um modelo de IA a uma estratégia de trading existente em MQL5

MetaTrader 5Negociação |
41 1
Hlomohang John Borotho
Hlomohang John Borotho

Introdução

Neste artigo, abordaremos a integração de um modelo de IA a uma estratégia de trading MQL5 já existente, usando Order Block com níveis de Fibonacci do artigo anterior. Muitas estratégias existentes em MQL5 se baseiam em um conjunto de indicadores, limiares predefinidos ou padrões predefinidos. A eficácia dessas soluções pode variar em diferentes ciclos de mercado. Essas estratégias não conseguem aprender com dados históricos, reconhecer padrões complexos nem se ajustar dinamicamente em função das mudanças nas condições do mercado.

A adição de um modelo de IA à estratégia de trading pode ajudar a superar essas limitações, ao incorporar capacidade de adaptação e tomada de decisão baseada em machine learning. Com técnicas como modelos Long Short-Term Memory (LSTM) e análise preditiva, a IA é capaz de analisar grandes volumes de dados históricos e dados em tempo real para tomar decisões de trading mais precisas. Ao contrário de estratégias rígidas, com regras predefinidas, sistemas com IA se adaptam dinamicamente e aprimoram suas abordagens ao aprender com as mudanças nas condições de mercado. Isso pode proporcionar maior precisão nos pontos de entrada e saída, gestão de risco mais eficiente e aumento da lucratividade ao longo do tempo.


Primeiros passos

Para começar, precisamos converter o código MQL5 existente para Python. Como estamos integrando modelos à estratégia de trading, é indispensável ter uma versão da lógica original em Python. Isso permitirá incorporar aprimoramentos com IA sem comprometer a funcionalidade principal da estratégia. A versão em Python deve reproduzir com precisão o comportamento do script em MQL5, incluindo a lógica de execução de operações, o cálculo de indicadores, a gestão de ordens e as regras de gestão de risco. Nesse caso, o modelo de IA interagirá com um sistema idêntico ao usado no MetaTrader 5, o que possibilita testes e otimização precisos antes da integração completa. Depois de concluir essa etapa, será possível iniciar a integração de modelos de machine learning, treinar a IA com dados de mercado e criar um sistema de trading inteligente e adaptativo.

Código MQL5:

#include <Trade/Trade.mqh>
#include <Arrays\ArrayObj.mqh>
CTrade trade;

#define BullOB clrLime
#define BearOB clrRed

//+------------------------------------------------------------------+
//|                           Global vars                            |
//+------------------------------------------------------------------+
double Lots = 0.01;
int takeProfit = 170;
int length = 100;
input double stopLoss = 350;
input double Mgtn = 0.85;

bool isBullishOB = false; 
bool isBearishOB = false;

input int Time1Hstrt = 3;
input int Time1Hend = 4;

class COrderBlock : public CObject {
public:
   int direction;
   datetime time;
   double high;
   double low;
   bool traded;

   string rectName;  
   string tradeRectName; 

   COrderBlock(int dir, datetime t, double h, double l) {
      direction = dir;
      time = t;
      high = h;
      low = l;
      traded = false;
      rectName = "";
      tradeRectName = "";
      
   }

   void draw(datetime tmS, datetime tmE, color clr) {
      rectName = "OB REC" + TimeToString(time);
      ObjectCreate(0, rectName, OBJ_RECTANGLE, 0, time, low, tmS, high);
      ObjectSetInteger(0, rectName, OBJPROP_FILL, true);
      ObjectSetInteger(0, rectName, OBJPROP_COLOR, clr);

      tradeRectName = "OB trade" + TimeToString(time);
      ObjectCreate(0, tradeRectName, OBJ_RECTANGLE, 0, tmS, high, tmE, low);
      ObjectSetInteger(0, tradeRectName, OBJPROP_FILL, true);
      ObjectSetInteger(0, tradeRectName, OBJPROP_COLOR, clr);
   }
   
   void removeDrawings() {
      if (ObjectFind(0, rectName) != -1) {
         ObjectDelete(0, rectName); // Delete the main rectangle
      }
      if (ObjectFind(0, tradeRectName) != -1) {
         ObjectDelete(0, tradeRectName); // Delete the trade rectangle
      }
   }
};
// Pointer to CArrayObj

// Declare the dynamic array to hold order blocks
CArrayObj *orderBlocks; 
color OBClr;
datetime T1;
datetime T2;

int OnInit() {
   orderBlocks = new CArrayObj(); // Allocate memory for the array
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason) {
   ObjectsDeleteAll(0, "OB");
   
   // Clear and free the order blocks
   if (orderBlocks != NULL) {
      orderBlocks.Clear(); // This will delete objects inside
      delete orderBlocks; // Free the array memory
      orderBlocks = NULL;
   }
}

void OnTick() {
   if (isNewBar()) {
      static int prevDay = 0;
      
      MqlDateTime structTime;
      TimeCurrent(structTime);
      structTime.min = 0;
      structTime.sec = 0;
      
      structTime.hour = Time1Hstrt;
      datetime timestrt = StructToTime(structTime);
      
      structTime.hour = Time1Hend;
      datetime timend = StructToTime(structTime);
      
      getOrderB();
      double Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

      for (int i = orderBlocks.Total() - 1; i >= 0; i--) {
         COrderBlock *OB = (COrderBlock *)orderBlocks.At(i);

         if (CheckPointer(OB) != POINTER_INVALID && !OB.traded) {
         
            if(OB.direction > 0 && Ask < OB.high){
               double entry = Ask;
               double tp = getHigh(iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, iBarShift(_Symbol, PERIOD_CURRENT, OB.time)));
               double sl = NormalizeDouble(OB.low - Mgtn, _Digits);
   
               T2 = getTime(0);
               OB.draw(T1, T2, BullOB);
               trade.Buy(Lots, _Symbol, entry, sl, tp, "OB buy");
               OB.traded = true;
               //OB.removeDrawings();
               orderBlocks.Delete(i); // Delete from array
               delete OB; // Free memory
               
               
            }
         }
         if(CheckPointer(OB) != POINTER_INVALID && !OB.traded){
            if (OB.direction < 0 && Bid > OB.low) {
                  double entry = Bid;
                  double tp = getLow(iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, iBarShift(_Symbol, PERIOD_CURRENT, OB.time)));
                  double sl = NormalizeDouble(OB.high + Mgtn, _Digits);
      
                  T2 = getTime(0);
                  OB.draw(T1, T2, BearOB);
                  trade.Sell(Lots, _Symbol, entry, sl, tp, "OB sell");
                  OB.traded = true;
                  //OB.removeDrawings();
                  orderBlocks.Delete(i); // Delete from array
                  delete OB; // Free memory
                  

            }
         }
      }
   }
}

void getOrderB(){

   static int prevDay = 0;
   
   MqlDateTime structTime;
   TimeCurrent(structTime);
   structTime.min = 0;
   structTime.sec = 0;
   
   structTime.hour = Time1Hstrt;
   datetime timestrt = StructToTime(structTime);
   
   structTime.hour = Time1Hend;
   datetime timend = StructToTime(structTime);
   
   int visibleBars = (int)ChartGetInteger(0,CHART_VISIBLE_BARS);
         
   for(int i = 1; i <= visibleBars; i++){
      if(getOpen(i) < getClose(i)){ // index is i since the loop starts from i which is = 1 "for(int i = 1)..."
         if(getOpen(i + 2) < getClose(i + 2)){
            if(getOpen(i + 3) > getClose(i + 3) && getOpen(i + 3) < getClose(i + 2)){
               Print("Bullish Order Block confirmed at: ", TimeToString(getTime(i + 2), TIME_DATE||TIME_MINUTES));
               //isBullishOB = true;
               //OB = new COrderBlock();
               int direction = 1;
               datetime time = getTime(i + 3);
               double high = getHigh(i + 3);
               double low = getLow(i + 3);
               isBullishOB = true;
               
               OBClr = isBullishOB ? BullOB : BearOB;
               
               // specify strt time
               T1 = time;
               // reset BULLOB flag
               isBullishOB = false;
               // crucial
               COrderBlock *newOB = new COrderBlock(direction, time, high, low);
               orderBlocks.Add(newOB);
               break;
               
               //delete newOB;
            }
         }
      }
      if(getOpen(i) > getClose(i)){
         if(getOpen(i + 2) > getClose(i + 2)){
            if(getOpen(i + 3) < getClose(i + 3) && getOpen(i + 3) < getClose(i + 2)){
               Print("Bearish Order Block confirmed at: ", TimeToString(getTime(i + 2), TIME_DATE||TIME_MINUTES));
               //isBearishOB = true;
               //OB = new COrderBlock();
               int direction = -1;
               datetime time = getTime(i + 3);
               double high = getHigh(i + 3);
               double low = getLow(i + 3);
               isBearishOB = true;
               
               OBClr = isBearishOB ? BearOB : BullOB;
               
               T1 = time;
               
               // reset the BEAROB flag
               isBearishOB = false;
               // crusssial
               COrderBlock *newOB = new COrderBlock(direction, time, high, low);
               orderBlocks.Add(newOB);
               break;
               
               //delete newOB;
            }
         }
      }
    }
      
}

double getHigh(int index) {
    return iHigh(_Symbol, _Period, index);
}

double getLow(int index) {
    return iLow(_Symbol, _Period, index);
}

double getOpen(int index){
   return iOpen(_Symbol, _Period, index);
}

double getClose(int index){
   return iClose(_Symbol, _Period, index);
}

datetime getTime(int index) {
    return iTime(_Symbol, _Period, index);
}

bool isNewBar() {
   // Memorize the time of opening of the last bar in the static variable
   static datetime last_time = 0;
   
   // Get current time
   datetime lastbar_time = (datetime)SeriesInfoInteger(Symbol(), Period(), SERIES_LASTBAR_DATE);

   // First call
   if (last_time == 0) {
      last_time = lastbar_time;
      return false;
   }

   // If the time differs (new bar)
   if (last_time != lastbar_time) {
      last_time = lastbar_time;
      return true;
   }

   // If no new bar, return false
   return false;
}

void deler(){
   static int prevDay = 0;
   
   MqlDateTime structTime;
   TimeCurrent(structTime);
   structTime.min = 0;
   structTime.sec = 0;
   
   structTime.hour = Time1Hstrt;
   datetime timestrt = StructToTime(structTime);
   
   structTime.hour = Time1Hend;
   datetime timend = StructToTime(structTime);

}

A funcionalidade e a estrutura desse código foram discutidas no artigo anterior. A estratégia identifica blocos de ordens (order blocks), padrões específicos de velas que são considerados sinais de possíveis reversões de mercado. Implementamos essa estratégia na forma de um EA completo, que combina análise por price action com execução automatizada de operações. A programação orientada a objetos é implementada por meio da classe COrderBlock, que armazena os dados dos padrões, como timestamps, limites de preço e direção, e controla a visualização no gráfico. O array dinâmico CArrayObj acompanha os blocos de ordens ativos, gerencia a memória e identifica os padrões em tempo real em múltiplos gráficos.

A função getOrderB() é responsável pelo reconhecimento dos padrões. Ela varre as velas históricas em busca de sequências específicas de alta e de baixa. Quando três velas consecutivas de alta aparecem após uma vela de baixa, isso é considerado um bloco de ordens de alta. Da mesma forma, um bloco de ordens de baixa consiste em três velas de baixa que vêm após uma vela de alta. Os padrões identificados são criados como objetos COrderBlock com sinalizadores de direção (1 para alta, -1 para baixa) e armazenados no vetor dinâmico. O código inclui filtros de tempo configuráveis (Time1Hstrt, Time1Hend), que permitem ao usuário escolher as sessões de trading desejadas. Isso tende a aumentar a relevância dos padrões.

A cada nova vela, identificada por meio de isNewBar(), o EA processa os blocos de ordens ativos na função OnTick(). Se um padrão de alta for encontrado, o EA abre uma posição longa quando o preço rompe acima da máxima do bloco e define os níveis de stop-loss abaixo da mínima do padrão, considerando a margem (Mtgn). As operações vendidas são ativadas quando o preço rompe a mínima do bloco, com stops acima da máxima do padrão. O EA usa CTrade para controlar as ordens e calcula os níveis de take-profit com base nas máximas e mínimas locais mais recentes. As operações executadas removem automaticamente os blocos de ordens relacionados e as marcações gráficas, para evitar a duplicação de sinais.

O sistema tem configurações de proteção da operação: as distâncias de stop-loss são ajustadas aos requisitos da corretora, o tamanho da posição é fixado no nível de Lots, e retângulos coloridos são exibidos no gráfico para facilitar a visualização. Todos os parâmetros necessários estão disponíveis para ajuste, como stop-loss (StopLoss), margem de lucro (Mtgn) e horário da sessão de trading. Ou seja, o código combina reconhecimento de padrões totalmente algorítmico com elementos configuráveis para levar em conta restrições da corretora, como as distâncias mínimas de stop e o spread.

Versão em Python:

Antes de começar, como sempre, precisamos de um conjunto de dados históricos de mercado. Esses dados são necessários para treinar o modelo de IA e verificar a precisão da estratégia. Espero que, neste ponto, você já esteja familiarizado com a obtenção de dados históricos. Caso contrário, recomendo consultar a primeira parte do meu guia sobre integração do MQL5 com pacotes de processamento de dados. Então, carregamos os dados históricos.

import pandas as pd

# Load historical data
file_path = '/home/int_junkie/Documents/DataVisuals/AI inside MQL5/XAUUSD_H1.csv'
data = pd.read_csv(file_path)

# Display the first few rows and column names
print(data.head())
print(data.columns)

Esse código em Python processa os dados históricos de mercado que serão usados no treinamento do modelo de IA. O primeiro passo é criar um pipeline de dados para carregar, pré-processar e estruturar os dados históricos de preços, incluindo características-chave como abertura, máxima, mínima, fechamento, volume e os indicadores técnicos utilizados. Essa estrutura ajudará o modelo a identificar padrões relevantes no comportamento do mercado.

Também adicionamos funcionalidade para treinar um modelo LSTM (Long Short-Term Memory). Trata-se de uma rede neural recorrente (RNN) especializada, capaz de analisar dados sequenciais e capturar dependências de longo prazo. O modelo é treinado em sincronia com a lógica de compra e venda da estratégia MQL5 original, para que o modelo aprenda a tomar decisões de trading com base nos preços históricos. O modelo LSTM relaciona dados passados aos sinais correspondentes de compra/venda e melhora gradualmente sua capacidade de previsão, para prever com mais precisão movimentos potenciais do mercado. Essa abordagem combina a estratégia tradicional com IA, aumentando a adaptabilidade e a precisão do sistema.

import pandas as pd
import numpy as np
from datetime import datetime
from keras.models import Sequential
from keras.layers import LSTM, Dense
import tensorflow as tf

# Constants
LOTS = 0.01
TAKE_PROFIT = 170
STOP_LOSS = 350
MGTN = 0.85
TIME1_HSTRT = 3
TIME1_HEND = 4

# Helper functions
def get_high(data, index):
    return data.iloc[index]['<HIGH>']

def get_low(data, index):
    return data.iloc[index]['<LOW>']

def get_open(data, index):
    return data.iloc[index]['<OPEN>']

def get_close(data, index):
    return data.iloc[index]['<CLOSE>']

def get_time(data, index):
    return data.iloc[index]['DATETIME']  # Combined datetime column

def is_new_bar(current_time, last_time):
    return current_time != last_time

class OrderBlock:
    def __init__(self, direction, time, high, low):
        self.direction = direction
        self.time = time
        self.high = high
        self.low = low
        self.traded = False

def get_order_blocks(data):
    order_blocks = []
    visible_bars = len(data)

    for i in range(1, visible_bars - 3):  # Adjusted to avoid index errors
        if get_open(data, i) < get_close(data, i):  # Bullish condition
            if get_open(data, i + 2) < get_close(data, i + 2):
                if get_open(data, i + 3) > get_close(data, i + 3) and get_open(data, i + 3) < get_close(data, i + 2):
                    print(f"Bullish Order Block confirmed at: {get_time(data, i + 2)}")
                    direction = 1
                    time = get_time(data, i + 3)
                    high = get_high(data, i + 3)
                    low = get_low(data, i + 3)
                    order_blocks.append(OrderBlock(direction, time, high, low))
                    break

        if get_open(data, i) > get_close(data, i):  # Bearish condition
            if get_open(data, i + 2) > get_close(data, i + 2):
                if get_open(data, i + 3) < get_close(data, i + 3) and get_open(data, i + 3) < get_close(data, i + 2):
                    print(f"Bearish Order Block confirmed at: {get_time(data, i + 2)}")
                    direction = -1
                    time = get_time(data, i + 3)
                    high = get_high(data, i + 3)
                    low = get_low(data, i + 3)
                    order_blocks.append(OrderBlock(direction, time, high, low))
                    break

    return order_blocks

def simulate_trading(data, order_blocks):
    trades = []
    last_time = None

    for i, row in data.iterrows():
        current_time = row['DATETIME']
        if is_new_bar(current_time, last_time):
            last_time = current_time

            bid = row['<CLOSE>']  # Assuming bid price is close price
            ask = row['<CLOSE>']  # Assuming ask price is close price

            for ob in order_blocks:
                if not ob.traded:
                    if ob.direction > 0 and ask < ob.high:  # Buy condition
                        entry = ask
                        tp = data.iloc[:i]['<HIGH>'].max()  # Take profit as highest high
                        sl = ob.low - MGTN  # Stop loss
                        trades.append({
                            'time': current_time,
                            'direction': 'buy',
                            'entry': entry,
                            'tp': tp,
                            'sl': sl
                        })
                        ob.traded = True

                    if ob.direction < 0 and bid > ob.low:  # Sell condition
                        entry = bid
                        tp = data.iloc[:i]['<LOW>'].min()  # Take profit as lowest low
                        sl = ob.high + MGTN  # Stop loss
                        trades.append({
                            'time': current_time,
                            'direction': 'sell',
                            'entry': entry,
                            'tp': tp,
                            'sl': sl
                        })
                        ob.traded = True

    return trades

O código implementa uma estratégia de trading baseada na identificação de blocos de ordens e na simulação de operações com base em dados históricos. Começamos importando as bibliotecas Pandas para processamento de dados, NumPy para operações numéricas e Keras/TensorFlow para a integração de IA. O script define os principais parâmetros de trading: tamanho do lote (LOTS), take-profit (TAKE_PROFIT), stop-loss (STOP_LOSS) e coeficiente de gestão de risco (MGTN). As funções auxiliares obtêm dados de preço OHLC e timestamps. A classe OrderBlock armazena informações sobre os blocos de ordens de alta e de baixa identificados, que mostram onde participantes institucionais podem ter posicionado ordens de grande porte.

A função get_order_blocks varre os dados históricos e identifica potenciais blocos de ordens com base em sequências de movimentos de preço. Ela registra o tempo, a máxima e a mínima de cada bloco. Quando um bloco de ordens é identificado, a função simulate_trading simula uma operação. Ela percorre os dados históricos e verifica o surgimento de novas velas e se as condições de preço atendem aos critérios de compra ou venda. Se a condição for atendida, a operação é registrada com definição dinâmica do preço de entrada, do take-profit e do stop-loss com base nos extremos anteriores. Isso nos permitirá, em primeiro lugar, testar a estratégia no histórico e, em segundo, estabelecer a base para a integração posterior do modelo de IA.

# Columns: ['<DATE>', '<TIME>', '<OPEN>', '<HIGH>', '<LOW>', '<CLOSE>']
data = pd.read_csv('/home/int_junkie/Documents/DataVisuals/AI inside MQL5/XAUUSD_H1.csv', delimiter='\t')

# Combine DATE and TIME into a single DATETIME column
data['DATETIME'] = pd.to_datetime(data['<DATE>'] + ' ' + data['<TIME>'])

# Drop the original DATE and TIME columns
data.drop(columns=['<DATE>', '<TIME>'], inplace=True)

# Step 1: Detect order blocks
order_blocks = get_order_blocks(data)

# Step 2: Simulate trading based on order blocks
trades = simulate_trading(data, order_blocks)

Após a junção, removemos as datas e os horários para simplificar o dataset. Em seguida, o script chama get_order_blocks(data), que identifica potenciais blocos de ordens de alta e de baixa. Quando esses blocos são encontrados, simulate_trading(data, order_blocks) executa o teste, verificando se esses blocos são acionados nas condições de mercado e simulando operações de acordo com as regras definidas de entrada, take-profit e stop-loss. Assim, a eficácia da estratégia é avaliada com base em dados históricos.

# Features: Historical OHLC data
# Labels: Buy (1), Sell (-1), Hold (0)
labels = []
for i, row in data.iterrows():
    label = 0  # Hold by default
    for trade in trades:
        if trade['time'] == row['DATETIME']:
            label = 1 if trade['direction'] == 'buy' else -1
    labels.append(label)

data['label'] = labels

# Step 4: Train LSTM model (example using Keras)
from keras.models import Sequential
from keras.layers import LSTM, Dense

# Prepare data for LSTM
def create_sequences(data, seq_length):
    X, y = [], []
    for i in range(len(data) - seq_length):
        X.append(data.iloc[i:i + seq_length][['<OPEN>', '<HIGH>', '<LOW>', '<CLOSE>']].values)
        y.append(data.iloc[i + seq_length]['label'])
    return np.array(X), np.array(y)

seq_length = 50  # Sequence length for LSTM
X, y = create_sequences(data, seq_length)

# Build LSTM model
model = Sequential()
model.add(LSTM(50, input_shape=(seq_length, 4)))  # 4 features: open, high, low, close
model.add(Dense(1, activation='tanh'))  # Output: -1 (sell), 0 (hold), 1 (buy)
model.compile(optimizer='adam', loss='mse')

# Train the model
model.fit(X, y, epochs=20, batch_size=32)

# Save the model
model.save('lstm_trading_model.h5')


Informações exibidas:


Nesta parte, treinamos o modelo LSTM para prever decisões de trading com base em preços históricos. O dataset é rotulado com três sinais: 1 (compra), -1 (venda), 0 (manutenção). Essa marcação é atribuída com base nos timestamps: se houve uma operação naquele momento, mostramos sua direção; caso contrário, 0. Isso permite realizar aprendizado supervisionado, para que o modelo aprenda a relacionar sequências de dados de mercado com ações futuras.

Para treinar o modelo LSTM, estruturamos os dados em sequências de 50 etapas a partir dos preços OHLC. Cada sequência é usada para prever o sinal no passo seguinte. A arquitetura do modelo inclui:

  • Camada LSTM (50 unidades) para analisar padrões temporais nos quatro atributos de entrada (OHLC).
  • Camada de saída densa com função de ativação tanh para gerar previsões no intervalo de -1 a 1.

O modelo é treinado durante 20 épocas com o otimizador Adam e a função de perda MSE. Após o treinamento, salvamos o modelo como lstm_trading_model.h5. Agora o modelo está pronto e pode ser incorporado à estratégia para gerar sinais em tempo real.



Implantação do modelo

Após a serialização do modelo LSTM no formato .h5, a próxima etapa é incorporá-lo ao ecossistema MQL5. Não há integração direta entre Python e MQL5, portanto criamos uma camada de comunicação entre o framework de ML em Python e a infraestrutura nativa de trading do MQL5. A solução padrão é implantar um microsserviço em Python, como Flask ou FastAPI, que armazena o modelo treinado. Esse servidor funciona como um endpoint. Ele recebe dados de mercado do MQL5, executa a inferência da LSTM e retorna sinais de trading em tempo real. No lado do MQL5, o EA usa a interface WebRequest() para transmitir os dados e processar as respostas em JSON, convertendo as previsões em ações.

Após essa implementação, a etapa seguinte é integrar a estratégia em tempo real. O EA envia sequências de dados, por exemplo, 50 barras OHLC, ao servidor de inferência em intervalos configuráveis. O serviço em Python pré-processa os dados, executa a inferência da LSTM e retorna recomendações probabilísticas de compra, venda ou manutenção, com um indicador de confiança. Esses sinais são encaminhados ao pipeline do EA, onde são aplicados parâmetros de risco, como stop-loss dinâmico, metas de lucro e algoritmos para calcular o volume das posições. Para reduzir os riscos operacionais, recomenda-se uma implantação por etapas: validação em ambiente de demonstração, monitoramento da latência da inferência e adoção de cenários de contingência, por exemplo, o retorno a estratégias baseadas em indicadores técnicos, para preservar a funcionalidade em caso de falhas do servidor ou anomalias nas previsões.


Conclusão

Neste projeto, partimos de uma estratégia MQL5 existente e a aprimoramos ao integrar uma lógica de decisão baseada em IA com o uso de LSTM. Primeiro, traduzimos a lógica principal do MQL5 para Python, reproduzindo o comportamento da estratégia com dados históricos OHLC. Em seguida, identificamos os principais sinais de trading a partir dos blocos de ordens (order blocks) e simulamos operações para gerar dados rotulados para treinar a IA. Depois disso, treinamos a LSTM com sequências de preços históricos para prever ações: comprar, vender ou manter. Ao final, salvamos o modelo no formato .h5, e ele fica pronto para aplicação em trading.

A integração de IA a uma estratégia tradicional oferece vantagens significativas. Ao contrário de uma lógica estática com condições fixas, o modelo LSTM é capaz de aprender padrões complexos do comportamento dos preços e de se adaptar às mudanças nas condições de mercado. Isso torna a estratégia mais flexível, potencialmente mais precisa e menos suscetível a sinais falsos. O operador passa a contar com um sistema que combina a estrutura e a confiabilidade das regras técnicas com a adaptabilidade e a capacidade de aprendizado do machine learning.

A abordagem híbrida melhora as decisões de entrada e saída e viabiliza uma gestão de risco em tempo real mais inteligente e orientada por dados. Ao contrário de uma lógica estática com condições fixas, o modelo LSTM é capaz de aprender padrões complexos do comportamento dos preços e de se adaptar às mudanças nas condições de mercado. Isso torna a estratégia mais flexível, potencialmente mais precisa e menos suscetível a sinais falsos. O operador passa a contar com um sistema que combina a estrutura e a confiabilidade das regras técnicas com a adaptabilidade e a capacidade de aprendizado do machine learning. A abordagem híbrida melhora as decisões de entrada e saída e viabiliza uma gestão de risco em tempo real mais inteligente e orientada por dados.

Nome do arquivo
Descrição
FIB_OB.mq5 Arquivo com a estratégia MQL5 original
FIB_OB to AI.ipynb
Arquivo que contém o notebook para converter a lógica da estratégia, treinar o modelo e salvar o modelo
XAUUSD_H1.csv
Arquivo com os dados históricos de preço do XAUUSD


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

Arquivos anexados |
Últimos Comentários | Ir para discussão (1)
malky3200
malky3200 | 28 abr. 2025 em 10:25
Pergunta.... Há algum motivo para você ter definido a época como 20?
É possível fazer com que a IA aprenda de forma contínua?
Caminhe em novos trilhos: Personalize indicadores no MQL5 Caminhe em novos trilhos: Personalize indicadores no MQL5
Vou agora listar todas as possibilidades novas e recursos do novo terminal e linguagem. Elas são várias, e algumas novidades valem a discussão em um artigo separado. Além disso, não há códigos aqui escritos com programação orientada ao objeto, é um tópico muito importante para ser simplesmente mencionado em um contexto como vantagens adicionais para os desenvolvedores. Neste artigo vamos considerar os indicadores, sua estrutura, desenho, tipos e seus detalhes de programação em comparação com o MQL4. Espero que este artigo seja útil tanto para desenvolvedores iniciantes quanto para experientes, talvez alguns deles encontrem algo novo.
De Iniciante a Especialista: Indicador de Força de Suporte e Resistência (SRSI) De Iniciante a Especialista: Indicador de Força de Suporte e Resistência (SRSI)
Neste artigo, compartilharemos insights sobre como utilizar a programação em MQL5 para identificar níveis de mercado — diferenciando entre níveis de preço mais fracos e mais fortes. Desenvolveremos completamente um indicador funcional de Força de Suporte e Resistência (SRSI).
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.
Estratégias de trading de rompimento: análise dos principais métodos Estratégias de trading de rompimento: análise dos principais métodos
As estratégias de rompimento da faixa de abertura (Opening Range Breakout, ORB) partem da ideia de que a faixa inicial de negociação, formada logo após a abertura do mercado, reflete níveis de preço relevantes, quando compradores e vendedores chegam a um acordo sobre o valor. Ao identificar rompimentos de uma determinada faixa para cima ou para baixo, os traders podem aproveitar o momentum que costuma surgir quando a direção do mercado fica mais clara. Neste artigo, vamos analisar três estratégias ORB adaptadas a partir de materiais da Concretum Group.