English Русский 中文 Español Deutsch 日本語
preview
Introdução ao MQL5 (Parte 13): Um Guia para Iniciantes na Construção de Indicadores Personalizados (II)

Introdução ao MQL5 (Parte 13): Um Guia para Iniciantes na Construção de Indicadores Personalizados (II)

MetaTrader 5Experts |
44 2
Israel Pelumi Abioye
Israel Pelumi Abioye

Introdução

Bem-vindo de volta à nossa série MQL5! Part 12 desta série explorou os fundamentos da construção de indicadores personalizados em MQL5. Criamos um indicador de Média Móvel do zero, implementando sua lógica manualmente em vez de depender de funções internas. Depois, ampliamos esse conhecimento transformando-o em uma Média Móvel no formato de velas, demonstrando como manipular elementos gráficos dentro de um indicador.

Com base nessa fundação, este artigo apresentará conceitos mais interessantes no desenvolvimento de indicadores. Usaremos uma abordagem baseada em projeto, como de costume, para garantir que você compreenda os tópicos colocando-os em prática. A criação de um indicador Heikin Ashi e o cálculo de uma Média Móvel utilizando seus dados serão os principais objetivos. Depois que esses indicadores forem construídos, desenvolveremos um Expert Advisor que incorpora os indicadores Heikin Ashi e Média Móvel. Mesmo aqueles que são novos em MQL5 podem acompanhar porque este é um artigo amigável para iniciantes. Para ajudar você a entender não apenas como a implementação funciona, mas também por que cada etapa é necessária, cada linha de código será explicada detalhadamente.

Este artigo abordará uma estratégia destinada apenas para fins educacionais. Não se destina a ser uma estratégia de trading que garanta sucesso ou aconselhamento financeiro. Antes de usar a estratégia em trading ao vivo, sempre teste em um ambiente sem risco.

Heikin Ashi (HA) e Média Móvel HA

Figura 1. Indicador Heikin Ashi e MA

Neste artigo, você aprenderá:

  • Como criar um indicador Heikin Ashi personalizado do zero em MQL5.
  • Utilizar dados de velas Heikin Ashi para calcular a Média Móvel Heikin Ashi.
  • Usar a função iCustom() para acessar indicadores que não são integrados e integrar seus dados em estratégias de trading.
  • Definir condições de entrada usando cruzamentos de Heikin Ashi e MA.
  • Gerenciar risco de forma eficaz definindo níveis de stop-loss e take-profit dinamicamente usando cálculos baseados em Heikin Ashi.
  • Aplicar um mecanismo de trailing stop usando padrões de velas Heikin Ashi para garantir lucros conforme as tendências se desenvolvem.

1. Indicador Heikin Ashi

1.1. Entendendo o Indicador Heikin Ashi

O indicador Heikin Ashi (HA) torna as tendências mais fáceis de visualizar, HA usa uma técnica única para determinar novos valores com base em dados históricos de preços médios, em contraste com gráficos de velas típicos, que exibem os preços exatos de abertura, máxima, mínima e fechamento para cada período. Isso ajuda os traders a filtrar o excesso de informação e se concentrar no que é importante, produzindo uma imagem mais clara e compreensível dos movimentos do mercado.

Cada vela em um gráfico de velas típico mostra o movimento do preço ao longo de um determinado período. Enquanto uma vela verde (bullish) mostra que o preço fechou mais alto do que abriu, uma vela vermelha (bearish) significa o contrário. Um vislumbre da volatilidade do mercado é fornecido aos traders pelos pavios finos acima e abaixo do corpo da vela, que mostram os preços mais altos e mais baixos atingidos durante esse tempo.

Mas as velas Heikin Ashi fazem as coisas de forma diferente. Elas usam um cálculo especial para suavizar as tendências em vez de relatar com precisão os movimentos de preço. Velas verdes mais longas com menos pavios são indicativas de uma tendência de alta, o que torna mais simples identificar e acompanhar o momentum bullish. Da mesma forma, velas vermelhas tornam-se mais visíveis durante uma tendência de baixa, indicando claramente movimentos negativos. Velas menores com pavios em ambas as extremidades frequentemente aparecem quando o mercado está em range ou não tem momentum significativo, indicando hesitação ou indecisão dos traders.

O indicador HA é único porque modifica os cálculos convencionais de velas usando uma técnica de média. Ele produz novos valores que criam uma representação mais suave e consistente do movimento do preço, em vez de simplesmente plotar os preços de abertura, máxima, mínima e fechamento do mercado. Ao remover o "ruído" de pequenas flutuações de preço, os traders conseguem identificar tendências melhor e tomar decisões mais informadas.

Heikin Ashi Close 

A média dos valores de abertura, máxima, mínima e fechamento do período atual é usada para determinar o preço de fechamento Heikin Ashi. Uma perspectiva mais equilibrada da mudança de preço é oferecida por velas padrão, que simplesmente usam o preço de fechamento.

A fórmula é:

Figura 2. H A_Close Formula

O Heikin Ashi Close suaviza as oscilações de preço ao fazer a média desses quatro valores, o que torna os padrões mais visíveis visualmente.

Heikin Ashi Open

A vela Heikin Ashi anterior, não a abertura real do mercado, é usada para determinar o preço Heikin Ashi Open. Ele é determinado fazendo a média dos valores anteriores de abertura e fechamento do Heikin Ashi:

Figura 3. H A_Open Formula

Heikin Ashi reduz os saltos imprevisíveis que frequentemente ocorrem em gráficos de velas convencionais ao estabelecer um fluxo contínuo de movimento de preço ao vincular o valor de abertura de cada nova vela ao anterior.

Heikin Ashi High

O preço Heikin Ashi High é o valor mais alto atingido durante o período; no entanto, ele considera três valores: a máxima do período atual, o Heikin Ashi Open e o Heikin Ashi Close, em vez de apenas a máxima real do mercado. Entre esses três, o mais alto é selecionado:

Figura 4. H A_High Formula

Heikin Ashi Low

Da mesma forma, o preço Heikin Ashi Low é calculado selecionando o menor valor entre o Heikin Ashi Close, Heikin Ashi Open e a mínima real do período:

Figura 5. H A_Low Formula

Essa abordagem mantém consistência com os métodos de suavização enquanto garante que o Heikin Ashi Low capture o ponto mais baixo da flutuação de preço. Heikin Ashi remove pequenas oscilações e fornece uma imagem mais precisa da direção do mercado usando esses cálculos. Usaremos esse raciocínio para construir nosso próprio indicador Heikin Ashi em MQL5 na próxima parte.

1.2. Benefícios de Usar Heikin Ashi

Como ele pode eliminar pequenas oscilações de preço, o indicador Heikin Ashi é um favorito entre traders e torna a identificação de tendências muito mais simples. Devido às rápidas mudanças de cor, gráficos de velas tradicionais podem ser difíceis de ler e frequentemente deixam os traders inseguros sobre se o mercado está subindo ou descendo. Ao usar dados de preço médios para suavizar o gráfico, Heikin Ashi resolve esse problema e ajuda você a evitar ficar preso em detalhes.

