Introdução ao MQL5 (Parte 12): Um Guia para Iniciantes sobre a Criação de Indicadores Personalizados
Introdução
Bem-vindo de volta à nossa série MQL5! Até agora, cobrimos bastante coisa, incluindo o uso de indicadores embutidos, a criação de Expert Advisors, a exploração de conceitos fundamentais do MQL5 e a aplicação do nosso conhecimento por meio de projetos práticos. É hora de avançar aprendendo como criar um indicador personalizado do zero. Obteremos uma compreensão mais aprofundada de como os indicadores operam internamente, permitindo-nos controle total sobre sua operação e design, em vez de depender de recursos embutidos. Você já se perguntou como a Média Móvel ou o MACD, dois dos indicadores embutidos do MQL5, são criados? Se não existissem funções como iRSI ou iMA, você ainda conseguiria criar indicadores?
Utilizando uma abordagem baseada em projetos, dividiremos o processo em duas partes principais. Primeiro, sem utilizar a função iMA, construiremos um indicador de Média Móvel inteiramente do zero. Em seguida, iremos um passo além e transformaremos a Média Móvel do formato tradicional de linha em um indicador no formato de candles. Além disso, esse método prático abrirá novos caminhos para o desenvolvimento de ferramentas de trading que sejam especificamente adequadas às suas necessidades.
Média Móvel no Formato de Linha

Média Móvel no Formato de Candle

