MQL5 — Integração Externa e Recursos Avançados
WebRequest, integração com Python via sockets, ONNX (machine learning), banco de dados SQLite, OnTimer e serviços em MQL5.
MQL5 — Integração Externa e Recursos Avançados
O MQL5 vai muito além de indicadores e EAs simples. É possível consumir APIs REST, integrar modelos de machine learning via ONNX, rodar Python em paralelo, armazenar dados em SQLite e criar serviços que rodam continuamente em background.
Fundamentos: MQL5 — Fundamentos
WebRequest — Consumir APIs REST
O WebRequest permite fazer chamadas HTTP/HTTPS diretamente do MQL5.
Pré-requisito: adicionar o domínio em Tools > Options > Expert Advisors > Allow WebRequest for listed URL.
#include <JAson.mqh> // biblioteca JSON da MQL5 Community
string GetEconomicCalendar()
{
string url = "https://api.tradingeconomics.com/calendar?c=YOUR_KEY&f=json";
string headers = "Content-Type: application/json\r\n";
char postData[];
char result[];
string resultHeaders;
int code = WebRequest("GET", url, headers, 5000, postData, result, resultHeaders);
if(code == 200)
return CharArrayToString(result);
else
{
Print("WebRequest erro: ", code, " | ", GetLastError());
return "";
}
}
// POST com JSON body
bool SendWebhookAlert(string message)
{
string url = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL";
string body = "{\"text\":\"" + message + "\"}";
char postData[];
StringToCharArray(body, postData, 0, StringLen(body));
char result[];
string headers = "Content-Type: application/json\r\n";
string resHeaders;
int code = WebRequest("POST", url, headers, 5000, postData, result, resHeaders);
return (code == 200 || code == 204);
}OnTimer — Execução Periódica
Útil para tarefas que não dependem de ticks: verificar calendário econômico, enviar relatórios, monitorar equity.
int OnInit()
{
EventSetTimer(60); // dispara OnTimer() a cada 60 segundos
return(INIT_SUCCEEDED);
}
void OnTimer()
{
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double drawdown = (balance - equity) / balance * 100;
if(drawdown > 5.0)
SendWebhookAlert("ALERTA: Drawdown de " + DoubleToString(drawdown, 2) + "%");
}
void OnDeinit(const int reason)
{
EventKillTimer();
}Serviços (Services) — Background Contínuo
Serviços rodam independentemente de qualquer gráfico, sem precisar de um EA anexado. Ideais para coleta de dados e monitoramento.
// Arquivo: MQL5/Services/DataCollector.mq5
void OnStart()
{
Print("Serviço iniciado");
while(!IsStopped())
{
MqlTick tick;
if(SymbolInfoTick("EURUSD", tick))
{
int file = FileOpen("eurusd_ticks.csv",
FILE_WRITE | FILE_READ | FILE_CSV | FILE_ANSI);
FileSeek(file, 0, SEEK_END);
FileWrite(file,
TimeToString(tick.time, TIME_DATE | TIME_SECONDS),
DoubleToString(tick.bid, 5),
DoubleToString(tick.ask, 5),
(long)tick.volume);
FileClose(file);
}
Sleep(1000); // em Services, Sleep() é permitido
}
Print("Serviço encerrado");
}SQLite — Banco de Dados Embutido
MQL5 inclui suporte nativo ao SQLite desde a build 2455.
#include <sqlite3.mqh> // disponível no CodeBase MQL5
int db;
int OnInit()
{
db = DatabaseOpen("trades.db", DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE);
DatabaseExecute(db,
"CREATE TABLE IF NOT EXISTS trades ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"symbol TEXT,"
"openTime DATETIME,"
"closeTime DATETIME,"
"lots REAL,"
"profit REAL"
")");
return INIT_SUCCEEDED;
}
void SaveTrade(string symbol, datetime openTime, datetime closeTime,
double lots, double profit)
{
string sql = StringFormat(
"INSERT INTO trades (symbol, openTime, closeTime, lots, profit) "
"VALUES ('%s', %d, %d, %.2f, %.2f)",
symbol, openTime, closeTime, lots, profit);
DatabaseExecute(db, sql);
}
void OnDeinit(const int reason)
{
DatabaseClose(db);
}ONNX — Machine Learning no MetaTrader 5
O MT5 suporta modelos ONNX (Open Neural Network Exchange) nativamente desde a build 3325. É possível treinar modelos em Python (scikit-learn, TensorFlow, PyTorch) e executar diretamente no EA.
Fluxo completo
Python (treino) MQL5 (inferência)
──────────────── ───────────────────
1. Coleta dados históricos 4. Carrega modelo .onnx
2. Feature engineering 5. Prepara input (normalizado)
3. Treina e exporta para .onnx → 6. OnnxRun() para previsão
7. Usa output como sinalExemplo de inferência em MQL5
#include <ONNX/OnnxModel.mqh>
long g_model;
float g_input[1][10]; // 1 amostra, 10 features
float g_output[1][1]; // 1 amostra, 1 saída
int OnInit()
{
// Carregar modelo treinado em Python
g_model = OnnxCreate("model.onnx", ONNX_DEFAULT);
if(g_model == INVALID_HANDLE)
{
Print("Falha ao carregar ONNX: ", GetLastError());
return INIT_FAILED;
}
// Configurar shapes
ulong inputShape[] = {1, 10};
ulong outputShape[] = {1, 1};
OnnxSetInputShape(g_model, 0, inputShape);
OnnxSetOutputShape(g_model, 0, outputShape);
return INIT_SUCCEEDED;
}
double PredictDirection()
{
// Preencher features (ex: retornos normalizados)
MqlRates rates[];
ArraySetAsSeries(rates, true);
CopyRates(_Symbol, PERIOD_H1, 1, 11, rates);
for(int i = 0; i < 10; i++)
g_input[0][i] = (float)((rates[i].close - rates[i+1].close) / rates[i+1].close);
// Inferência
if(!OnnxRun(g_model, ONNX_DEFAULT, g_input, g_output))
{
Print("Erro na inferência ONNX: ", GetLastError());
return 0;
}
return g_output[0][0]; // probabilidade de subida (0 a 1)
}
void OnDeinit(const int reason)
{
OnnxRelease(g_model);
}Treinamento em Python (exemplo com scikit-learn)
import MetaTrader5 as mt5
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
import skl2onnx
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
# Conectar ao MT5
mt5.initialize()
# Baixar dados
rates = mt5.copy_rates_from_pos("EURUSD", mt5.TIMEFRAME_H1, 0, 5000)
df = pd.DataFrame(rates)
# Feature engineering
for i in range(1, 11):
df[f'ret_{i}'] = df['close'].pct_change(i)
df['target'] = (df['close'].shift(-1) > df['close']).astype(int)
df.dropna(inplace=True)
features = [f'ret_{i}' for i in range(1, 11)]
X, y = df[features].values.astype(np.float32), df['target'].values
# Treinar
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X, y)
# Exportar para ONNX
initial_type = [('float_input', FloatTensorType([None, 10]))]
onnx_model = convert_sklearn(model, initial_types=initial_type,
target_opset=12)
with open("model.onnx", "wb") as f:
f.write(onnx_model.SerializeToString())
print("Modelo exportado: model.onnx")
mt5.shutdown()Python + MetaTrader 5 via biblioteca oficial
A MetaQuotes mantém a biblioteca MetaTrader5 para Python, que permite controle total do terminal.
import MetaTrader5 as mt5
# Inicializar
mt5.initialize()
# Informações da conta
info = mt5.account_info()
print(f"Balance: {info.balance} | Equity: {info.equity}")
# Dados históricos
import pandas as pd
rates = mt5.copy_rates_from_pos("EURUSD", mt5.TIMEFRAME_M15, 0, 1000)
df = pd.DataFrame(rates)
df['time'] = pd.to_datetime(df['time'], unit='s')
# Enviar ordem
request = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": "EURUSD",
"volume": 0.1,
"type": mt5.ORDER_TYPE_BUY,
"price": mt5.symbol_info_tick("EURUSD").ask,
"sl": mt5.symbol_info_tick("EURUSD").ask - 0.0050,
"tp": mt5.symbol_info_tick("EURUSD").ask + 0.0100,
"comment": "Python order",
"magic": 12345,
}
result = mt5.order_send(request)
print(f"Retcode: {result.retcode} | Deal: {result.deal}")
mt5.shutdown()OnChartEvent — Interface interativa
Permite criar painéis com botões e inputs diretamente no gráfico.
void OnChartEvent(const int id, const long &lparam,
const double &dparam, const string &sparam)
{
// Clique em objeto gráfico (botão)
if(id == CHARTEVENT_OBJECT_CLICK)
{
if(sparam == "btn_buy")
{
CTrade trade;
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
trade.Buy(0.1, _Symbol, ask, ask - 50*_Point, ask + 100*_Point);
}
if(sparam == "btn_close_all")
CloseAllPositions();
}
// Clique no gráfico (coordenadas de preço)
if(id == CHARTEVENT_CLICK)
{
double price = ChartGetDouble(0, CHART_PRICE_MIN) + dparam;
Print("Clique no preço: ", price);
}
}
// Criar botão no gráfico
void CreateButton(string name, string text, int x, int y)
{
ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_XSIZE, 100);
ObjectSetInteger(0, name, OBJPROP_YSIZE, 30);
}Referências
MQL5 — Otimização e Robustez de Estratégias
Walk forward testing, análise de sensibilidade, evitar overfitting, métricas de qualidade e validação estatística de Expert Advisors no Strategy Tester do MetaTrader 5.
Automação no TradingView: Pine Script v6, indicadores e webhooks
Guia completo para automação de estratégias no TradingView usando Pine Script v6.