Uma sequência de velas vermelhas indica uma tendência de baixa, enquanto uma sequência de velas verdes normalmente indica uma forte tendência de alta. Devido a essa clareza, fica mais simples distinguir entre mudanças reais e de longo prazo no mercado e quedas breves. Heikin Ashi ajuda você a reduzir sinais falsos, evitando operações desnecessárias causadas por oscilações de preço de curto prazo. Ao usar dados históricos, ele filtra o ruído do mercado, oferecendo confirmação de tendência mais confiável. Muitos traders o combinam com ferramentas como RSI ou Médias Móveis para melhorar suas estratégias. Com sua visão mais clara da ação de preço, Heikin Ashi facilita decidir quando entrar ou sair de trades.

1.3. Implementando Heikin Ashi em MQL5

Implementar o indicador Heikin Ashi em MQL5 é o próximo passo após aprender sobre seu funcionamento. Construiremos nosso próprio indicador Heikin Ashi do zero porque o MetaTrader 5 não possui um. Para fazer isso, as fórmulas Heikin Ashi devem ser codificadas, aplicadas aos dados de preço e o indicador deve ser exibido no gráfico.

Como de costume, desenvolver um programa começa com a elaboração de um pseudocódigo que descreve a lógica antes de começarmos a escrever código. Isso garante que compreendamos cada etapa antes de colocar o programa em prática e ajuda a estruturá-lo corretamente.

Pseudocódigo:

INDICADOR DE CONFIGURAÇÃO

  • Definir o indicador para ser plotado em uma janela separada do gráfico.
  • Configurações de plotagem para velas Heikin Ashi
  • Definir 4 buffers para armazenar valores Heikin Ashi (Open, High, Low, Close).
DEFINIR BUFFERS

Criar buffers para armazenar os valores calculados para:

  • Heikin Ashi Open
  • Heikin Ashi High
  • Heikin Ashi Low
  • Heikin Ashi Close

CALCULE OS VALORES DE HEIKIN ASHI 

Percorrer dados históricos de preço para calcular valores Heikin Ashi usando as fórmulas:

  • HA Close = (Open + High + Low + Close) / 4
  • HA Open = (HA Open anterior + HA Close anterior) / 2
  • HA Open = (HA Open anterior + HA Close anterior) / 2
  • HA Low = Mínimo entre (Low, HA Open, HA Close)

1.3.1. Criando e Personalizando Heikin Ashi

Agora devemos avançar com a programação após criar um pseudocódigo. Como foi abordado no artigo anterior, o primeiro passo ao projetar e modificar um indicador é imaginar como ele deve aparecer no gráfico. A plotagem do indicador, a exibição das velas Heikin Ashi e a inclusão de quaisquer outros componentes, como cores para tendências bullish e bearish, devem ser decididas antes de criar qualquer código.

Devemos garantir que nosso indicador personalizado substitua corretamente seus próprios valores calculados no lugar dos gráficos de velas normais, já que Heikin Ashi altera a aparência das velas. Isso envolve configurar buffers para os preços open, high, low e close e garantir que as cores mudem dinamicamente para mostrar tendências bearish e bullish. Podemos especificar a estrutura do indicador e começar a escrever o código assim que tivermos essa visualização clara. Devemos definir as configurações de propriedade do indicador Heikin Ashi antes de aplicar sua lógica. Esses parâmetros determinam o estilo dos elementos plotados (como velas Heikin Ashi), o número de buffers que o indicador utilizará e como o indicador aparecerá no gráfico.

Exemplo:

// PROPERTY SETTINGS
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   1

// PLOT SETTINGS FOR HEIKIN ASHI CANDLES
#property indicator_label1  "Heikin Ashi"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrGreen, clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

Explicação:

Configurações da propriedade
#property indicator_separate_window

Isso instrui o MetaTrader 5 que o indicador deve ser exibido em uma janela diferente em vez de ser sobreposto no gráfico principal. Esta linha seria removida se quiséssemos que ele aparecesse diretamente no gráfico de preços.

Analogia

Considere seu gráfico de trading como uma estação de trabalho onde você examina mudanças no mercado. Considere seu gráfico de trading como uma estação de trabalho onde você examina mudanças no mercado. Agora, imagine-se trabalhando em um projeto paralelo minucioso que precisa de uma área específica, como um pequeno quadro branco ao lado da sua mesa. Ao mover essa atividade específica para o quadro branco, você pode se concentrar nela de forma independente em vez de sobrecarregar o espaço principal de trabalho.

De forma semelhante, #property indicator_separate_window torna mais simples examinar tendências sem interferir nos dados padrão de velas ao mover o indicador Heikin Ashi para sua própria janela em vez de sobrepô-lo no gráfico principal de preços.

#property indicator_buffers 5

Isso especifica quantos buffers o indicador utilizará. Cinco buffers estão sendo usados neste caso, um para representação de cor e os outros para armazenar os valores Heikin Ashi calculados (Open, High, Low e Close).

Analogia

Agora que você tem um quadro branco diferente ao lado da sua bancada para seu projeto paralelo, imagine-se precisando de cinco bandejas diferentes para acompanhar seu trabalho. Esboços, medições, anotações e assim por diante são armazenados em bandejas diferentes. Isso mantém tudo organizado para que você possa encontrar rapidamente a informação relevante quando precisar.

Semelhante a essas bandejas, #property indicator_buffers 5 garante que vários pontos de dados do Heikin Ashi sejam mantidos separados. Aqui, temos cinco buffers: um para representação de cor e quatro para os valores Heikin Ashi (Open, High, Low e Close). Esses buffers mantêm os cálculos do indicador estruturados, o que torna mais simples exibir os dados corretos no gráfico, da mesma forma que as bandejas mantêm seu espaço de trabalho organizado.

#property indicator_plots 1

Isso indica quantos gráficos o indicador exibirá. Precisamos apenas de um plot porque estamos desenhando velas Heikin Ashi como uma única unidade.

Analogia

Depois de organizar seus materiais em bandejas distintas e configurar seu espaço de trabalho no quadro branco, o próximo passo é escolher como exibir seu trabalho. Em vez de criar vários gráficos distintos, imagine-se criando um único diagrama abrangente que unifica todos os dados em uma representação visual única e compreensível.

Da mesma forma, o MetaTrader 5 é informado por #property indicator_plots 1 de que o indicador Heikin Ashi será mostrado como um único elemento plotado. Semelhante ao seu único diagrama no quadro branco, vários buffers armazenam dados distintos (Open, High, Low, Close e cor), mas todos se combinam para criar um único conjunto de velas. Precisamos apenas de um plot para mostrar as velas Heikin Ashi no gráfico porque estamos apenas plotando elas.

Configurações do gráfico

#property indicator_label1  "Heikin Ashi"
#property indicator_type1   DRAW_COLOR_CANDLES  
#property indicator_color1  clrGreen, clrRed    
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

Analogia

Depois de organizar seus materiais e configurar seu espaço de trabalho no quadro branco, é importante comunicar seus resultados de forma clara e compreensível. Para tornar as tendências mais aparentes, você escolhe empregar símbolos codificados por cores em vez de escrever texto simples ou criar desenhos abstratos. Você identifica claramente o que seu diagrama representa rotulando-o como "Heikin Ashi" para qualquer pessoa que esteja observando o quadro branco. Da mesma forma, #property indicator_label1 "Heikin Ashi" dá um nome ao indicador e garante que ele apareça na lista de indicadores do MetaTrader 5. Dessa maneira, os traders podem identificá-lo rapidamente em seus gráficos entre outros indicadores.