Neste artigo, você aprenderá:
- Como criar indicadores personalizados do zero em MQL5.
- A diferença entre plotar indicadores no formato de linha e no formato de candle.
- O uso de buffers de indicadores para armazenar e exibir valores calculados.
- Como definir corretamente as propriedades do indicador.
- Criar um indicador personalizado de Média Móvel em MQL5.
- Mapear buffers de indicadores usando SetIndexBuffer().
- Processar dados de preço usando a função OnCalculate().
- Como determinar as cores dos candles com base no movimento do preço.
Mesmo que você seja novo no MQL5, é possível acompanhar sem se sentir sobrecarregado, pois este artigo foi pensado para iniciantes. Cada linha de código será explicada detalhadamente, dividindo ideias complexas em etapas gerenciáveis. Ao final deste tutorial, você deverá ter uma compreensão sólida de como os indicadores personalizados funcionam em MQL5, pois manterei tudo simples e prático.
1. Indicadores Personalizados
1.1. O que são Indicadores Personalizados?
Indicadores personalizados são aqueles que não estão disponíveis no MQL5 por padrão. Diferentemente dos indicadores embutidos que acompanham o MetaTrader 5, como Médias Móveis (MA), Índice de Força Relativa (RSI) ou MACD, os usuários podem criar seus próprios indicadores para realizar cálculos específicos, fornecer sinais ou apresentar dados de mercado da forma que desejarem.
É simples incorporar indicadores embutidos em estratégias de trading, pois eles podem ser acessados diretamente por meio de funções como iMA(), iRSI() e iMACD(). Mas, quando se trata de personalização, eles são limitados. Por outro lado, indicadores personalizados oferecem controle total sobre os cálculos, a lógica e a exibição no gráfico, permitindo criar ferramentas adaptadas às necessidades específicas de trading. Traders que desejam realizar análises de mercado de maneiras não suportadas por indicadores embutidos acharão esses indicadores especialmente úteis. Você pode projetar indicadores exclusivos que forneçam uma compreensão mais profunda do movimento de preços, tendências e possíveis oportunidades de trading utilizando a programação em MQL5.
Analogia
Considere organizar uma estante de livros na sua sala de estar. Indicadores embutidos são comparáveis a estantes pré-montadas compradas em lojas. Essas estantes têm tamanhos, formatos e recursos pré-determinados e estão disponíveis em designs padronizados. Para a maioria das pessoas, elas são fáceis de usar, convenientes e eficazes. No entanto, a estante pré-montada pode não se encaixar perfeitamente ou atender às suas necessidades se o seu espaço tiver um formato incomum ou se você precisar de prateleiras especiais para volumes raros.
Por outro lado, indicadores personalizados são como uma estante que você mesmo constrói. As medidas exatas, o número de prateleiras e os materiais podem ser escolhidos para criar uma estante que se encaixe no seu espaço e organize seus livros da maneira que você preferir. Da mesma forma, no trading, indicadores personalizados oferecem a precisão e a flexibilidade que os indicadores embutidos não conseguem fornecer, permitindo que você projete soluções que se adaptem à sua estratégia exclusiva.
1.2. Diferenças entre Expert Advisors e Indicadores
Embora indicadores e Expert Advisors analisem dados de mercado de maneiras um pouco semelhantes, suas funções são bastante distintas. Como os EAs são projetados para automatizar o trading, além de analisar o mercado, eles também executam operações de acordo com regras predefinidas. Eles são capazes de gerenciar risco, modificar stop-loss, determinar níveis de take-profit e abrir e fechar ordens. Toda vez que há uma nova atualização de preço, a função OnTick(), uma das mais importantes em um EA, é chamada. Com a ajuda dessa função, o EA pode monitorar os movimentos de preço em tempo real e verificar se os critérios de trading são atendidos antes de enviar uma ordem.
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // }
Em contraste, os indicadores não têm a capacidade de executar operações; em vez disso, concentram-se apenas na análise de mercado. Os indicadores utilizam o método OnCalculate(), que analisa dados históricos e atuais para produzir indicações de trading, em vez do OnTick(). O cálculo dos valores do indicador, a atualização dos elementos do gráfico e a apresentação de sinais visuais, como linhas de tendência ou candles coloridos, são todos tratados pelo OnCalculate().
Os indicadores apenas oferecem informações; a decisão final fica a cargo do trader, ao contrário dos EAs, que são feitos para agir. Embora ambos analisem dados de mercado, indicadores e EAs servem a propósitos diferentes. Enquanto os indicadores auxiliam os traders a interpretar manualmente o mercado e tomar decisões de trading bem fundamentadas, os EAs atuam diretamente sobre as oportunidades de trading.
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { // }
Analogia
Considere indicadores e Expert Advisors como duas ferramentas de trading distintas. Um EA analisa o mercado, toma decisões e executa operações de forma autônoma, assim como um carro autônomo. Sem intervenção humana, ele aplica estratégias de trading, monitora continuamente as flutuações do mercado e controla o risco.
Um indicador, por outro lado, funciona mais como um GPS, pois oferece orientação, mas não executa nenhuma ação. Ele analisa dados de mercado, identifica padrões e ajuda os traders a compreender as mudanças de preço. Uma média móvel, por exemplo, pode indicar se o mercado está em tendência de alta ou de baixa, mas não pode iniciar ou encerrar operações. Um indicador apenas fornece informações; a decisão final é sua, enquanto um EA opera por você.
2. Configuração do Projeto
Agora que sabemos o que são indicadores personalizados e como eles diferem dos Expert Advisors e dos indicadores embutidos, vamos ver como criar e modificar nossos indicadores em MQL5. Exploraremos o procedimento em detalhes nesta seção para garantir que você tenha uma boa compreensão de como criar um indicador desde o início. Sem utilizar rotinas de indicadores pré-existentes, como MA, construiremos dois indicadores exclusivos do zero neste tutorial.
2.1. MA em Linha
O primeiro indicador será um indicador simples de média móvel que calcula e exibe três médias móveis diferentes:
- Período 200 aplicado ao preço High.
- Período 100 aplicado ao preço Close.
- Período 50 aplicado ao preço Open.
Para construir um indicador personalizado, é essencial primeiro compreender a lógica por trás de sua funcionalidade. Antes de escrever qualquer código, devemos definir como o indicador irá processar os dados de mercado e exibir as informações relevantes. Essa etapa garante que nossa abordagem seja bem estruturada e fácil de implementar. Elaborar um pseudocódigo é um passo essencial além de compreender a lógica. Criar um pseudocódigo facilita a divisão da implementação em partes menores e mais gerenciáveis. Isso reduz a possibilidade de erros e aumenta a eficiência do processo de codificação ao delinear claramente o que deve ser feito.
A lógica necessária para calcular e exibir três médias móveis utilizando diferentes fontes de preço será examinada primeiro nesta seção. Antes de escrever o código real, elaboraremos um pseudocódigo para servir como guia para nossa implementação. Essa abordagem estruturada nos ajudará a construir um indicador personalizado bem definido, ao mesmo tempo em que reforça conceitos-chave de programação em MQL5.
Pseudocódigo:
// CONFIGURAR INDICADOR
1. Definir o indicador para ser exibido na janela do gráfico.
2. Definir 3 buffers para armazenar dados das médias móveis (MA200, MA100, MA50).
3. Definir 3 plots para exibir as médias móveis no gráfico.
// CONFIGURAR PROPRIEDADES DO PLOT
4. Para MA200:
- Rótulo: "MA 200"
- Tipo: Linha
- Estilo: Traço-Ponto-Ponto
- Largura: 1
- Cor: Azul
5. Para MA100:
- Rótulo: "MA 100"
- Tipo: Linha
- Estilo: Traço
- Largura: 1
- Cor: Marrom
6. Para MA50:
- Rótulo: "MA 50"
- Tipo: Linha
- Estilo: Ponto
- Largura: 1
- Cor: Roxo
// DEFINIR BUFFERS
7. Criar buffers para armazenar os valores calculados de:
- MA200
- MA100
- MA50
// DEFINIR PARÂMETROS DE ENTRADA
8. Permitir que o usuário defina o período para cada média móvel:
- MA200: Período padrão = 200
- MA100: Período padrão = 100
- MA50: Período padrão = 50
// FUNÇÃO DE INICIALIZAÇÃO
9. Quando o indicador for inicializado:
- Atribuir cada buffer ao seu plot correspondente.
- Definir o número de barras iniciais a serem ignoradas para cada média móvel:
- MA200: Ignorar as primeiras 200 barras
- MA100: Ignorar as primeiras 100 barras
- MA50: Ignorar as primeiras 50 barras
// FUNÇÃO DE CÁLCULO
10. Para cada novo candle ou quando o gráfico for atualizado:
Os preços High, Close e Open das 200, 100 e 50 barras anteriores serão somados para cada barra, divididos pelo período correspondente, e os resultados serão armazenados nos buffers apropriados para determinar a MA200, MA100 e MA50.
2.2. Candle MA
Em seguida, criaremos um indicador de média móvel diferente que representa as tendências de preço no formato de candles. Esse indicador utilizará uma média móvel com período de 5 e representará visualmente seus valores usando candles em vez de linhas. Ao exibir os dados da média móvel dessa forma, podemos destacar tendências de curto prazo e filtrar o ruído do mercado de maneira mais eficaz. Isso fornecerá uma perspectiva única sobre o movimento de preços, mantendo os princípios dos cálculos de média móvel.
Cada projeto será explicado de forma detalhada, garantindo que cada linha de código seja simples o suficiente para iniciantes compreenderem. Ao final desta parte, você terá experiência prática na construção e modificação de indicadores do zero, adquirindo habilidades úteis para projetos futuros.
Pseudocódigo:
// CONFIGURAR INDICADOR
1. Definir o indicador para ser exibido em uma janela separada.
2. Criar 5 arrays (buffers) para armazenar:
- Preços de abertura (OpenBuffer)
- Preços máximos (HighBuffer)
- Preços mínimos (LowBuffer)
- Preços de fechamento (CloseBuffer)
- Cores dos candles (ColorBuffer: 0 = verde, 1 = vermelho)
3. Definir 1 plot para exibir os candles.
// CONFIGURAR PROPRIEDADES DO PLOT
4. Para o plot:
- Rótulo: "Candles"
- Tipo: Candles Coloridos (DRAW_COLOR_CANDLES)
- Cores: Verde para candles de alta, Vermelho para candles de baixa
- Estilo: Sólido
- Largura: 1
// DEFINIR PARÂMETROS DE ENTRADA
5. Permitir que o usuário defina o período de suavização (padrão = 5).
// FUNÇÃO DE INICIALIZAÇÃO
6. Quando o indicador for inicializado:
- Atribuir cada buffer ao seu respectivo índice de dados ou de cor.
- Definir o número de barras iniciais a serem ignoradas (igual ao período de suavização).
// FUNÇÃO DE CÁLCULO
7. Para cada novo candle ou quando o gráfico for atualizado:
- Verificar se há barras suficientes para o cálculo (pelo menos "período" barras).
- Caso contrário, exibir uma mensagem de erro e interromper.
8. Para cada barra, da barra "período-1" até a barra mais recente:
Calcular os preços suavizados de abertura, máxima, mínima e fechamento:
- Somar os preços de abertura, máxima, mínima e fechamento das últimas "período" barras.
- Dividir cada soma por "período" para obter a média.
- Armazenar os resultados em OpenBuffer, HighBuffer, LowBuffer e CloseBuffer.
Definir a cor do candle:
- Se o preço de fechamento suavizado ≥ preço de abertura suavizado, definir a cor como verde (0).
- Caso contrário, definir a cor como vermelho (1).
3. Criação e Personalização de Indicadores Personalizados
Agora podemos criar e modificar nossos indicadores personalizados, já que escrevemos um pseudocódigo. Com uma estratégia bem definida, começaremos a colocar a lógica em prática gradualmente, garantindo que o indicador funcione conforme o esperado. Ao organizar corretamente nosso código, podemos visualizar de forma eficiente os movimentos do mercado e adaptar o indicador às nossas necessidades.
3.1. Construindo um Indicador de Média Móvel no Formato de Linha
O primeiro passo para criar um indicador é imaginar como você deseja que ele apareça e funcione. É fundamental fazer a si mesmo algumas perguntas importantes para ajudar a compreender o design e a implementação antes de escrever qualquer código:
- O indicador deve ser exibido na janela principal do gráfico ou em uma janela separada?
- Quantos buffers o indicador precisará para armazenar e exibir dados?
- Que tipo de plot deve ser usado — linha, histograma, candles ou outro?
- Quais cores devem ser atribuídas aos diferentes elementos para melhor visibilidade?
- O indicador utilizará múltiplas fontes de dados, como preços máximo, mínimo, abertura ou fechamento?
Ao responder a essas perguntas, você pode criar um plano claro para o seu indicador, tornando o processo de desenvolvimento mais fluido e estruturado.
Exemplo:
//INDICATOR IN CHART WINDOW #property indicator_chart_window //SET INDICATOR BUFFER TO STORE DATA #property indicator_buffers 3 //SET NUMBER FOR INDICATOR PLOTS #property indicator_plots 3
Explicação:
Indicador na Janela do Gráfico#property indicator_chart_window
Em vez de exibir o indicador personalizado em uma janela separada, essa diretiva instrui o MetaTrader 5 a exibi-lo diretamente no gráfico principal, onde a ação do preço é mostrada. Para plotar o indicador em uma janela diferente (como RSI ou MACD), utilizaríamos:
#propriedadeindicador_janela_separada
Essa diretiva garante que o indicador seja exibido em uma janela separada abaixo do gráfico principal, em vez de ser plotado diretamente sobre o gráfico de preços.
Configurando Buffers de Indicadores para Armazenar Dados
#propriedadeindicator_buffers3
Os valores calculados que serão plotados no gráfico são armazenados em arrays chamados buffers de indicadores. Cada buffer representa um elemento distinto do indicador. Neste caso, armazenaremos três conjuntos distintos de valores, pois estamos construindo três buffers de indicador. São necessários três buffers para manter os valores de cada média móvel de forma independente, já que estamos criando um indicador de média móvel com três períodos distintos (50, 100 e 200).
Definindo o Número de Plots do Indicador
#property indicator_plots 3
Isso especifica quantos plots o indicador irá exibir. Uma representação gráfica distinta no gráfico é chamada de plot. São necessários três plots, pois estamos desenhando três médias móveis: uma para cada média móvel de período 50, 100 e 200.
Cor, estilo e formato (como linha, histograma ou candles) podem ser personalizados para cada plot. Aqui, cada um dos três plots será exibido como uma linha que representa uma média móvel distinta.
Resumo
- O indicador será exibido no gráfico principal (#property indicator_chart_window).
- Ele armazenará três conjuntos de valores usando buffers de indicador (#property indicator_buffers 3).
- Ele irá plotar três médias móveis diferentes (#property indicator_plots 3).
Essa configuração garante que o indicador calcule e exiba corretamente as três médias móveis no gráfico de preços.

Definir as propriedades do plot vem em seguida após estabelecer as características fundamentais do nosso indicador. Para especificar como o indicador aparecerá no gráfico, é essencial fornecer atributos de plot ao construir um indicador personalizado em MQL5. O tipo de desenho, o estilo da linha, a espessura, a cor e os rótulos são todos determinados por esses parâmetros. Compreender esses parâmetros ajudará você a criar e modificar indicadores para diferentes casos de uso, já que este artigo se concentra em ensinar como projetar indicadores personalizados usando uma abordagem baseada em projetos.
Exemplos:
//INDICATOR IN CHART WINDOW #property indicator_chart_window //SET INDICATOR BUFFER TO STORE DATA #property indicator_buffers 3 //SET NUMBER FOR INDICATOR PLOTS #property indicator_plots 3 //SETTING PLOTS PROPERTIES //PROPERTIES OF THE FIRST MA (MA200) #property indicator_label1 "MA 200" //GIVE PLOT ONE A NAME #property indicator_type1 DRAW_LINE //TYPE OF PLOT THE FIRST MA #property indicator_style1 STYLE_DASHDOTDOT //STYLE OF SPOT THE FIRST MA #property indicator_width1 1 //LINE THICKNESS THE FIRST MA #property indicator_color1 clrBlue //LINE COLOR THE FIRST MA //PROPERTIES OF THE SECOND MA (MA100) #property indicator_label2 "MA 100" //GIVE PLOT TWO A NAME #property indicator_type2 DRAW_LINE //TYPE OF PLOT THE SECOND MA #property indicator_style2 STYLE_DASH //STYLE OF SPOT THE SECOND MA #property indicator_width2 1 //LINE THICKNESS THE SECOND MA #property indicator_color2 clrBrown //LINE COLOR THE SECOND MA //PROPERTIES OF THE THIRD MA (MA50) #property indicator_label3 "MA 50" //GIVE PLOT TWO A NAME #property indicator_type3 DRAW_LINE //TYPE OF PLOT THE THIRD MA #property indicator_style3 STYLE_DOT //STYLE OF SPOT THE THIRD MA #property indicator_width3 1 //LINE THICKNESS THE THIRD MA #property indicator_color3 clrPurple //LINE COLOR THE THIRD MA
Explicação:
Primeira Média Móvel (MA 200)
#property indicator_label1 "MA 200" //GIVE PLOT ONE A NAME #property indicator_type1 DRAW_LINE //TYPE OF PLOT THE FIRST MA #property indicator_style1 STYLE_DASHDOTDOT //STYLE OF SPOT THE FIRST MA #property indicator_width1 1 //LINE THICKNESS THE FIRST MA #property indicator_color1 clrBlue //LINE COLOR THE FIRST MA
A primeira Média Móvel (MA200) aparecerá como uma linha azul tracejada com pontos, com espessura de 1.
Segunda Média Móvel (MA 100)
#property indicator_label2 "MA 100" //GIVE PLOT TWO A NAME #property indicator_type2 DRAW_LINE //TYPE OF PLOT THE SECOND MA #property indicator_style2 STYLE_DASH //STYLE OF SPOT THE SECOND MA #property indicator_width2 1 //LINE THICKNESS THE SECOND MA #property indicator_color2 clrBrown //LINE COLOR THE SECOND MA
A segunda Média Móvel (MA100) será exibida como uma linha marrom tracejada, com espessura de 1.
Terceira Média Móvel (MA 50)
#property indicator_label3 "MA 50" //GIVE PLOT TWO A NAME #property indicator_type3 DRAW_LINE //TYPE OF PLOT THE THIRD MA #property indicator_style3 STYLE_DOT //STYLE OF SPOT THE THIRD MA #property indicator_width3 1 //LINE THICKNESS THE THIRD MA #property indicator_color3 clrPurple //LINE COLOR THE THIRD MA
A terceira Média Móvel (MA50) será exibida como uma linha roxa pontilhada, com espessura de 1.
Compreendendo a Relação entre as Propriedades de Plot no MQL5
Cada plot (linha, histograma, seta etc.) exige um conjunto de características para definir sua aparência quando um indicador é exibido em um gráfico. Sufixos numerados, como indicator_label1, indicator_type1, indicator_style1 etc., são usados no MQL5 para atribuir essas propriedades.
Essa numeração garante que todas as propriedades de um determinado plot pertençam ao mesmo conjunto. Vamos analisar:
- indicator_label1 atribui um nome ao primeiro plot, facilitando sua identificação.
- indicator_type1 especifica como esse primeiro plot será desenhado (por exemplo, como uma linha).
- indicator_style1 determina o estilo da linha para esse primeiro plot (sólido, tracejado, pontilhado etc.).
- indicator_width1 controla a espessura do primeiro plot.
- indicator_color1 define a cor desse primeiro plot.
Exemplo para Esclarecer a Relação
Pense nessas propriedades como um conjunto correspondente para cada média móvel:
| Propriedade | O que controla | Primeira MA (200) | Segunda MA (100) | Terceira MA (50) |
|---|---|---|---|---|
| indicator_labelX | Nome da MA | "MA 200" | "MA 100" | "MA 50" |
| indicator_typeX | Tipo de Plot | DRAW_LINE | DRAW_LINE | DRAW_LINE |
| indicator_styleX | Estilo da Linha | STYLE_DASHDOTDOT | STYLE_DASH | STYLE_DOT |
| indicator_widthX | Espessura | 1 | 1 | 1 |
| indicator_colorX | Cor | clrBlue | clrBrown | clrPurple |
Essa abordagem garante que cada propriedade corresponda à média móvel correta e nos permite especificar vários plots de forma organizada. Portanto, apenas a Segunda MA será afetada se indicator_style2 for alterado. Apenas a cor da Terceira MA será alterada se indicator_color3 for modificado. Podemos gerenciar a aparência de cada média móvel no gráfico sem criar confusão ao manter essas propriedades consistentes e organizadas.
Além dos diversos tipos de plot, estilos de linha e cores que utilizamos em nosso indicador de Média Móvel, o MQL5 oferece uma ampla gama de outras possibilidades de personalização para plots de indicadores. Os desenvolvedores podem criar diversos tipos de indicação usando esses parâmetros, desde linhas simples até visualizações mais complexas, como bandas, setas e histogramas. Estamos utilizando uma abordagem baseada em projetos, concentrando-nos em um único indicador enquanto apresentamos conceitos essenciais que podem ser aplicados a outros indicadores personalizados, pois há muitas variáveis para serem abordadas em um único artigo. Ainda assim, é útil saber que existem opções adicionais.
Em geral, diferentes estilos de plot podem ser analisados usando a mesma lógica aplicada neste artigo. Porém, isso nem sempre é válido para todos os tipos de plot. Por exemplo, enquanto DRAW_LINE requer apenas um buffer por plot, DRAW_CANDLES exige quatro buffers para plotar um único candle. Você pode consultar a documentação do MQL5 para uma descrição completa dos vários tipos de plot disponíveis, juntamente com seus requisitos específicos.
Declarar variáveis do tipo double para armazenar os buffers do indicador é o próximo passo após configurar os atributos do plot. Esses buffers são cruciais, pois armazenam os valores calculados que serão exibidos no gráfico. A função SetIndexBuffer() deve ser usada para vincular as variáveis aos buffers do indicador após elas serem declaradas. Essa etapa garante que os dados armazenados nesses buffers possam ser exibidos corretamente e estejam devidamente associados aos plots correspondentes.
Exemplo:
//INDICATOR IN CHART WINDOW #property indicator_chart_window //SET INDICATOR BUFFER TO STORE DATA #property indicator_buffers 3 //SET NUMBER FOR INDICATOR PLOTS #property indicator_plots 3 //SETTING PLOTS PROPERTIES //PROPERTIES OF THE FIRST MA (MA200) #property indicator_label1 "MA 200" //GIVE PLOT ONE A NAME #property indicator_type1 DRAW_LINE //TYPE OF PLOT THE FIRST MA #property indicator_style1 STYLE_DASHDOTDOT //STYLE OF SPOT THE FIRST MA #property indicator_width1 1 //LINE THICKNESS THE FIRST MA #property indicator_color1 clrBlue //LINE COLOR THE FIRST MA //PROPERTIES OF THE SECOND MA (MA100) #property indicator_label2 "MA 100" //GIVE PLOT TWO A NAME #property indicator_type2 DRAW_LINE //TYPE OF PLOT THE SECOND MA #property indicator_style2 STYLE_DASH //STYLE OF SPOT THE SECOND MA #property indicator_width2 1 //LINE THICKNESS THE SECOND MA #property indicator_color2 clrBrown //LINE COLOR THE SECOND MA //PROPERTIES OF THE THIRD MA (MA50) #property indicator_label3 "MA 50" //GIVE PLOT TWO A NAME #property indicator_type3 DRAW_LINE //TYPE OF PLOT THE THIRD MA #property indicator_style3 STYLE_DOT //STYLE OF SPOT THE THIRD MA #property indicator_width3 1 //LINE THICKNESS THE THIRD MA #property indicator_color3 clrPurple //LINE COLOR THE THIRD MA //SET MA BUFFER TO STORE DATA double buffer_mA200[]; //BUFFER FOR THE FIRST MA double buffer_mA100[]; //BUFFER FOR THE SECOND MA double buffer_mA50[]; //BUFFER FOR THE THIRD MA //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //SETTING BUFFER SetIndexBuffer(0, buffer_mA200, INDICATOR_DATA); //INDEX 0 FOR MA200 SetIndexBuffer(1, buffer_mA100, INDICATOR_DATA); //INDEX 1 FOR MA100 SetIndexBuffer(2, buffer_mA50, INDICATOR_DATA); //INDEX 1 FOR MA50 //--- return(INIT_SUCCEEDED); }
Explicação:
//SET MA BUFFER TO STORE DATA double buffer_mA200[]; //BUFFER FOR THE FIRST MA double buffer_mA100[]; //BUFFER FOR THE SECOND MA double buffer_mA50[]; //BUFFER FOR THE THIRD MA
Esses arrays (buffer_mA200, buffer_mA100, buffer_mA50) servem como armazenamento para os valores calculados de cada Média Móvel (MA).
Cada buffer corresponde a uma MA específica:
- buffer_mA200 → Armazena valores da MA 200
- buffer_mA100 → Armazena valores da MA 100
- buffer_mA50 → Armazena valores da MA 50
Quando o indicador é exibido, os valores armazenados nesses buffers serão plotados no gráfico. Para armazenar os valores calculados de um indicador em MQL5, os buffers de indicador são necessários. Sem buffers, seria impossível salvar e exibir os resultados.
//SETTING BUFFER SetIndexBuffer(0, buffer_mA200, INDICATOR_DATA); //INDEX 0 FOR MA200 SetIndexBuffer(1, buffer_mA100, INDICATOR_DATA); //INDEX 1 FOR MA100 SetIndexBuffer(2, buffer_mA50, INDICATOR_DATA); //INDEX 2 FOR MA50
SetIndexBuffer() é usado para vincular cada buffer ao sistema de plotagem do indicador.
Ele recebe três parâmetros:
- Índice do buffer → Determina a ordem em que os buffers são usados (começando em 0).
- A variável do buffer → O buffer que irá armazenar os valores para esse índice.
- Tipo de buffer → INDICATOR_DATA especifica que o buffer contém valores do indicador.
Detalhamento de cada linha:
- SetIndexBuffer(0, buffer_mA200, INDICATOR_DATA); → Atribui buffer_mA200 ao índice 0 (Primeira MA).
- SetIndexBuffer(1, buffer_mA100, INDICATOR_DATA); → Atribui buffer_mA100 ao índice 1 (Segunda MA).
- SetIndexBuffer(2, buffer_mA50, INDICATOR_DATA); → Atribui buffer_mA50 ao índice 2 (Terceira MA).
Isso garante que o sistema de indicadores do MQL5 reconheça e plote corretamente cada buffer. Sem essa etapa, o indicador não funcionaria corretamente.
Ter um entendimento sólido da matemática ou da lógica subjacente a um indicador é essencial para sua criação. Somente quando um indicador avalia corretamente as variações de preço com base em fundamentos matemáticos ou lógicos sólidos ele pode ser considerado útil. Antes de colocá-lo em prática no MQL5, é necessário compreender como o indicador funciona e quais entradas são necessárias para calculá-lo de forma eficiente.
Por exemplo, vamos considerar a Média Móvel:
Ao suavizar as oscilações de preço, a média móvel facilita a identificação de padrões de mercado sem ser influenciada por variações transitórias.
Para calcular uma Média Móvel, precisamos considerar:
Período
O número de candles históricos usados para calcular a média móvel depende do timeframe. Por exemplo, uma MA de período 200 calcula a média dos últimos 200 candles. Quanto menor o período, mais sensível a MA é aos movimentos recentes; já um período maior produz uma linha mais suave, que reage mais lentamente às mudanças de preço.
Tipo de Preço
A MA pode ser calculada utilizando diferentes tipos de preço, como:
- Preço de Fechamento → Usa o preço de fechamento de cada candle.
- Preço de Abertura → Usa o preço de abertura de cada candle.
- Preço Máximo → Usa o preço mais alto de cada candle.
- Preço Mínimo → Usa o preço mais baixo de cada candle.
Neste projeto, trabalharemos com três Médias Móveis diferentes:
- MA 200 (aplicada ao preço High)
- MA 100 (aplicada ao preço Close)
- MA 50 (aplicada ao preço Open)
Compreender esses conceitos fundamentais garante que possamos calcular e visualizar corretamente a Média Móvel sem depender de funções embutidas do MQL5, como iMA().
Exemplo:
//INDICATOR IN CHART WINDOW #property indicator_chart_window //SET INDICATOR BUFFER TO STORE DATA #property indicator_buffers 3 //SET NUMBER FOR INDICATOR PLOTS #property indicator_plots 3 //SETTING PLOTS PROPERTIES //PROPERTIES OF THE FIRST MA (MA200) #property indicator_label1 "MA 200" //GIVE PLOT ONE A NAME #property indicator_type1 DRAW_LINE //TYPE OF PLOT THE FIRST MA #property indicator_style1 STYLE_DASHDOTDOT //STYLE OF SPOT THE FIRST MA #property indicator_width1 1 //LINE THICKNESS THE FIRST MA #property indicator_color1 clrBlue //LINE COLOR THE FIRST MA //PROPERTIES OF THE SECOND MA (MA100) #property indicator_label2 "MA 100" //GIVE PLOT TWO A NAME #property indicator_type2 DRAW_LINE //TYPE OF PLOT THE SECOND MA #property indicator_style2 STYLE_DASH //STYLE OF SPOT THE SECOND MA #property indicator_width2 1 //LINE THICKNESS THE SECOND MA #property indicator_color2 clrBrown //LINE COLOR THE SECOND MA //PROPERTIES OF THE THIRD MA (MA50) #property indicator_label3 "MA 50" //GIVE PLOT TWO A NAME #property indicator_type3 DRAW_LINE //TYPE OF PLOT THE THIRD MA #property indicator_style3 STYLE_DOT //STYLE OF SPOT THE THIRD MA #property indicator_width3 1 //LINE THICKNESS THE THIRD MA #property indicator_color3 clrPurple //LINE COLOR THE THIRD MA //SET MA BUFFER TO STORE DATA double buffer_mA200[]; //BUFFER FOR THE FIRST MA double buffer_mA100[]; //BUFFER FOR THE SECOND MA double buffer_mA50[]; //BUFFER FOR THE THIRD MA //SET MA PERIOD input int period_ma200 = 200; //PERIOD FOR THE FIRST MA input int period_ma100 = 100; //PERIOD FOR THE SECOND MA input int period_ma50 = 50; //PERIOD FOR THE THIRD MA //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //SETTING BUFFER SetIndexBuffer(0, buffer_mA200, INDICATOR_DATA); //INDEX 0 FOR MA200 SetIndexBuffer(1, buffer_mA100, INDICATOR_DATA); //INDEX 1 FOR MA100 SetIndexBuffer(2, buffer_mA50, INDICATOR_DATA); //INDEX 1 FOR MA50 //SETTING BARS TO START PLOTTING PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period_ma200); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, period_ma100); PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, period_ma50); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { //CALCULATE THE MOVING AVERAGE FOR THE THE First MA (MA200) for(int i = period_ma200 - 1; i < rates_total; i++) { double sum = 0.0; for(int j = 0; j < period_ma200; j++) { sum += high[i - j]; } buffer_mA200[i] = sum / period_ma200; } //CALCULATE THE MOVING AVERAGE FOR THE THE SECOND MA (MA100) for(int i = period_ma100 - 1; i < rates_total; i++) { double sum = 0.0; for(int j = 0; j < period_ma100; j++) { sum += close[i - j]; } buffer_mA100[i] = sum / period_ma100; } //CALCULATE THE MOVING AVERAGE FOR THE THE THIRD MA (MA50) for(int i = period_ma50 - 1; i < rates_total; i++) { double sum = 0.0; for(int j = 0; j < period_ma50; j++) { sum += open[i - j]; } buffer_mA50[i] = sum / period_ma50; } //--- return value of prev_calculated for next call return(rates_total); }
Explicação:
//SET MA PERIOD input int period_ma200 = 200; //PERIOD FOR THE FIRST MA input int period_ma100 = 100; //PERIOD FOR THE SECOND MA input int period_ma50 = 50; //PERIOD FOR THE THIRD MA
- Essas variáveis de entrada definem o período de cada Média Móvel (MA).
- O período determina quantos candles passados a MA utilizará para seu cálculo.
- period_ma200 = 200 significa que a MA200 usará os últimos 200 candles para calcular o preço médio.
- period_ma100 = 100 significa que a MA100 usará os últimos 100 candles para calcular a média.
- period_ma50 = 50 significa que a MA50 usará os últimos 50 candles para calcular a média.
- Como essas são variáveis de entrada, os traders podem modificá-las nas configurações do indicador sem alterar o código.
//SETTING BARS TO START PLOTTING PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period_ma200); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, period_ma100); PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, period_ma50);
Por que isso é necessário?
- Como uma Média Móvel com período 200 precisa de 200 candles anteriores para calcular seu valor, ela não pode plotar nada antes dos primeiros 200 candles.
- PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period_ma200); informa ao MetaTrader para começar a desenhar a MA200 somente após 200 candles estarem disponíveis.
- PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, period_ma100); faz o mesmo para a MA100 (começa após 100 candles).
- PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, period_ma50); garante que a MA50 comece após 50 candles.

//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[])
A função central de todo indicador personalizado, OnCalculate(), é chamada automaticamente sempre que um novo tick é recebido ou quando os dados históricos são atualizados. Ela é crucial para os cálculos do indicador, pois processa os dados de preço e atualiza os buffers do indicador. Diferentemente do OnTick(), utilizado em Expert Advisors, o OnCalculate() foi projetado especificamente para indicadores e oferece acesso direto aos dados históricos de preço sem a necessidade de procedimentos adicionais como CopyOpen(), CopyClose() ou ArraySetAsSeries().
Diferença entre OnCalculate() e OnTick()| Recurso | OnCalculate() | OnTick() |
|---|---|---|
| Usado em | Indicadores | Expert Advisors |
| Chamado quando | Novo tick chega ou o gráfico é atualizado | Novo tick chega |
| Acesso aos dados de preço | Usa arrays embutidos (open[], close[], etc.) | Requer funções como CopyClose() para obter dados |
| Objetivo | Calcula e atualiza os valores do indicador | Executa lógica de trading, envia ordens |
| Parâmetro | Descrição |
|---|---|
| rates_total | O número total de candles (barras) disponíveis no gráfico. |
| prev_calculated | O número de barras calculadas anteriormente (ajuda a otimizar o desempenho). |
| time[] | O timestamp de cada candle (por exemplo, 2024.02.02 12:30). |
| open[] | O preço de abertura de cada candle. |
| high[] | O preço máximo de cada candle. |
| low[] | O preço mínimo de cada candle. |
| close[] | O preço de fechamento de cada candle. |
| tick_volume[] | O número de ticks (atualizações de preço) dentro de um candle. |
| volume[] | O volume total negociado dentro de um candle. |
| spread[] | O spread (diferença entre os preços bid e ask) de cada candle. |
// CALCULATE THE MOVING AVERAGE FOR THE FIRST MA (MA200) for(int i = period_ma200 - 1; i < rates_total; i++) { double sum = 0.0; for(int j = 0; j < period_ma200; j++) { sum += high[i - j]; // SUM OF HIGH PRICES OVER THE PERIOD } buffer_mA200[i] = sum / period_ma200; // CALCULATE THE AVERAGE }
Um loop for que percorre os dados de preço é usado para calcular a Média Móvel (MA) da primeira MA (MA200). Temos dados anteriores suficientes para calcular a média porque o loop começa em period_ma200 - 1. Ele continua até rates_total, que é a quantidade total de pontos de dados de preço disponíveis. Esse método evita erros que poderiam ocorrer ao tentar acessar pontos de dados inexistentes (como índices negativos). Cada barra do gráfico tem sua média móvel calculada de forma sistemática pelo loop, que então atualiza o buffer do indicador adequadamente.
Para armazenar a soma acumulada dos preços máximos ao longo do período definido (neste caso, 200), inicializamos uma variável sum dentro do loop. Um loop for aninhado percorre as últimas 200 barras, de 0 até period_ma200. Em cada iteração, Sum += high[i - j]; é utilizado para adicionar o preço máximo de uma barra específica à variável sum. Ao retroceder a partir do índice atual i, a fórmula i - j garante que estamos somando os preços máximos das últimas 200 barras. Esse procedimento soma de forma eficiente todos os preços máximos para o período especificado.
Depois de obter o total dos preços máximos ao longo dos 200 períodos, dividimos esse valor pelo tamanho do período para obter a média: buffer_mA200[i] = sum / period_ma200;Esse valor final representa a MA calculada para cada barra e é então armazenado no índice correspondente do buffer_mA200 Ao calcular a média dos últimos 200 preços máximos, a média móvel suaviza as oscilações de preço e permite que os traders identifiquem tendências de longo prazo. Embora as outras médias móveis utilizem diferentes tipos de preço (close e open) e períodos (100 e 50), o mesmo raciocínio se aplica a elas.

3.2. Construindo um Indicador de Média Móvel no Formato de Candle
Nesta seção, desenvolveremos um tipo diferente de indicador de média móvel que utiliza o formato de candle para mostrar os movimentos de preço. Esse indicador empregará uma média móvel de período cinco e usará candles, em vez de linhas, para exibir graficamente seus valores. Ao apresentar os dados da média móvel dessa maneira, conseguimos filtrar o ruído do mercado de forma mais eficaz e destacar tendências de curto prazo. Isso preserva os fundamentos dos cálculos de média móvel ao mesmo tempo em que oferece uma perspectiva distinta sobre o movimento de preços.
O preço de abertura, o preço de fechamento, o preço máximo e o preço mínimo são os quatro componentes essenciais de preço que formam um candle. Diferentemente do estilo de linha, que requer apenas um valor de preço por período (como close ou open), o formato de candle exige cálculos independentes de média móvel para esses quatro valores. Consequentemente, são necessários no mínimo quatro buffers para um único plot, um para cada um dos valores da média móvel que representam os preços de abertura, fechamento, máximo e mínimo. A estrutura desse indicador garante que os dados da média móvel sejam apresentados de forma semelhante aos padrões reais de candles, facilitando a análise de tendências de preço por meio de referências visuais familiares.
Exemplo:
#property indicator_separate_window #property indicator_buffers 5 #property indicator_plots 1 //---- plot ColorCandles #property indicator_label1 "Candles" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrGreen, clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- indicator buffers double OpenBuffer[]; double HighBuffer[]; double LowBuffer[]; double CloseBuffer[]; double ColorBuffer[]; int period = 5; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0, OpenBuffer, INDICATOR_DATA); SetIndexBuffer(1, HighBuffer, INDICATOR_DATA); SetIndexBuffer(2, LowBuffer, INDICATOR_DATA); SetIndexBuffer(3, CloseBuffer, INDICATOR_DATA); SetIndexBuffer(4, ColorBuffer, INDICATOR_COLOR_INDEX); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { if(rates_total < period) { Print("Error: Not enough bars to calculate."); return 0; } for(int i = period - 1; i < rates_total; i++) { if(i - period + 1 < 0) continue; double sumClose = 0.0; double sumOpen = 0.0; double sumHigh = 0.0; double sumLow = 0.0; for(int j = 0; j < period; j++) { int index = i - j; if(index < 0) continue; // Prevent out-of-bounds access sumClose += close[index]; sumOpen += open[index]; sumHigh += high[index]; sumLow += low[index]; } if(period > 0) { OpenBuffer[i] = sumOpen / period; HighBuffer[i] = sumHigh / period; LowBuffer[i] = sumLow / period; CloseBuffer[i] = sumClose / period; } else { Print("Error: Division by zero prevented."); return 0; } ColorBuffer[i] = (CloseBuffer[i] >= OpenBuffer[i]) ? 0 : 1; } return rates_total; }
Explicação:
#property indicator_separate_window #property indicator_buffers 5 #property indicator_plots 1 //---- plot ColorCandles #property indicator_label1 "Candles" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrGreen, clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- indicator buffers double OpenBuffer[]; double HighBuffer[]; double LowBuffer[]; double CloseBuffer[]; double ColorBuffer[]; int period = 5;
As propriedades e os buffers de um indicador personalizado que exibe uma média móvel no formato de candlestick são definidos por este código. Um candlestick normalmente requer quatro buffers: um para os componentes de preço Open, High, Low e Close. No entanto, como é necessário um buffer adicional (ColorBuffer) para identificar e armazenar a cor de cada candle, esse indicador precisa de cinco buffers.
Propriedades do Indicador
- #property indicator_separate_window garante que o indicador seja exibido em uma janela separada, em vez de ser plotado no gráfico principal.
- #property indicator_buffers 5 define o número de buffers utilizados. Embora um candle exija apenas quatro buffers (Open, High, Low e Close), um quinto buffer é necessário para atribuir uma cor a cada candle.
- #property indicator_plots 1 especifica que o indicador possui apenas um plot, que utilizará candles coloridos.
Configurações de Plot e Visualização
- indicator_label1 "Candles" define o nome do plot.
- indicator_type1 DRAW_COLOR_CANDLES define o tipo de plot como candlesticks coloridos. Diferentemente de DRAW_LINE, esse tipo requer valores de Open, High, Low e Close, além de um índice de cor.
- indicator_color1 clrGreen, clrRed atribui a cor verde para candles de alta e vermelha para candles de baixa.
- indicator_style1 STYLE_SOLID garante bordas sólidas nos candles.
- indicator_width1 1 define a espessura do contorno dos candles.
Por que Cinco Buffers em vez de Quatro?
Uma estrutura típica de candlestick requer quatro buffers:
- OpenBuffer[]: Armazena os preços de abertura da média móvel.
- HighBuffer[]: Armazena os preços máximos da média móvel.
- LowBuffer[]: Armazena os preços mínimos da média móvel.
- CloseBuffer[]: Armazena os preços de fechamento da média móvel.
No entanto, como o indicador utiliza candles coloridos, ele também precisa de um quinto buffer:
- ColorBuffer[]: Armazena o índice de cor (0 para verde, 1 para vermelho). Ao fornecer um buffer adicional, a média móvel é representada graficamente por candles de baixa (vermelhos) e de alta (verdes), facilitando a identificação de padrões de preço.
//--- indicator buffers mapping SetIndexBuffer(0, OpenBuffer, INDICATOR_DATA); SetIndexBuffer(1, HighBuffer, INDICATOR_DATA); SetIndexBuffer(2, LowBuffer, INDICATOR_DATA); SetIndexBuffer(3, CloseBuffer, INDICATOR_DATA); SetIndexBuffer(4, ColorBuffer, INDICATOR_COLOR_INDEX); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period);
Para salvar os valores calculados da média móvel no formato de candlestick, esta seção do código mapeia os buffers do indicador. Essa variante em candlestick da média móvel utiliza quatro buffers (OpenBuffer, HighBuffer, LowBuffer e CloseBuffer) para armazenar os equivalentes de média móvel dos preços de abertura, máxima, mínima e fechamento, em contraste com a versão convencional baseada em linhas, que necessita apenas de um buffer para armazenar os valores calculados para plotagem.
Um quinto buffer, chamado ColorBuffer, também é utilizado para identificar a cor de cada candle, diferenciando candles de baixa (vermelhos) e de alta (verdes). Para garantir que o indicador processe e exiba os dados corretamente, a função SetIndexBuffer() associa cada buffer a um índice de plot distinto. Para evitar gráficos incompletos ou enganosos, PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, period); garante que o indicador só comece a ser plotado após haver barras suficientes disponíveis.
if(rates_total < period) { Print("Error: Not enough bars to calculate."); return 0; } for(int i = period - 1; i < rates_total; i++) { if(i - period + 1 < 0) continue; double sumClose = 0.0; double sumOpen = 0.0; double sumHigh = 0.0; double sumLow = 0.0; for(int j = 0; j < period; j++) { int index = i - j; if(index < 0) continue; // Prevent out-of-bounds access sumClose += close[index]; sumOpen += open[index]; sumHigh += high[index]; sumLow += low[index]; } if(period > 0) { OpenBuffer[i] = sumOpen / period; HighBuffer[i] = sumHigh / period; LowBuffer[i] = sumLow / period; CloseBuffer[i] = sumClose / period; } else { Print("Error: Division by zero prevented."); return 0; } ColorBuffer[i] = (CloseBuffer[i] >= OpenBuffer[i]) ? 0 : 1; } return rates_total;
Este trecho de código começa verificando se há barras de preço suficientes para que o cálculo prossiga. A condição if (rates_total < period) garante que existam dados históricos suficientes (ou “barras”) para calcular a média móvel com base no período definido pelo usuário. Caso não haja barras suficientes, a função retorna 0 e exibe uma mensagem de erro. Essa etapa é essencial, pois um cálculo significativo de média móvel não pode ser realizado sem dados suficientes, e tentar fazê-lo pode resultar em estatísticas imprecisas ou enganosas.
Após verificar que há barras suficientes, o loop for percorre os dados de preço, começando no índice period - 1 e indo até rates_total. Cada barra é processada pelo loop, que inicia no ponto designado e segue adiante. Nesse loop, a variável i representa o índice da barra atual. Utilizando as informações de preço das barras do período anterior, esse loop calcula a média móvel para cada barra. O loop garante que o cálculo só comece quando o número necessário de barras estiver disponível ao continuar para a próxima iteração caso o índice i - period + 1 seja menor que 0.
Quatro variáveis são inicializadas com 0.0 dentro do loop: sumClose, sumOpen, sumHigh e sumLow. Essas variáveis armazenarão as somas acumuladas dos respectivos dados de preço para o período especificado. As informações de preço de cada barra dentro do período são coletadas por meio de um segundo loop for, que percorre de 0 até period - 1. Ao subtrair j do índice atual i, o loop interno recupera cada uma das barras anteriores e calcula a soma dos preços de fechamento, abertura, máximo e mínimo durante o período especificado. O loop evita dados inválidos ao utilizar a condição if(index < 0) para impedir o acesso a posições fora dos limites dos arrays.
Para evitar problemas de divisão por zero, o código verifica se o período é maior que zero após coletar os dados de preço do período. Se o período for válido, o código calcula a média dos preços de abertura, máximo, mínimo e fechamento ao longo do período e armazena os resultados nos buffers OpenBuffer, HighBuffer, LowBuffer e CloseBuffer. Esses buffers armazenam os valores calculados que serão utilizados no plot de candlestick. Por fim, a cor do candle é definida atualizando o ColorBuffer. O candle é colorido de verde (valor 0) quando o preço de fechamento é maior ou igual ao preço de abertura, indicando uma tendência de alta; caso o preço de fechamento seja menor que o preço de abertura, o candle é colorido de vermelho (valor 1), indicando uma tendência de baixa.
Ao final da função OnCalculate, o valor de rates_total é retornado, informando ao MetaTrader quantas barras foram processadas com sucesso. Esse valor é crucial para chamadas subsequentes do método OnCalculate, pois ele mantém o controle do número de barras processadas e garante que as atualizações de dados em tempo real sejam tratadas corretamente.

Ao trabalhar com formatos de candle, também estabelecemos a base para indicadores mais avançados, como os gráficos Heikin Ashi, que serão explorados em artigos futuros.
Conclusão
Em conclusão, este artigo apresentou conceitos básicos como a criação de indicadores personalizados, o uso de médias móveis e a visualização de dados em diferentes formatos, como estilos de linha e candle. Também exploramos como utilizar buffers e configurar plots para representar dados. Nos próximos artigos, focaremos em projetos mais interessantes. A melhor forma de aprender como iniciante é por meio de uma abordagem baseada em projetos, que divide o aprendizado em etapas gerenciáveis, em vez de sobrecarregar com detalhes desnecessários neste estágio. Esse método garante um progresso gradual e uma compreensão mais profunda dos conceitos-chave.
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/17096
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Do básico ao intermediário: Sub Janelas (II)
Testes de Robustez em Expert Advisors
Rede neural na prática: Surgimento de C_Neuron
Rede neural na prática: Quando usar um neurônio artificial e entender sua função em MQL5
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Obrigado pelo esforço. Isreal. Agradeço por isso.
Gostaria de fazer um comentário nesta parte da série para personalizar o indicador.
Você não utilizou o prev_calculated. Isso significa que, para cada tick em execução
, seu código recalcularia novamente cada barra calculada anteriormente.
Você não utilizou o prev_calculated. Isso significa que, para cada tick em execução
, seu código recalcularia novamente cada barra calculada anteriormente.