MQL5 — Indicadores Customizados
Como criar indicadores personalizados em MQL5: SetIndexBuffer, estilos de plotagem (DRAW_LINE, DRAW_HISTOGRAM, DRAW_ARROW, DRAW_FILLING, DRAW_CANDLES), buffers, propriedades e exemplos completos.
MQL5 — Indicadores Customizados
Os indicadores customizados em MQL5 analisam preços e exibem informações visuais no gráfico — linhas, histogramas, setas, velas e outros estilos. Eles não executam ordens, mas são usados por Expert Advisors via iCustom() e CopyBuffer().
Event handlers: MQL5 — Event Handlers | Indicadores prontos: Indicadores Técnicos
Estrutura Básica de um Indicador
// 1. Propriedades do indicador
#property indicator_chart_window // ou indicator_separate_window
#property indicator_buffers 1 // número total de buffers
#property indicator_plots 1 // número de séries plotadas
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_width1 2
// 2. Buffer global
double LineBuffer[];
// 3. OnInit: vincular buffers
int OnInit()
{
SetIndexBuffer(0, LineBuffer, INDICATOR_DATA);
PlotIndexSetString(0, PLOT_LABEL, "Meu Indicador");
IndicatorSetString(INDICATOR_SHORTNAME, "MeuInd");
return(INIT_SUCCEEDED);
}
// 4. OnCalculate: preencher buffers
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[])
{
int start = (prev_calculated == 0) ? 1 : prev_calculated;
for(int i = start; i < rates_total; i++)
LineBuffer[i] = (high[i] + low[i]) / 2.0;
return(rates_total);
}Propriedades do Indicador (#property)
Posicionamento
| Propriedade | Descrição |
|---|---|
indicator_chart_window | Plota na janela principal do gráfico |
indicator_separate_window | Plota em janela separada (sub-janela) |
indicator_minimum / indicator_maximum | Escala mínima/máxima da sub-janela |
Configuração de buffers e plots
| Propriedade | Descrição |
|---|---|
indicator_buffers N | Total de buffers alocados (máximo: 512) |
indicator_plots N | Total de séries visíveis no gráfico |
indicator_typeN DRAW_* | Estilo de plotagem da série N |
indicator_colorN clrXxx | Cor da série N |
indicator_widthN N | Espessura da linha N (pixels) |
indicator_styleN STYLE_* | Estilo de linha (SOLID, DASH, DOT, DASHDOT) |
indicator_labelN "nome" | Rótulo exibido no tooltip da série N |
// Exemplo: duas linhas + histograma
#property indicator_separate_window
#property indicator_minimum -100
#property indicator_maximum 100
#property indicator_buffers 3
#property indicator_plots 3
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_width1 2
#property indicator_label1 "Linha Rápida"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_width2 1
#property indicator_label2 "Linha Lenta"
#property indicator_type3 DRAW_HISTOGRAM
#property indicator_color3 clrGray
#property indicator_label3 "Diferença"SetIndexBuffer — Vincular Buffers
bool SetIndexBuffer(int index,
double &buffer[],
ENUM_INDEXBUFFER_TYPE usage)usage | Descrição |
|---|---|
INDICATOR_DATA | Dados visíveis no gráfico (plotados) |
INDICATOR_CALCULATIONS | Buffer interno (não plotado) — para cálculos intermediários |
INDICATOR_COLOR_INDEX | Buffer de índice de cor (para estilos COLOR) |
double FastLine[], SlowLine[], DiffHist[], CalcBuffer[];
int OnInit()
{
// Buffers visíveis
SetIndexBuffer(0, FastLine, INDICATOR_DATA);
SetIndexBuffer(1, SlowLine, INDICATOR_DATA);
SetIndexBuffer(2, DiffHist, INDICATOR_DATA);
// Buffer de cálculo interno (não aparece no gráfico)
SetIndexBuffer(3, CalcBuffer, INDICATOR_CALCULATIONS);
return(INIT_SUCCEEDED);
}Estilos de Plotagem (DRAW_*)
DRAW_LINE — Linha contínua
#property indicator_type1 DRAW_LINE
// Buffers necessários: 1 (valores)DRAW_SECTION — Linha com segmentos (com gaps quando EMPTY_VALUE)
#property indicator_type1 DRAW_SECTION
// Buffers necessários: 1
// Define EMPTY_VALUE onde não deve plotar
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);DRAW_HISTOGRAM — Histograma a partir do zero
#property indicator_type1 DRAW_HISTOGRAM
// Buffers necessários: 1 (altura da barra)
// Útil para OBV, volume, MACD histogramDRAW_HISTOGRAM2 — Histograma entre dois valores
#property indicator_type1 DRAW_HISTOGRAM2
// Buffers necessários: 2 (valor superior, valor inferior)
// Útil para plotar faixasDRAW_ARROW — Setas/símbolos nos pontos
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrGold
// Buffers necessários: 1 (posição vertical da seta)
// Código Wingdings da seta:
PlotIndexSetInteger(0, PLOT_ARROW, 233); // símbolo de seta para cimaCódigos comuns de setas (Wingdings):
| Código | Símbolo |
|---|---|
| 233 | ▲ seta para cima |
| 234 | ▼ seta para baixo |
| 159 | ● círculo |
| 108 | ◆ diamante |
DRAW_ZIGZAG — Linha zigzag entre pares de pontos
#property indicator_type1 DRAW_ZIGZAG
// Buffers necessários: 2 (pontos altos, pontos baixos)
// Buffer 1: valores de máximas (ou EMPTY_VALUE)
// Buffer 2: valores de mínimas (ou EMPTY_VALUE)DRAW_FILLING — Preenchimento entre duas linhas
#property indicator_type1 DRAW_FILLING
#property indicator_color1 clrLightBlue // cor quando linha1 > linha2
#property indicator_color2 clrLightPink // cor quando linha1 < linha2
// Buffers necessários: 2 (linha superior, linha inferior)
// Usado em Bollinger Bands, Ichimoku Cloud, EnvelopesDRAW_BARS — Barras OHLC
#property indicator_type1 DRAW_BARS
// Buffers necessários: 4 (open[], high[], low[], close[])DRAW_CANDLES — Velas japonesas
#property indicator_type1 DRAW_CANDLES
#property indicator_color1 clrWhite // corpo de alta
#property indicator_color2 clrRed // corpo de baixa
// Buffers necessários: 4 (open[], high[], low[], close[])Estilos com cor dinâmica (DRAW_COLOR_*)
Versões com buffer de índice de cor — permite cores diferentes por barra:
| Estilo | Buffers | Uso |
|---|---|---|
DRAW_COLOR_LINE | 2 (valor + índice cor) | Linha com cor variável |
DRAW_COLOR_SECTION | 2 | Segmentos coloridos |
DRAW_COLOR_HISTOGRAM | 2 | Histograma colorido |
DRAW_COLOR_HISTOGRAM2 | 3 | Histograma 2 colorido |
DRAW_COLOR_ARROW | 2 | Setas coloridas |
DRAW_COLOR_ZIGZAG | 3 | Zigzag colorido |
DRAW_COLOR_BARS | 5 | Barras coloridas |
DRAW_COLOR_CANDLES | 5 | Velas coloridas |
// Exemplo: histograma com cor dinâmica (verde se positivo, vermelho se negativo)
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrGreen, clrRed // índice 0=verde, 1=vermelho
double HistBuffer[], ColorBuffer[];
int OnInit()
{
SetIndexBuffer(0, HistBuffer, INDICATOR_DATA);
SetIndexBuffer(1, ColorBuffer, INDICATOR_COLOR_INDEX);
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[])
{
for(int i = MathMax(prev_calculated, 1); i < rates_total; i++)
{
HistBuffer[i] = close[i] - close[i-1]; // variação
ColorBuffer[i] = (HistBuffer[i] >= 0) ? 0 : 1; // 0=verde, 1=vermelho
}
return(rates_total);
}PlotIndexSetInteger/Double/String — Configurar Plots
// Configurar após SetIndexBuffer
PlotIndexSetInteger(int plot_index, ENUM_PLOT_PROPERTY_INTEGER prop_id, int value);
PlotIndexSetDouble (int plot_index, ENUM_PLOT_PROPERTY_DOUBLE prop_id, double value);
PlotIndexSetString (int plot_index, ENUM_PLOT_PROPERTY_STRING prop_id, string value);| Propriedade | Tipo | Descrição |
|---|---|---|
PLOT_DRAW_TYPE | Integer | Estilo (DRAW_LINE, etc.) |
PLOT_COLOR_INDEXES | Integer | Número de cores para estilos COLOR |
PLOT_LINE_COLOR | Integer | Cor da linha (índice de cor) |
PLOT_LINE_WIDTH | Integer | Espessura |
PLOT_LINE_STYLE | Integer | STYLE_SOLID, STYLE_DASH, etc. |
PLOT_ARROW | Integer | Código Wingdings da seta |
PLOT_EMPTY_VALUE | Double | Valor a ignorar na plotagem |
PLOT_LABEL | String | Nome no tooltip |
PLOT_DRAW_BEGIN | Integer | Índice a partir do qual plotar |
// Exemplo de configuração via código (alternativa ao #property)
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrDodgerBlue);
PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 2);
PlotIndexSetDouble (0, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetString (0, PLOT_LABEL, "Minha Linha");
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 20); // começar após 20 barrasIndicatorSetInteger/Double/String — Configurar o Indicador
IndicatorSetString(INDICATOR_SHORTNAME, "Nome no gráfico");
IndicatorSetInteger(INDICATOR_DIGITS, 4); // casas decimais no tooltip
IndicatorSetDouble(INDICATOR_MINIMUM, -100.0); // escala da sub-janela
IndicatorSetDouble(INDICATOR_MAXIMUM, 100.0);Exemplo Completo: Bollinger Bands com Filling
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrSilver
#property indicator_width1 1
#property indicator_label1 "BB Superior"
#property indicator_type2 DRAW_FILLING
#property indicator_color2 clrLightBlue, clrLightBlue
#property indicator_label2 "BB Filling"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrSilver
#property indicator_width3 1
#property indicator_label3 "BB Inferior"
input int BBPeriod = 20;
input double BBDev = 2.0;
double UpperBand[], FillUpper[], LowerBand[];
int OnInit()
{
SetIndexBuffer(0, UpperBand, INDICATOR_DATA);
SetIndexBuffer(1, FillUpper, INDICATOR_DATA); // topo do filling
SetIndexBuffer(2, LowerBand, INDICATOR_DATA); // fundo do filling (plot 2)
// plot 1 (índice 1) é o DRAW_FILLING entre buffer 1 e buffer 2
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, BBPeriod);
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, BBPeriod);
PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, BBPeriod);
IndicatorSetString(INDICATOR_SHORTNAME,
StringFormat("BB(%d, %.1f)", BBPeriod, BBDev));
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[])
{
int start = MathMax(prev_calculated, BBPeriod);
for(int i = start; i < rates_total; i++)
{
// Calcular média
double sum = 0;
for(int j = 0; j < BBPeriod; j++) sum += close[i - j];
double ma = sum / BBPeriod;
// Calcular desvio padrão
double variance = 0;
for(int j = 0; j < BBPeriod; j++)
variance += MathPow(close[i - j] - ma, 2);
double stddev = MathSqrt(variance / BBPeriod);
UpperBand[i] = ma + BBDev * stddev;
FillUpper[i] = ma + BBDev * stddev; // mesmo que UpperBand
LowerBand[i] = ma - BBDev * stddev;
}
return(rates_total);
}Usando o Indicador Customizado em um EA
// Via iCustom()
int handle = iCustom(_Symbol, PERIOD_CURRENT, "MeuIndicador",
param1, param2, param3);
if(handle == INVALID_HANDLE)
{
Print("Erro ao criar handle: ", GetLastError());
return(INIT_FAILED);
}
// Ler valores do buffer 0 (3 últimos valores)
double buffer[];
ArraySetAsSeries(buffer, true);
if(CopyBuffer(handle, 0, 0, 3, buffer) < 3) return;
double valorAtual = buffer[0];
double valorAnterior = buffer[1];
// Liberar ao finalizar
IndicatorRelease(handle);Limitações e Boas Práticas
| Limite | Valor |
|---|---|
| Máximo de buffers por indicador | 512 |
| Máximo de plots visíveis | 64 |
| Extensão do arquivo compilado | .ex5 |
Boas práticas:
- Use
INDICATOR_CALCULATIONSpara buffers intermediários — reduz memória consumida - Defina
PLOT_DRAW_BEGINpara não plotar nas primeiras barras onde o cálculo é inválido - Defina
PLOT_EMPTY_VALUEpara omitir pontos específicos sem criar gaps visuais indesejados - Use
ArraySetAsSeries(buffer, false)para acessar buffers em ordem cronológica (índice 0 = mais antigo) dentro deOnCalculate
Referências
Referências externas
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.
MQL5 — Gestão de Risco em Código
Como implementar position sizing, risco por trade, stops baseados em ATR, drawdown máximo e proteção de capital em Expert Advisors MQL5.