#property indicator_type1 DRAW_COLOR_CANDLES informa ao MetaTrader 5 para usar velas codificadas por cores em vez de linhas ou histogramas. As cores são definidas por #property indicator_color1 clrGreen, clrRed, onde verde representa velas bullish e vermelho representa velas bearish. Essa clareza visual torna mais fácil identificar tendências rapidamente. Para manter seu quadro branco limpo e legível, você decide usar um traço de marcador sólido em vez de linhas tracejadas ou pontilhadas.

Da mesma forma, #property indicator_style1 STYLE_SOLID garante que as velas Heikin Ashi sejam preenchidas com uma cor sólida, tornando-as visualmente distintas. Por fim, assim como você evita deixar suas linhas muito grossas para que não sobrecarreguem seu diagrama, #property indicator_width1 1 mantém o contorno das velas com uma largura adequada para clareza sem sobrecarregar o gráfico. Ao configurar o indicador Heikin Ashi dessa forma, criamos uma representação clara, estruturada e visualmente intuitiva das tendências de mercado, assim como você fez com seu espaço de trabalho bem organizado no quadro branco.

Agora que configuramos as propriedades do indicador e as configurações de plotagem, o próximo passo é definir buffers que armazenarão os preços das velas Heikin Ashi. Buffers atuam como contêineres de armazenamento para os valores calculados do indicador, permitindo que o MetaTrader 5 os exiba no gráfico. Neste caso, precisamos de buffers para armazenar os preços Heikin Ashi Open, High, Low e Close, bem como um buffer adicional para representação de cor. Também definiremos seus respectivos índices de buffer para garantir que cada buffer corresponda corretamente aos dados pretendidos.

Exemplo:

// PROPERTY SETTINGS
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   1

// PLOT SETTINGS FOR HEIKIN ASHI CANDLES
#property indicator_label1  "Heikin Ashi"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrGreen, clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

// INDICATOR BUFFERS
double HA_Open[];
double HA_High[];
double HA_Low[];
double HA_Close[];
double ColorBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
// SET BUFFERS
   SetIndexBuffer(0, HA_Open, INDICATOR_DATA);
   SetIndexBuffer(1, HA_High, INDICATOR_DATA);
   SetIndexBuffer(2, HA_Low, INDICATOR_DATA);
   SetIndexBuffer(3, HA_Close, INDICATOR_DATA);
   SetIndexBuffer(4, ColorBuffer, INDICATOR_COLOR_INDEX);

   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[])
  {

   return(rates_total);

  }

Explicação:

Construímos arrays (buffers) que manterão os preços Open, High, Low e Close das velas modificadas para armazenar os valores calculados do indicador Heikin Ashi. Também controlamos a cor de cada vela usando um buffer diferente.

double HA_Open[];
double HA_High[];
double HA_Low[];
double HA_Close[];
double ColorBuffer[];

O buffer HA_Open[] contém o preço de abertura Heikin Ashi de cada vela, enquanto HA_High[] contém o preço máximo da vela Heikin Ashi. O buffer HA_Open[] contém o preço de abertura Heikin Ashi de cada vela, enquanto HA_High[] contém o preço máximo da vela Heikin Ashi. Além disso, o ColorBuffer[] é usado para decidir a cor de cada vela para distinguir entre velas bullish (verde) e bearish (vermelho). O gráfico pode salvar e exibir as velas Heikin Ashi atualizadas graças ao trabalho conjunto desses buffers.

SetIndexBuffer(0, HA_Open, INDICATOR_DATA);
SetIndexBuffer(1, HA_High, INDICATOR_DATA);
SetIndexBuffer(2, HA_Low, INDICATOR_DATA);
SetIndexBuffer(3, HA_Close, INDICATOR_DATA);
SetIndexBuffer(4, ColorBuffer, INDICATOR_COLOR_INDEX);     

A função SetIndexBuffer no MetaTrader 5 conecta buffers específicos aos seus índices correspondentes, garantindo que os dados Heikin Ashi sejam manipulados e exibidos corretamente. A função SetIndexBuffer no MetaTrader 5 conecta buffers específicos aos seus índices correspondentes, garantindo que os dados Heikin Ashi sejam manipulados e exibidos corretamente. De acordo com a estrutura de velas da plataforma, o preço Open é sempre atribuído ao índice 0, e os valores High, Low e Close são mapeados para os índices 1, 2 e 3.

SetIndexBuffer(4, ColorBuffer, INDICATOR_COLOR_INDEX) especifica a cor de cada vela, indicando movimentos bullish (verde) ou bearish (vermelho), para diferenciar visualmente as tendências. O indicador Heikin Ashi garante representação correta de preço e estilo visual ao indexar adequadamente esses buffers, permitindo que os traders analisem tendências rapidamente e tomem decisões bem informadas.

O indicador Heikin Ashi garante representação correta de preço e estilo visual ao indexar adequadamente esses buffers, permitindo que os traders analisem tendências rapidamente e tomem decisões bem informadas.

Exemplo:

// PROPERTY SETTINGS
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   1

// PLOT SETTINGS FOR HEIKIN ASHI CANDLES
#property indicator_label1  "Heikin Ashi"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrGreen, clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

// INDICATOR BUFFERS
double HA_Open[];
double HA_High[];
double HA_Low[];
double HA_Close[];
double ColorBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
// SET BUFFERS
   SetIndexBuffer(0, HA_Open, INDICATOR_DATA);
   SetIndexBuffer(1, HA_High, INDICATOR_DATA);
   SetIndexBuffer(2, HA_Low, INDICATOR_DATA);
   SetIndexBuffer(3, HA_Close, INDICATOR_DATA);
   SetIndexBuffer(4, ColorBuffer, INDICATOR_COLOR_INDEX);

   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 < 2)
      return 0; // ENSURE ENOUGH DATA

   for(int i = 1; i < rates_total; i++)  // START FROM SECOND BAR
     {
      // HEIKIN ASHI CLOSE FORMULA
      HA_Close[i] = (open[i] + high[i] + low[i] + close[i]) / 4.0;

      // HEIKIN ASHI OPEN FORMULA
      HA_Open[i] = (HA_Open[i - 1] + HA_Close[i - 1]) / 2.0;

      // HEIKIN ASHI HIGH FORMULA
      HA_High[i] = MathMax(high[i], MathMax(HA_Open[i], HA_Close[i]));

      // HEIKIN ASHI LOW FORMULA
      HA_Low[i] = MathMin(low[i], MathMin(HA_Open[i], HA_Close[i]));

      // SET COLOR: GREEN FOR BULLISH, RED FOR BEARISH
      ColorBuffer[i] = (HA_Close[i] >= HA_Open[i]) ? 0 : 1;
     }

   return(rates_total);

  }

Como a primeira barra não contém dados anteriores, este método calcula valores Heikin Ashi começando a partir da segunda barra. Como a primeira barra não contém dados anteriores, este método calcula valores Heikin Ashi começando a partir da segunda barra. Para suavizar oscilações de preço, o preço de fechamento é a média dos preços de abertura, máxima, mínima e fechamento da barra atual. O preço Open garante transições suaves ao fazer a média entre o Heikin Ashi Open e Close da barra anterior. Por fim, as velas são coloridas em vermelho (bearish) caso contrário ou verde (bullish) se o Close for menor ou igual ao Open. Isso ajuda os traders a visualizar tendências ao reduzir o ruído do mercado.

