MQL5 — Event Handlers: Estrutura de Execução
Guia completo dos 14 event handlers do MQL5: OnInit, OnDeinit, OnTick, OnCalculate, OnTimer, OnTrade, OnTradeTransaction, OnChartEvent, OnTester e outros — com assinaturas, códigos de retorno e exemplos práticos.
MQL5 — Event Handlers: Estrutura de Execução
O MQL5 é orientado a eventos. Em vez de um loop infinito, cada programa reage a eventos gerados pelo terminal. Os event handlers são as funções que você implementa para processar esses eventos.
Fundamentos da linguagem: MQL5 — Fundamentos | Indicadores técnicos: Indicadores Técnicos
Visão Geral dos 14 Handlers
| Handler | Tipo de programa | Quando é chamado |
|---|---|---|
OnStart() | Scripts, Serviços | Uma vez ao iniciar |
OnInit() | EA, Indicador | Uma vez ao carregar |
OnDeinit() | EA, Indicador | Uma vez ao remover |
OnTick() | EA | A cada novo tick |
OnCalculate() | Indicador | A cada novo tick / nova barra |
OnTimer() | EA, Indicador | A cada N segundos (EventSetTimer) |
OnTrade() | EA | Ao mudar estado de ordens/posições |
OnTradeTransaction() | EA | Para cada transação de trading |
OnBookEvent() | EA | Mudança no Book (DOM) |
OnChartEvent() | EA, Indicador | Click, teclado, objeto gráfico |
OnTester() | EA | Ao finalizar um pass no Tester |
OnTesterInit() | EA | Início do processo de otimização |
OnTesterDeinit() | EA | Fim do processo de otimização |
OnTesterPass() | EA | Fim de cada pass na otimização |
OnStart — Scripts e Serviços
int OnStart(void)Função principal de scripts e serviços. Executa uma vez e depois encerra (scripts) ou em loop (serviços).
// Script: executa uma ação e encerra
void OnStart()
{
// Fechar todas as posições abertas
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
trade.PositionClose(ticket);
}
Print("Todas as posições fechadas.");
}// Serviço: loop contínuo
void OnStart()
{
while(!IsStopped())
{
// Verificar condições e agir
Sleep(1000); // esperar 1 segundo
}
}OnInit — Inicialização
int OnInit(void)Executado uma vez ao carregar o EA ou indicador no gráfico. Use para:
- Criar handles de indicadores com
iMA(),iRSI(), etc. - Validar parâmetros de entrada
- Inicializar variáveis e objetos
Códigos de retorno
| Constante | Valor | Descrição |
|---|---|---|
INIT_SUCCEEDED | 0 | Inicialização bem-sucedida |
INIT_FAILED | 1 | Falha — programa é removido |
INIT_PARAMETERS_INCORRECT | -1 | Parâmetros inválidos |
INIT_AGENT_NOT_SUITABLE | -2 | Agente incompatível (otimização) |
input int FastPeriod = 10;
input int SlowPeriod = 20;
int handleFast, handleSlow;
int OnInit()
{
// Validar parâmetros
if(FastPeriod >= SlowPeriod)
{
Print("Erro: FastPeriod deve ser menor que SlowPeriod");
return(INIT_PARAMETERS_INCORRECT);
}
// Criar handles de indicadores
handleFast = iMA(_Symbol, PERIOD_CURRENT, FastPeriod, 0, MODE_EMA, PRICE_CLOSE);
handleSlow = iMA(_Symbol, PERIOD_CURRENT, SlowPeriod, 0, MODE_EMA, PRICE_CLOSE);
if(handleFast == INVALID_HANDLE || handleSlow == INVALID_HANDLE)
{
Print("Erro ao criar handles de indicadores: ", GetLastError());
return(INIT_FAILED);
}
// Configurar timer (opcional)
EventSetTimer(60); // dispara OnTimer a cada 60s
return(INIT_SUCCEEDED);
}OnDeinit — Limpeza
void OnDeinit(const int reason)Executado ao remover o programa. Libere recursos criados em OnInit().
Códigos de razão (reason)
| Constante | Valor | Descrição |
|---|---|---|
REASON_PROGRAM | 0 | Encerrado pelo próprio programa |
REASON_REMOVE | 1 | Removido do gráfico manualmente |
REASON_RECOMPILE | 2 | Recompilado no MetaEditor |
REASON_CHARTCHANGE | 3 | Símbolo ou timeframe mudou |
REASON_CHARTCLOSE | 4 | Gráfico foi fechado |
REASON_PARAMETERS | 5 | Parâmetros de input foram alterados |
REASON_ACCOUNT | 6 | Conta alterada |
REASON_TEMPLATE | 7 | Template aplicado |
REASON_INITFAILED | 8 | OnInit() retornou erro |
REASON_CLOSE | 9 | Terminal sendo fechado |
void OnDeinit(const int reason)
{
// Liberar handles de indicadores
IndicatorRelease(handleFast);
IndicatorRelease(handleSlow);
// Cancelar timer
EventKillTimer();
// Remover objetos gráficos criados
ObjectsDeleteAll(0, "EA_");
// Log da razão
Print("OnDeinit: razão = ", reason);
}OnTick — Lógica Principal do EA
void OnTick(void)Chamado a cada tick (atualização de preço). É onde fica a lógica central do Expert Advisor.
Não disponível em indicadores — use
OnCalculate().
#include <Trade/Trade.mqh>
CTrade trade;
void OnTick()
{
// 1. Verificar se há uma nova barra (evitar execução redundante)
static datetime lastBar = 0;
datetime currentBar = iTime(_Symbol, PERIOD_CURRENT, 0);
if(currentBar == lastBar) return;
lastBar = currentBar;
// 2. Ler valores dos indicadores
double fast[], slow[];
ArraySetAsSeries(fast, true);
ArraySetAsSeries(slow, true);
if(CopyBuffer(handleFast, 0, 0, 3, fast) < 3) return;
if(CopyBuffer(handleSlow, 0, 0, 3, slow) < 3) return;
// 3. Detectar cruzamento
bool crossUp = (fast[1] > slow[1]) && (fast[2] <= slow[2]);
bool crossDown = (fast[1] < slow[1]) && (fast[2] >= slow[2]);
// 4. Executar
if(crossUp && PositionsTotal() == 0) trade.Buy(0.1);
if(crossDown && PositionsTotal() == 0) trade.Sell(0.1);
}Padrão: executar apenas na abertura de nova barra
bool IsNewBar()
{
static datetime prevTime = 0;
datetime curTime = iTime(_Symbol, PERIOD_CURRENT, 0);
if(curTime != prevTime)
{
prevTime = curTime;
return true;
}
return false;
}
void OnTick()
{
if(!IsNewBar()) return;
// lógica aqui...
}OnCalculate — Lógica Principal do Indicador
Dois overloads disponíveis:
Overload simples (uma série de preço)
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])Usado quando o indicador é aplicado sobre outro indicador ou série de preço.
Overload completo (OHLCV)
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])Lógica de prev_calculated
prev_calculated= número de barras já calculadas na chamada anterior- Permite calcular apenas as barras novas, sem recalcular o histórico inteiro
double Buffer[];
int OnInit()
{
SetIndexBuffer(0, Buffer, INDICATOR_DATA);
return(INIT_SUCCEEDED);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
// Calcular apenas barras novas (eficiência)
int start = (prev_calculated == 0) ? 1 : prev_calculated;
for(int i = start; i < rates_total; i++)
{
Buffer[i] = (high[i] + low[i] + close[i]) / 3.0; // Typical Price
}
return(rates_total); // retorna o total calculado
}OnTimer — Eventos Periódicos
void OnTimer(void)Disparado a cada N segundos após EventSetTimer(N) em OnInit().
int OnInit()
{
EventSetTimer(3600); // a cada 1 hora
return(INIT_SUCCEEDED);
}
void OnTimer()
{
// Enviar relatório, verificar notícias, atualizar parâmetros...
string msg = StringFormat("Posições abertas: %d | P&L: %.2f",
PositionsTotal(),
AccountInfoDouble(ACCOUNT_PROFIT));
Print(msg);
}
void OnDeinit(const int reason)
{
EventKillTimer();
}OnTrade — Mudança de Estado de Trading
void OnTrade(void)Chamado quando o estado de ordens ou posições muda (abertura, fechamento, modificação). Não inclui detalhes da transação — use OnTradeTransaction() para isso.
void OnTrade()
{
// Verificar se posição foi fechada
if(PositionsTotal() == 0)
{
Print("Todas as posições foram fechadas.");
// Reset de variáveis, log, etc.
}
}OnTradeTransaction — Detalhes de Cada Transação
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)Chamado para cada transação processada — mais granular que OnTrade().
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
// Filtrar apenas transações de deal executado
if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
{
if(trans.deal_type == DEAL_TYPE_BUY)
Print("Compra executada: ", trans.volume, " @ ", trans.price);
else if(trans.deal_type == DEAL_TYPE_SELL)
Print("Venda executada: ", trans.volume, " @ ", trans.price);
}
}Tipos de transação relevantes
| Constante | Descrição |
|---|---|
TRADE_TRANSACTION_ORDER_ADD | Nova ordem adicionada |
TRADE_TRANSACTION_ORDER_UPDATE | Ordem modificada |
TRADE_TRANSACTION_ORDER_DELETE | Ordem removida (executada/cancelada) |
TRADE_TRANSACTION_DEAL_ADD | Novo deal executado |
TRADE_TRANSACTION_POSITION | Posição atualizada |
TRADE_TRANSACTION_HISTORY_ADD | Deal adicionado ao histórico |
OnChartEvent — Interação com o Gráfico
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)Processa eventos de interface: mouse, teclado, objetos gráficos.
id | Evento | lparam | dparam | sparam |
|---|---|---|---|---|
CHARTEVENT_CLICK | Click no gráfico | x (pixels) | y (pixels) | — |
CHARTEVENT_KEYDOWN | Tecla pressionada | código da tecla | — | — |
CHARTEVENT_OBJECT_CLICK | Click em objeto | x | y | nome do objeto |
CHARTEVENT_OBJECT_DRAG | Objeto arrastado | — | — | nome do objeto |
CHARTEVENT_CUSTOM | Evento customizado (0..65535) | — | — | — |
CHARTEVENT_MOUSE_MOVE | Mouse movido | x | y | flags |
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id == CHARTEVENT_KEYDOWN)
{
if(lparam == 66) // tecla 'B'
{
trade.Buy(0.1);
Print("Compra manual via teclado");
}
if(lparam == 83) // tecla 'S'
{
trade.Sell(0.1);
Print("Venda manual via teclado");
}
}
if(id == CHARTEVENT_OBJECT_DRAG && sparam == "StopLine")
{
// Atualizar stop loss ao arrastar linha
double newStop = ObjectGetDouble(0, "StopLine", OBJPROP_PRICE);
Print("Novo Stop Loss: ", newStop);
}
}OnTester, OnTesterInit, OnTesterDeinit, OnTesterPass
Handlers usados para personalizar o processo de otimização no Strategy Tester.
// Retorna a métrica customizada para o otimizador
double OnTester()
{
double profit = TesterStatistics(STAT_PROFIT);
double drawdown = TesterStatistics(STAT_EQUITY_DD_RELATIVE);
double trades = TesterStatistics(STAT_TRADES);
if(trades < 50 || drawdown > 20) return 0; // penalizar
return profit / MathMax(drawdown, 0.01); // maximizar ratio
}
// Chamado antes do início da otimização (no agente coordenador)
void OnTesterInit()
{
Print("Iniciando otimização...");
}
// Chamado ao final da otimização completa
void OnTesterDeinit()
{
Print("Otimização concluída.");
}
// Chamado após cada pass individual ser concluído
void OnTesterPass()
{
// Coletar resultados de cada pass para análise customizada
}Estatísticas disponíveis em TesterStatistics()
| Constante | Descrição |
|---|---|
STAT_PROFIT | Lucro líquido |
STAT_TRADES | Total de trades |
STAT_PROFIT_FACTOR | Profit Factor |
STAT_EXPECTED_PAYOFF | Payoff esperado |
STAT_EQUITY_DD | Drawdown absoluto |
STAT_EQUITY_DD_RELATIVE | Drawdown relativo (%) |
STAT_SHARPE_RATIO | Sharpe Ratio |
STAT_RECOVERY_FACTOR | Recovery Factor |
OnBookEvent — Profundidade de Mercado (DOM)
void OnBookEvent(const string &symbol)Chamado quando o book de ofertas muda. Requer MarketBookAdd(symbol) em OnInit().
int OnInit()
{
MarketBookAdd(_Symbol);
return(INIT_SUCCEEDED);
}
void OnBookEvent(const string &symbol)
{
if(symbol != _Symbol) return;
MqlBookInfo book[];
MarketBookGet(_Symbol, book);
// book[0] = melhor oferta de venda (ask)
// Analisar pressão compradora vs vendedora
int bids = 0, asks = 0;
for(int i = 0; i < ArraySize(book); i++)
{
if(book[i].type == BOOK_TYPE_BUY) bids++;
if(book[i].type == BOOK_TYPE_SELL) asks++;
}
Print("Bids: ", bids, " | Asks: ", asks);
}
void OnDeinit(const int reason)
{
MarketBookRelease(_Symbol);
}Ordem de Chamada dos Handlers
Ao carregar o EA/indicador:
OnInit()
↓ (se INIT_SUCCEEDED)
OnTick() / OnCalculate() ← loop principal
OnTimer() ← em paralelo (se EventSetTimer ativo)
OnTrade() ← ao mudar posições
OnTradeTransaction() ← para cada transação
OnChartEvent() ← interação do usuário
↓ (ao remover)
OnDeinit(reason)Referências
- MQL5 — Fundamentos
- MQL5 — Indicadores Técnicos
- MQL5 — Indicadores Customizados
- MQL5 — Ordens Avançadas
Referências externas
- MQL5 Reference — Event Handling Functions (MetaQuotes)
- MQL5 Reference — OnInit (MetaQuotes)
- MQL5 Reference — OnTick (MetaQuotes)
- MQL5 Reference — OnCalculate (MetaQuotes)
- MQL5 Reference — OnTradeTransaction (MetaQuotes)
- MQL5 Reference — OnChartEvent (MetaQuotes)
- MQL5 Reference — OnTester (MetaQuotes)
MQL5 — Fundamentos da Linguagem
Tipos de dados, OOP, structs, arrays, strings e padrões fundamentais de programação em MQL5 para criar EAs e indicadores robustos.
MQL5 — Indicadores Técnicos
Referência dos 38 indicadores técnicos nativos do MQL5: iMA, iRSI, iMACD, iBands, iATR, iADX, iStochastic, iSAR, iCCI, iIchimoku e outros — com assinaturas, parâmetros e exemplos de uso com CopyBuffer.