Figura 6. Indicador HA


2. Criando uma média móvel a partir de dados Heikin Ashi

Agora que geramos com sucesso as velas Heikin Ashi, o próximo passo é criar uma Média Móvel (MA) baseada nos valores Heikin Ashi em vez de dados padrão de preço.

Pseudocódigo:

MODIFICAR PROPRIEDADES DO INDICADOR

  • Ajustar a quantidade de buffers de cinco para seis para criar espaço para a Média Móvel Heikin Ashi.MODIFICAR PROPRIEDADES DO INDICADOR 

  • Alterar o número de plots de 1 para 2 para que as velas e a Média Móvel Heikin Ashi possam ser vistas juntas.

DEFINIR BUFFER PARA MÉDIA MÓVEL DE HEIKIN ASHI

  • Criar um buffer para armazenar os valores da Média Móvel Heikin Ashi.
  • Definir uma variável de entrada para o período da Média Móvel (por exemplo, 20).

DEFINIR BUFFER PARA MÉDIA MÓVEL DE HEIKIN ASHI

  • Vincular o buffer a um índice para armazenar valores de MA calculados.
  • Definir o índice de plotagem para começar no período da Média Móvel para garantir exibição correta.

CALCULAR A MÉDIA MÓVEL DE HEIKIN ASHI

  • Começar o loop a partir de (period - 1) para garantir dados suficientes.
  • Calcular a soma dos últimos 'n' valores de Heikin Ashi Close.
  • Dividir a soma pelo período e armazenar o resultado no buffer.

Exemplo:

// PROPERTY SETTINGS
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_plots   2

// PLOT SETTINGS FOR HEIKIN ASHI CANDLES
#property indicator_label1  "Heikin Ashi"
#property indicator_type1   DRAW_COLOR_CANDLES  
#property indicator_color1  clrGreen, clrRed    
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//PROPERTIES OF THE Heikin MA
#property indicator_label2  "Heikin MA"   
#property indicator_type2   DRAW_LINE  
#property indicator_style2  STYLE_DASH 
#property indicator_width2  1          
#property indicator_color2  clrBrown   

// INDICATOR BUFFERS
double HA_Open[];
double HA_High[];
double HA_Low[];
double HA_Close[];
double ColorBuffer[]; 

double Heikin_MA_Buffer[];
int input  heikin_ma_period = 20;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    // SET BUFFERS
    SetIndexBuffer(0, HA_Open, INDICATOR_DATA);
    SetIndexBuffer(1, HA_High, INDICATOR_DATA);
    SetIndexBuffer(2, HA_Low, INDICATOR_DATA);
    SetIndexBuffer(3, HA_Close, INDICATOR_DATA);
    SetIndexBuffer(4, ColorBuffer, INDICATOR_COLOR_INDEX);
    
    SetIndexBuffer(5, Heikin_MA_Buffer, INDICATOR_DATA);  
    PlotIndexSetInteger(5, PLOT_DRAW_BEGIN, heikin_ma_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 < 2) return 0; // ENSURE ENOUGH DATA
      
    for (int i = 1; i < rates_total; i++) // START FROM SECOND BAR
    {
        // HEIKIN ASHI CLOSE FORMULA
        HA_Close[i] = (open[i] + high[i] + low[i] + close[i]) / 4.0;

        // HEIKIN ASHI OPEN FORMULA
        HA_Open[i] = (HA_Open[i - 1] + HA_Close[i - 1]) / 2.0;

        // HEIKIN ASHI HIGH FORMULA
        HA_High[i] = MathMax(high[i], MathMax(HA_Open[i], HA_Close[i]));

        // HEIKIN ASHI LOW FORMULA
        HA_Low[i] = MathMin(low[i], MathMin(HA_Open[i], HA_Close[i]));

        // SET COLOR: GREEN FOR BULLISH, RED FOR BEARISH
        ColorBuffer[i] = (HA_Close[i] >= HA_Open[i]) ? 0 : 1;
    }    
    
     for(int i = heikin_ma_period - 1; i < rates_total; i++)
     {

      double sum = 0.0;
      for(int j = 0; j < heikin_ma_period; j++)
        {
         sum += HA_Close[i - j];
        }

      Heikin_MA_Buffer[i] = sum / heikin_ma_period;

     }

    return rates_total;
}

Explicação:

Primeiro devemos modificar as configurações de buffer e de plotagem para incorporar a Média Móvel Heikin Ashi (HA MA) ao indicador. Usando #property indicator_buffers 6, a contagem de buffers é aumentada de 5 para 6, garantindo que haja um buffer adicional para armazenar os dados da Heikin MA. Usando #property indicator_buffers 6, a contagem de buffers é aumentada de 5 para 6, garantindo que haja um buffer adicional para armazenar os dados da Heikin MA. Isso garante que o indicador possa lidar de forma eficaz com ambos os conjuntos de dados.

As propriedades do plot da Heikin MA são então configuradas. #property indicator_label2 é o rótulo. Ao dar um nome à Média Móvel, "Heikin MA" torna-a perceptível na lista de indicadores. Para definir que a Média Móvel será exibida como uma linha em vez de velas, o tipo é definido usando #property indicator_type2 DRAW_LINE. Para definir que a Média Móvel será exibida como uma linha em vez de velas, o tipo é definido usando #property indicator_type2 DRAW_LINE. Definimos #property indicator_style2 STYLE_DASH para tornar a linha tracejada e usamos #property indicator_width2 1 para determinar sua largura e aumentar a visibilidade.

Usando #property indicator_color2 clrBrown, a cor é definida como marrom, garantindo um contraste marcante com as velas Heikin Ashi. SetIndexBuffer(5, Heikin_MA_Buffer, INDICATOR_DATA); é usado para vincular o buffer ao indicador, permitindo que o MetaTrader 5 gerencie e exiba os valores corretamente. PlotIndexSetInteger(5, PLOT_DRAW_BEGIN, heikin_ma_period); também garante que a Média Móvel seja plotada apenas depois que houver barras suficientes disponíveis.

Calcular a Média Móvel Heikin Ashi é a última etapa. Para garantir que tenhamos pontos de dados suficientes para o cálculo, o loop começa em heikin_ma_period -1. A Média Móvel é calculada dentro do loop somando os últimos n valores de Heikin Ashi Close e dividindo o total pelo período. O indicador então plota a Média Móvel ao lado das velas Heikin Ashi após armazenar o resultado em Heikin_MA_Buffer[i], fornecendo aos traders uma ferramenta suavizada de acompanhamento de tendência.

Figura 7. Indicador HA e MA HA


3. Integrando um Indicador Personalizado em um Expert Advisor

Você pode estar se perguntando, agora que criamos um indicador personalizado, como podemos usá-lo para criar um Expert Advisor. Usando o indicador Heikin Ashi que foi criado no capítulo anterior, continuaremos nossa abordagem baseada em projetos neste capítulo e projetaremos um EA. Nossa técnica será transformada em um robô de trading funcional graças ao uso de sinais Heikin Ashi por este EA para automatizar decisões de trading.

Uma estratégia simples de cruzamento baseada na Média Móvel Heikin Ashi (HA MA) e nas velas Heikin Ashi (HA) será nossa estratégia de trading. Essa técnica ajuda a identificar possíveis reversões de tendência e sinais de continuação observando a relação entre o preço de fechamento da vela Heikin Ashi e a Média Móvel Heikin Ashi. Uma tendência de alta e uma possível oportunidade de compra são indicadas por uma vela Heikin Ashi fechando acima da Média Móvel Heikin Ashi. Por outro lado, uma vela Heikin Ashi fechando abaixo da Média Móvel Heikin Ashi gera um sinal de venda, sugerindo uma reversão de tendência bearish e uma possível oportunidade de venda.

Figura 8. Lógica de compra e venda

3.1. Recuperando Dados do Indicador

A primeira coisa em que você deve pensar ao integrar um indicador personalizado em um EA é como inserir os dados do indicador em seu EA. A primeira coisa em que você deve pensar ao integrar um indicador personalizado em um EA é como inserir os dados do indicador em seu EA. O EA não consegue basear decisões de trade no indicador se seus valores estiverem inacessíveis.

  • Preço HA Open
  • Preço HA Open
  • Preço HA Low
  • Preço HA Close

Nossos sinais de trading são baseados nesses parâmetros, que serão usados para avaliar se uma vela Heikin Ashi cruzou acima ou abaixo da HA MA.

Exemplo:

// Declare arrays to store Heikin Ashi data from the custom indicator
double heikin_open[];   // Stores Heikin Ashi Open prices
double heikin_close[];  // Stores Heikin Ashi Close prices
double heikin_low[];    // Stores Heikin Ashi Low prices
double heikin_high[];   // Stores Heikin Ashi High prices
double heikin_ma[];     // Stores Heikin Ashi Moving Average values

int heikin_handle;      // Handle for the custom Heikin Ashi indicator

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
// Ensure arrays store data in a time series format (most recent data first)
   ArraySetAsSeries(heikin_open, true);
   ArraySetAsSeries(heikin_close, true);
   ArraySetAsSeries(heikin_low, true);
   ArraySetAsSeries(heikin_high, true);
   ArraySetAsSeries(heikin_ma, true);

// Load the custom Heikin Ashi indicator and get its handle
   heikin_handle = iCustom(_Symbol, PERIOD_CURRENT, "Project7 Heikin Ashi Indicator.ex5");

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// Nothing to clean up in this case, but can be used for resource management if needed
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Copy the latest 3 values of each buffer from the Heikin Ashi indicator
   CopyBuffer(heikin_handle, 0, 0, 3, heikin_open);  // Get HA Open values
   CopyBuffer(heikin_handle, 1, 0, 3, heikin_high);  // Get HA High values
   CopyBuffer(heikin_handle, 2, 0, 3, heikin_low);   // Get HA Low values
   CopyBuffer(heikin_handle, 3, 0, 3, heikin_close); // Get HA Close values
   CopyBuffer(heikin_handle, 5, 0, 3, heikin_ma);    // Get HA Moving Average values

// Print index 0 values to the terminal
   Print("HA Open: ", heikin_open[0],
         "\nHA High: ", heikin_high[0],
         "\nHA Low: ", heikin_low[0],
         "\nHA Close: ", heikin_close[0],
         "\nHA MA: ", heikin_ma[0]);
  }

Explicação:

Declaração de arrays para armazenar dados Heikin Ashi

Declarar arrays para armazenar os dados coletados do indicador é o primeiro passo na integração de um indicador personalizado em um Expert Advisor (EA). Cinco arrays são declarados neste caso para armazenar os vários componentes do indicador Heikin Ashi:

  • heikin_open[]: Armazena os preços de abertura Heikin Ashi.
  • heikin_close[]: Para os preços de fechamento Heikin Ashi.
  • heikin_low[]: Armazena os preços mínimos Heikin Ashi.
  • heikin_low[]: Armazena os preços mínimos Heikin Ashi.
  • heikin_ma[]: Armazena os valores da Média Móvel Heikin Ashi.

Esses arrays são cruciais porque fornecem ao EA acesso aos valores Heikin Ashi passados e atuais. O EA pode avaliar movimentos históricos de preço e ajustar decisões de trading ao armazenar esses dados. Esses arrays não precisam ser inicializados com valores fixos, pois serão preenchidos com dados do indicador personalizado; em vez disso, serão atualizados dinamicamente conforme novos dados se tornarem disponíveis.

Declarando o Handle do Indicador

O handle do indicador Heikin Ashi personalizado é armazenado na variável heikin_handle. Um handle em MQL5 é uma referência distinta a uma instância de indicador em execução em segundo plano. Como permite que o EA interaja com o indicador e solicite dados quando necessário, esse handle é essencial. O EA não teria acesso aos valores Heikin Ashi sem um handle. Posteriormente, quando a função iCustom() for executada, um valor será atribuído ao handle. O indicador não foi carregado corretamente se o handle for inválido (retornar -1), o que impede o EA de recuperar os dados necessários.

Inicialização de Arrays no Formato de Série Temporal

Os arrays devem ser configurados para que os dados mais recentes estejam sempre no índice 0 quando forem declarados. Os arrays devem ser configurados para que os dados mais recentes estejam sempre no índice 0 quando forem declarados.

A função é aplicada a cada um dos cinco arrays da seguinte forma:

 ArraySetAsSeries(heikin_open, true);
 ArraySetAsSeries(heikin_close, true);
 ArraySetAsSeries(heikin_low, true);
 ArraySetAsSeries(heikin_high, true);
 ArraySetAsSeries(heikin_ma, true);

Ao converter esses arrays para um formato de série temporal, o índice 0 permite que o EA sempre acesse os dados Heikin Ashi mais recentes. Ao converter esses arrays para um formato de série temporal, o índice 0 permite que o EA sempre acesse os dados Heikin Ashi mais recentes.

Carregando o Indicador Heikin Ashi Personalizado com iCustom()

Ao estabelecer, precisamos de um meio de acessar os dados para incorporar um indicador personalizado em um Expert Advisor (EA). Podemos carregar um indicador personalizado e receber um handle que o EA pode usar para solicitar valores do indicador usando a função iCustom(). Podemos carregar um indicador personalizado e receber um handle que o EA pode usar para solicitar valores do indicador usando a função iCustom().

heikin_handle = iCustom(_Symbol, PERIOD_CURRENT, "Project7 Heikin Ashi Indicator.ex5");

  • _Symbol: Isso informa à função para aplicar o indicador ao símbolo de trading atual (por exemplo, EUR/USD, GBP/JPY, etc.). Isso garante que o indicador processe dados para o mesmo ativo em que o EA está sendo executado.
  • PERIOD_CURRENT: Isso aplica o indicador ao mesmo timeframe que o EA. Se o EA estiver sendo executado em um gráfico H1, o indicador também será aplicado em H1.
  • "Project7 Heikin Ashi Indicator.ex5": Isso especifica o nome do arquivo do indicador personalizado que o EA deve usar. "Project7 Heikin Ashi Indicator.ex5": Isso especifica o nome do arquivo do indicador personalizado que o EA deve usar.

Garantir que o arquivo do indicador esteja armazenado no diretório apropriado do MetaTrader 5 é essencial. O indicador precisa estar na pasta Indicators do diretório MQL5. O caminho completo desse diretório é:

MQL5/Indicators/

A principal função que conecta um indicador personalizado a um EA é iCustom(), em resumo. Ela fornece ao EA um handle que permite a extração dinâmica de valores do indicador. A função não funcionará corretamente a menos que o indicador esteja devidamente colocado no diretório Indicators (ou em uma subpasta dentro dele).

Copiando Dados do Indicador para os Arrays

Depois de obter o handle, o EA pode recuperar os valores Heikin Ashi mais recentes do indicador usando a função CopyBuffer(). Os dados são copiados para os arrays do EA a partir dos buffers internos de um indicador usando a função CopyBuffer(). Este EA chama o método cinco vezes, uma para cada tipo de dado:

CopyBuffer(heikin_handle, 0, 0, 3, heikin_open);  // Get HA Open values
CopyBuffer(heikin_handle, 1, 0, 3, heikin_high);  // Get HA High values
CopyBuffer(heikin_handle, 2, 0, 3, heikin_low);   // Get HA Low values
CopyBuffer(heikin_handle, 3, 0, 3, heikin_close); // Get HA Close values
CopyBuffer(heikin_handle, 5, 0, 3, heikin_ma);    // Get HA Moving Average values

Os dados são recuperados do indicador personalizado usando a mesma estrutura para cada chamada de CopyBuffer(). O handle recuperado da função iCustom() é o primeiro parâmetro, heikin_handle. O EA pode acessar os dados do indicador Heikin Ashi personalizado usando esse handle como referência. O EA pode acessar os dados do indicador Heikin Ashi personalizado usando esse handle como referência. Em MQL5, os indicadores usam buffers para armazenar seus dados, e cada buffer recebe um índice único. O preço Heikin Ashi Open neste caso é representado pelo buffer 0, o High pelo buffer 1, o Low pelo buffer 2, o Close pelo buffer 3 e a Média Móvel Heikin Ashi pelo buffer 5. Garantimos que os dados corretos sejam obtidos do indicador ao fornecer esses índices.

Os dados devem ser copiados começando pela barra mais recente (vela atual), de acordo com a terceira opção, 0. Isso garante que o EA esteja sempre utilizando os dados de mercado mais recentes, o que é necessário para decisões de trading em tempo real. Três pontos de dados devem ser replicados, de acordo com o quarto parâmetro, 3. A recuperação de múltiplos valores permite que o EA examine dados Heikin Ashi históricos e atuais, o que é útil para descobrir padrões ou validar tendências. 

Por fim, os arrays correspondentes — heikin_open, heikin_high, heikin_low, heikin_close e heikin_ma — são usados para armazenar os dados recuperados. Os valores recuperados são armazenados nesses arrays para que o EA possa processá-los e utilizá-los em sua lógica de trading. Para que o EA tome decisões de trading bem informadas com base nas tendências de preço, é essencial que ele tenha informações atuais do indicador Heikin Ashi.

3.2. Utilizando Dados do Indicador em Nossa Estratégia de Trading

Depois de aprender como extrair dados do indicador personalizado, agora precisamos compreender como aplicar esses dados à nossa estratégia de trading. Isso permitirá que utilizemos com sucesso o indicador Heikin Ashi em um EA e mostrará como basear decisões de trading nos valores que são recuperados. Além disso, esse processo oferece uma oportunidade de investigar alguns conceitos importantes do MQL5, o que melhora nossa compreensão à medida que avançamos neste texto. 

No entanto, não podemos simplesmente aplicar o raciocínio sem considerar elementos cruciais do EA. A administração adequada de trades requer a incorporação de determinados recursos. Isso inclui acompanhar a quantidade de posições abertas, implementar trailing stops, controlar parâmetros de risco e garantir que o EA execute trades de forma metódica. Ao incluir esses elementos essenciais, construímos um sistema de trading mais confiável e útil que pode funcionar bem em um ambiente real.

3.2.1. Rastreamento de Posições de Compra e Venda Abertas no Expert Advisor

Devemos garantir que apenas uma posição de compra e uma de venda estejam abertas ao mesmo tempo para que a técnica de trading funcione corretamente. Devemos garantir que apenas uma posição de compra e uma de venda estejam abertas ao mesmo tempo para que a técnica de trading funcione corretamente. O EA pode decidir se deve estabelecer uma nova posição ou aguardar que uma existente seja fechada antes de executar outra ao monitorar o número de posições abertas. Esse método garante que a estratégia funcione conforme planejado e melhora o gerenciamento de posições.

Exemplo:

int totalPositions = 0;
int position_type_buy = 0;
int position_type_sell = 0;

for(int i = 0; i < PositionsTotal(); i++)
  {
   ulong ticket = PositionGetTicket(i);

   if(PositionSelectByTicket(ticket))
     {
      if(PositionGetInteger(POSITION_MAGIC) == MagicNumber && PositionGetString(POSITION_SYMBOL) == ChartSymbol(ChartID())
     {
      totalPositions++;
      if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
           {
            position_type_buy++;
           }
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
           {
            position_type_sell++;
           }
        }
     }
  }

O EA conta o número de trades de compra, venda e o total de trades para acompanhar as posições abertas. Ele percorre as posições abertas, classifica-as como buy ou sell e utiliza o número mágico e o símbolo do gráfico para confirmar que estão alinhadas com a estratégia. Ao permitir apenas um trade de compra e um de venda por vez, isso garante um gerenciamento de posição controlado.

3.2.2. Rastreamento de Limites Diários de Trades no Expert Advisor

A soma de trades realizados durante uma determinada sessão de trading é o principal assunto desta seção. A soma de trades realizados durante uma determinada sessão de trading é o principal assunto desta seção. Ao evitar overtrading durante o período definido, essa abordagem ajuda a manter um comportamento de trading controlado.

Exemplo:

input int daily_trades = 6; // Total Daily Trades

// Start and end time for
string start = "00:00";
string end = "23:50";

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   datetime start_time = StringToTime(start);
   datetime end_time = StringToTime(end);
   bool success = HistorySelect(start_time, end_time);

// Getting total trades
   int totalDeal = 0;
   int deal_type_buy = 0;
   int deal_type_sell = 0;
   if(success)
     {
      for(int i = 0; i < HistoryDealsTotal(); i++)
        {
         ulong ticket = HistoryDealGetTicket(i);

         if(HistoryDealGetInteger(ticket, DEAL_MAGIC) == MagicNumber && HistoryDealGetString(ticket,DEAL_SYMBOL) == ChartSymbol(chart_id))
           {
            if(HistoryDealGetInteger(ticket, DEAL_ENTRY) == DEAL_ENTRY_IN)
              {
               totalDeal++;
               if(HistoryDealGetInteger(ticket, DEAL_TYPE) == DEAL_TYPE_BUY)
                 {

                  deal_type_buy++;

                 }
               if(HistoryDealGetInteger(ticket, DEAL_TYPE) == DEAL_TYPE_SELL)
                 {

                  deal_type_sell++;

                 }
              }
           }
        }
     }
  }

Explicação:

O Expert Advisor inicialmente converte os horários especificados de início e término para o formato datetime para acompanhar o número total de trades realizados durante uma sessão de trading. A função HistorySelect() é então usada para selecionar o histórico de trading que se enquadra nesse intervalo de tempo. O EA configura contadores para registrar o número total de trades executados e o número de operações de compra e venda separadamente se a seleção for bem-sucedida.

O EA então extrai o número do ticket de cada trade percorrendo o histórico de trading. Para garantir que apenas negociações relevantes sejam contabilizadas, ele verifica se o trade foi aberto usando o mesmo Magic Number e símbolo do gráfico atual. O número total de trades é aumentado se o trade for identificado como uma operação de entrada. Depois de determinar se o trade foi realizado, o EA atualiza os contadores correspondentes. Isso garante que a estratégia monitore as transações executadas e impede que o limite diário de trading seja excedido.

3.2.3. Prevenindo Trades Repetidos dentro da Mesma Vela

Em alguns casos, o EA pode abrir um novo trade imediatamente após fechar uma posição existente se você quiser que novas operações sejam concluídas apenas no preço de abertura de uma nova barra. Isso é especialmente verdadeiro se as condições de trading ainda forem as mesmas. Trades consecutivos não intencionais dentro da mesma vela podem resultar disso. Nesta parte, veremos maneiras de evitar isso, incluindo garantir que as operações sejam executadas apenas no preço de abertura da barra seguinte, melhorar o controle de trades e impedir reentradas desnecessárias.

Exemplo:

// Declare an array to store time data
datetime time[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
// Ensure the time array is structured as a time series (most recent data first)
   ArraySetAsSeries(time, true);

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Retrieve the latest three time values from the current symbol and timeframe
   CopyTime(_Symbol, PERIOD_CURRENT, 0, 3, time);

// Select trading history from the earliest recorded time to the current time
   bool trade_control = HistorySelect(time[0], TimeCurrent());

// Variable to count the number of closed trades
   int total_deals_out = 0;

// If the trading history selection is successful, process the data
   if(trade_control)
     {
      // Loop through all closed trades in the history
      for(int i = 0; i < HistoryDealsTotal(); i++)
        {
         // Get the ticket number of the historical trade
         ulong ticket = HistoryDealGetTicket(i);

         // Check if the trade matches the current EA's Magic Number and symbol
         if(HistoryDealGetInteger(ticket, DEAL_MAGIC) == MagicNumber && HistoryDealGetString(ticket, DEAL_SYMBOL) == ChartSymbol(chart_id))
           {
            // If the trade was an exit trade, increment the counter
            if(HistoryDealGetInteger(ticket, DEAL_ENTRY) == DEAL_ENTRY_OUT)
              {
               total_deals_out++;
              }
           }
        }
     }
  }

Explicação:

Esse recurso impede que o EA abra um trade dentro da mesma vela após fechar um. Usando CopyTime(), que retorna os timestamps das barras mais recentes, o procedimento primeiro recupera os valores de tempo mais recentes do gráfico. Em seguida, desde o primeiro tempo de barra registrado (time[0]) até o tempo atual do mercado (TimeCurrent()), o EA seleciona o histórico de trades dentro desse intervalo.

Para encontrar trades fechados que correspondam ao número mágico e ao símbolo do EA, ele então percorre o histórico de trading. O contador total_deals_out é incrementado se um trade fechado — mais especificamente, um trade de saída (DEAL_ENTRY_OUT) — for encontrado. Se um trade foi recentemente fechado dentro da mesma vela, esse contador pode ajudar a identificar isso. Se um trade foi recentemente fechado dentro da mesma vela, esse contador pode ajudar a identificar isso.

3.2.4. Implementando Gerenciamento de Risco e Execução de Trades com Heikin Ashi

Para garantir que trades de compra e venda sejam executados de acordo com os sinais Heikin Ashi, especificaremos os requisitos para execução de trades nesta seção. Além disso, ao determinar tamanhos de lote com base em um risco em dólares predeterminado por trade e uma relação risco-retorno (RRR), integraremos gerenciamento de risco. Essa abordagem evita exposição excessiva ao risco enquanto mantém o trading controlado.

Exemplo:

input  double dollar_risk = 12.0; // How Many Dollars($) Per Trade?
input double RRR = 3;

double ask_price;
double lot_size;
double point_risk;
double take_profit;

// Variable to store the time of the last executed trade
datetime lastTradeBarTime = 0;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

// Get the opening time of the current bar
   datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);

// Check conditions for opening a buy position
// Ensures Heikin Ashi candle crosses above the moving average
// Limits trades per day and prevents multiple trades in the same candlestick
   if(heikin_open[1] < heikin_ma[1] && heikin_close[1] > heikin_ma[1] &&
      deal_type_buy < (daily_trades / 2) && total_deals_out < 1 &&
      totalPositions < 1 && currentBarTime != lastTradeBarTime)
     {
      // Calculate risk in points (distance from entry to stop loss)
      point_risk = ask_price - heikin_low[1];

      // Calculate take profit based on risk-to-reward ratio (RRR)
      take_profit = ((ask_price - heikin_low[1]) * RRR) + ask_price;

      // Determine lot size based on the dollar risk per trade
      lot_size = CalculateLotSize(_Symbol, dollar_risk, point_risk);

      // Execute a buy trade
      trade.Buy(lot_size, _Symbol, ask_price, heikin_low[1], take_profit);

      // Store the current bar time to prevent multiple trades in the same candle
      lastTradeBarTime = currentBarTime;
     }

// Check conditions for opening a sell position
// Ensures Heikin Ashi candle crosses below the moving average
// Limits trades per day and prevents multiple trades in the same candlestick
   if(heikin_open[1] > heikin_ma[1] && heikin_close[1] < heikin_ma[1] &&
      deal_type_sell < (daily_trades / 2) && total_deals_out < 1 &&
      totalPositions < 1 && currentBarTime != lastTradeBarTime)
     {
      // Calculate risk in points (distance from entry to stop loss)
      point_risk = heikin_high[1] - ask_price;

      // Calculate take profit based on risk-to-reward ratio (RRR)
      take_profit = MathAbs(((heikin_high[1] - ask_price) * RRR) - ask_price);

      // Determine lot size based on the dollar risk per trade
      lot_size = CalculateLotSize(_Symbol, dollar_risk, point_risk);

      // Execute a sell trade
      trade.Sell(lot_size, _Symbol, ask_price, heikin_high[1], take_profit);

      // Store the current bar time to prevent multiple trades in the same candle
      lastTradeBarTime = currentBarTime;
     }
  }

//+------------------------------------------------------------------+
//| Function to calculate the lot size based on risk amount and stop loss
//+------------------------------------------------------------------+
double CalculateLotSize(string symbol, double riskAmount, double stopLossPips)
  {
// Get symbol information
   double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
   double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);

// Calculate pip value per lot
   double pipValuePerLot = tickValue / point;

// Calculate the stop loss value in currency
   double stopLossValue = stopLossPips * pipValuePerLot;

// Calculate the lot size
   double lotSize = riskAmount / stopLossValue;

// Round the lot size to the nearest acceptable lot step
   double lotStep = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   lotSize = MathFloor(lotSize / lotStep) * lotStep;

   return lotSize;
  }

Explicação:

Para validar tendências, a lógica de execução de trades depende de velas Heikin Ashi cruzando uma Média Móvel (MA). Uma reversão bullish é indicada quando o preço de abertura está abaixo da MA e o fechamento está acima, e uma venda quando ocorre o oposto. O sistema limita trades diários, garante que não haja posições abertas e executa operações apenas em novas velas para evitar trading excessivo. Stop losses em máximas ou mínimas anteriores de Heikin Ashi, realização de lucro baseada em uma relação Risco-Retorno (RRR) e dimensionamento dinâmico de lote são todos componentes do gerenciamento de risco.

3.2.5. Usando Velas Heikin Ashi para Implementar um Trailing Stop

A implementação de um mecanismo de trailing stop usando velas Heikin Ashi é o principal objetivo desta seção. Ele garante que os níveis de stop-loss sejam ajustados dinamicamente em resposta a mudanças no preço Heikin Ashi.

Exemplo:

input bool    allow_trailing  = false; // Do you Allow Trailing Stop?

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   // Check if trailing stop is enabled
   if(allow_trailing == true)
     {
      // Variables to store trade-related information
      double positionProfit = 0;
      double positionopen = 0;
      double positionTP = 0;
      double positionSL = 0;

      // Loop through all open positions
      for(int i = 0; i < PositionsTotal(); i++)
        {
         // Get the ticket number of the position
         ulong ticket = PositionGetTicket(i);

         // Select the position using its ticket number
         if(PositionSelectByTicket(ticket))
           {
            // Check if the position belongs to the EA by verifying the magic number and symbol
            if(PositionGetInteger(POSITION_MAGIC) == MagicNumber && PositionGetString(POSITION_SYMBOL) == ChartSymbol(chart_id))
              {
               // Retrieve trade details: open price, take profit, profit, and stop loss
               positionopen = PositionGetDouble(POSITION_PRICE_OPEN);
               positionTP = PositionGetDouble(POSITION_TP);
               positionProfit = PositionGetDouble(POSITION_PROFIT);
               positionSL = PositionGetDouble(POSITION_SL);

               // Apply trailing stop logic for buy positions
               if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                 {
                  // Adjust stop loss if Heikin Ashi low is above the entry price and the candle is bullish
                  if(heikin_low[1] > positionopen && heikin_close[1] > heikin_open[1])
                    {
                     trade.PositionModify(ticket, heikin_low[1], positionTP);
                    }
                 }

               // Apply trailing stop logic for sell positions
               if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
                 {
                  // Adjust stop loss if Heikin Ashi high is below the entry price and the candle is bearish
                  if(heikin_high[1] < positionopen && heikin_close[1] < heikin_open[1])
                    {
                     trade.PositionModify(ticket, heikin_high[1], positionTP);
                    }
                 }
              }
           }
        }
     }
  }

Explicação:

Para proteger lucros e ajustar dinamicamente os níveis de stop-loss, esta seção usa velas Heikin Ashi para implementar um sistema de trailing stop. A variável de entrada allow_trailing controla se o recurso de trailing stop está habilitado; se estiver definida como true, o sistema percorre todas as posições abertas, recupera seus detalhes e verifica se pertencem ao EA verificando o número mágico e o símbolo. Para facilitar a lógica do trailing stop, informações essenciais do trade são extraídas, incluindo preço de abertura, take profit, lucro e stop loss.

Ao verificar que a mínima Heikin Ashi anterior é maior que o preço de entrada e que o fechamento Heikin Ashi é maior que sua abertura, o sistema valida posições abertas e confirma uma tendência bullish. Para proteger lucros enquanto permite maior movimento ascendente, o stop loss é definido na mínima Heikin Ashi quando essa condição é atendida. Garantindo que a máxima Heikin Ashi anterior esteja abaixo do preço de entrada e que o fechamento Heikin Ashi esteja abaixo da abertura, ele valida uma tendência de baixa para trades de venda. Para proteger o trade e capturar mais movimentos do mercado, o stop loss é definido na máxima Heikin Ashi quando essas condições são atendidas.


Conclusão

Neste artigo, construímos um indicador Heikin Ashi do zero, o integramos com uma Média Móvel que utiliza dados de velas Heikin Ashi e exploramos como incorporar um indicador personalizado em um EA, garantindo integração perfeita para trading automatizado. Implementamos técnicas de gerenciamento de risco, como limitar trades diários, impedir múltiplos trades fechados dentro da mesma vela e calcular dinamicamente os tamanhos de lote. Além disso, introduzimos um mecanismo de trailing stop usando velas Heikin Ashi para ajustar níveis de stop-loss. Esses conceitos fornecem uma base sólida para construir e aprimorar estratégias de trading automatizadas em MQL5.

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

Últimos Comentários | Ir para discussão (2)
dhermanus
dhermanus | 31 mai. 2025 em 11:08

Oi Isreal,

Obrigado pelo blog, pelo tempo e pelo esforço.


Gostaria de perguntar sobre o código do indicador personalizado Heikin Ashi.

Sobre a fórmula do Heikin Ashi Open:

// FÓRMULA DE ABERTURA DO HEIKIN ASHI
HA_Open[i] = (HA_Open[i - 1] + HA_Close[i - 1]) / 2.0;

Como você não calculou o HA_Open[i - 1]. Esse valor não seria 0?


Minha sugestão:


se (i == 1){

HA_Open[i] = (open[i - 1] + close[i - 1])/2.0; // Na primeira barra do HA, use apenas os dados normais de abertura/fechamento

}

else{

// FÓRMULA DE ABERTURA DO HEIKIN ASHI

HA_Open[i] = (HA_Open[i - 1] + HA_Close[i - 1]) / 2,0;


}

Israel Pelumi Abioye
Israel Pelumi Abioye | 31 mai. 2025 em 12:28
dhermanus do indicador personalizado Heikin Ashi.

Sobre a fórmula do Heikin Ashi Open:

// FÓRMULA DE ABERTURA DO HEIKIN ASHI
HA_Open[i] = (HA_Open[i - 1] + HA_Close[i - 1]) / 2.0;

Como você não calculou o HA_Open[i - 1]. Esse valor não seria 0?


Minha sugestão:


se (i == 1){

HA_Open[i] = (open[i - 1] + close[i - 1])/2.0; // Na primeira barra do HA, use apenas os dados normais de abertura/fechamento

}

else{

// FÓRMULA DE ABERTURA DO HEIKIN ASHI

HA_Open[i] = (HA_Open[i - 1] + HA_Close[i - 1]) / 2.0;


}

Obrigado. Vou dar uma olhada nisso
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.
Multiple Symbol Analysis With Python And MQL5 (Part 3): Taxas de Câmbio Triangulares Multiple Symbol Analysis With Python And MQL5 (Part 3): Taxas de Câmbio Triangulares
Traders frequentemente enfrentam drawdowns causados por sinais falsos, enquanto esperar por confirmação pode levar à perda de oportunidades. Este artigo apresenta uma estratégia de trading triangular utilizando a cotação da Prata em Dólares (XAGUSD) e em Euros (XAGEUR), juntamente com a taxa de câmbio EURUSD, para filtrar ruído. Ao aproveitar relações entre mercados, traders podem descobrir sentimento oculto do mercado e refinar suas entradas em tempo real.
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.
Explorando modelos de regressão para inferência causal e trading Explorando modelos de regressão para inferência causal e trading
Neste artigo, foi realizado um estudo sobre a possibilidade de aplicar modelos de regressão no trading algorítmico. Os modelos de regressão, diferentemente da classificação binária, permitem criar estratégias de trading mais flexíveis por meio da avaliação quantitativa das variações de preço previstas.