English Русский 中文 Español Deutsch 日本語
preview
Como criar um Canal Donchian personalizado usando o MQL5

Como criar um Canal Donchian personalizado usando o MQL5

MetaTrader 5Negociação | 3 outubro 2023, 09:49
410 1
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introdução

Neste artigo, discutiremos um conceito muito importante no trading, que é a identificação de tendências. Aprenderemos sobre uma ferramenta técnica que pode ser útil para isso, que é o Canal Donchian. Este indicador segue a tendência, como veremos.

Abordaremos todos esses tópicos nos seguintes pontos:


Atenção! Todo o conteúdo deste artigo é apresentado "tal qual como está", apenas para fins educacionais e não constitui uma recomendação de trading. O artigo não fornece qualquer garantia de resultados. Tudo o que você colocar em prática com base neste artigo, você faz exclusivamente por sua conta e risco, o autor não garante nenhum resultado.


Definição do Canal Donchian

Nesta parte, identificaremos o Canal Donchian e entenderemos o conceito principal por trás dele para utilizá-lo eficazmente. O Canal Donchian foi desenvolvido pelo trader Richard Donchian, e o objetivo principal é identificar a tendência, o que significa que ele é um indicador que segue a tendência e tem atraso, pois acompanha as direções da tendência e os movimentos de preço. Ele consiste em três linhas que formam um canal que envolve o preço. A linha superior do canal representa o preço mais alto registrado durante um período específico, a linha inferior do canal representa o preço mais baixo de um período específico e a linha do meio representa a metade da distância entre as linhas superior e inferior.

O gráfico a seguir é um exemplo do gráfico do Canal Donchian:

exemplo do indicador

Como podemos ver no gráfico anterior, há uma linha acima dos preços, outra abaixo e uma terceira entre elas. O que torna o indicador útil é que ele envolve ou cerca os preços com linhas superior e inferior, além de outra linha do meio que também pode ser útil. O indicador pode ser a base para diferentes estratégias na hora de buscar tendências, especialmente rupturas e linhas de suporte/resistência.

A objetivo principal deste indicador consiste em observar os pontos mais altos e mais baixos dos preços ao longo de um período específico para identificar tendências ou a direção para a qual podemos ter uma inclinação. Se o preço estiver acima do ponto mais alto de um período específico, isso indica que há uma pressão de compra e pode ser um sinal de compra. Se o preço estiver abaixo do ponto mais baixo de um período específico, isso indica que há uma pressão de venda e pode ser um sinal de venda. Portanto, uma vez que especificamos um período de tempo específico e determinamos os pontos mais altos e mais baixos, observaremos esses valores até que os preços se movam em uma direção específica para cima ou para baixo, e o sinal aqui é a quebra do ponto mais alto ou mais baixo determinado.

Este indicador pode ser usado com o objetivo de determinar os níveis de stop-loss e take-profit, Isso é muito importante no trading, pois ajuda a reduzir a probabilidade de erros na hora de definir níveis ao usar os parâmetros corretos. Portanto, por exemplo, a parte baixa do canal pode ser usada como um nível de stop-loss para uma posição de compra ou como um nível de take-profit para uma posição curta. Mas a parte alta do canal pode ser usada como um nível de stop-loss para uma posição curta ou como um take-profit para uma posição de compra.

Agora vejamos como calcular esse indicador:

  • Linha superior (CH)= Máxima mais alta dos últimos N períodos
  • Linha inferior (CL)= Mínima mais baixa dos últimos N períodos
  • Linha média (ML)= (CH+CL)/2

Bem, precisamos determinar o período de tempo desejado durante o qual precisamos detectar a direção, identificar o preço mais alto e o preço mais baixo, traçar uma linha ao lado deles para observação e obter a linha do meio calculando a distância média entre os níveis mais altos e mais baixos. É bom mencionar também que há uma diferença entre os Canais Donchian e as Bandas de Bollinger, pois os Canais Donchian traçam o preço mais alto e o preço mais baixo durante um período específico, como mencionamos, mas as Bandas de Bollinger traçam uma média ao longo de um período de tempo após a adição e subtração de dois desvios padrão. Se você precisar de mais informações, pode ler meu artigo anterior sobre as Bandas de Bollinger para aprender mais sobre elas e como criar um sistema de trading com base nelas.

É muito importante notar que será melhor se usarmos este indicador com outros indicadores técnicos relevantes para obter insights e resultados melhores.


Canal Donchian personalizado

Neste tópico, vou compartilhar um método que pode ser usado para criar um Canal Donchian personalizado usando o MQL5. Vamos criar o indicador na forma de uma linha superior, uma linha inferior e uma linha do meio, como podemos ver nos seguintes passos. 

Criamos parâmetros adicionais com os seguintes valores:

  • indicator_chart_window - exibição do indicador na janela do gráfico.
  • indicator_buffers - número de buffers de cálculo do indicador. O valor usado é (3).
  • indicator_plots - número de séries gráficas no indicador. O valor usado é (3).
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3

Criamos dois parâmetros de entrada: um para o período e outro para a cor das linhas do indicador, conforme mostrado abaixo:

  • Criamos uma variável inteira (indPeriod) e definimos 20 como o valor padrão. Você pode usar um valor diferente.
  • Criamos uma variável de cor (indColor) e definimos azul como o valor padrão. Você pode usar um valor diferente.
input int indPeriod=20; //Period
input color indColor=clrBlue; //Color

Criamos variáveis globais conforme mostrado abaixo:

  • arrays double - upperBuff, lowerBuff, middleBuff
  • arrays double - upperLine, lowerLine, middleLine
  • variáveis inteiras - start e bar
double upperBuff[];
double lowerBuff[];
double middleBuff[];
double upperLine,lowerLine,middleLine;
int start, bar;

Criamos uma função personalizada usando void para não retornar nada e fazemos uma variável indInit com três parâmetros (índice, buffer como um array dinâmico e etiqueta como uma string para cada linha do indicador). No corpo da função, faremos o seguinte:

  • Usamos a função SetIndexBuffer, que associa o indicador especificado a um array dinâmico unidimensional. Seus parâmetros são:
    • index - especifica o número do buffer do indicador. Usaremos a variável index.
    • buffer[] - define o array dinâmico criado buffer[].
    • data_type - define os valores padrão que precisamos armazenar (INDICATOR_DATA).
  • Usamos a função PlotIndexSetInteger cinco vezes com diferentes parâmetros prop-id e prop_value, como veremos no código. A função define o valor da linha do indicador correspondente. A propriedade do indicador deve ser um número inteiro. Parâmetros:
    • plot_index - define o índice do gráfico. Usaremos a variável de índice. Usaremos a variável index.
    • prop_id - define o valor do identificador da propriedade, que pode ser um dos ENUM_PLOT_PROPERT_INTEGER.
    • prop_value - define o valor da propriedade definida em prop_id.
  • Usamos a função PlotIndexSetString, que define o valor do indicador correspondente da propriedade string. Seus parâmetros são os mesmos da função PlotIndexSetInteger, mas a propriedade do indicador aqui deve ser um string.
  • Usamos a função PlotIndexSetDouble para definir o valor do indicador correspondente da propriedade double. Os parâmetros são os mesmos, mas a propriedade do indicador deve ser do tipo double.
void indInit(int index, double &buffer[],string label)
  {
   SetIndexBuffer(index,buffer,INDICATOR_DATA);
   PlotIndexSetInteger(index,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(index,PLOT_LINE_WIDTH,2);
   PlotIndexSetInteger(index,PLOT_DRAW_BEGIN,indPeriod-1);
   PlotIndexSetInteger(index,PLOT_SHIFT,1);
   PlotIndexSetInteger(index,PLOT_LINE_COLOR,indColor);
   PlotIndexSetString(index,PLOT_LABEL,label);
   PlotIndexSetDouble(index,PLOT_EMPTY_VALUE,EMPTY_VALUE);
  }

Após isso, no corpo do OnInit(), usaremos nossa função personalizada do indicador três vezes para as três linhas do indicador, e será igual ao seguinte:

   indInit(0,upperBuff,"Donchian Channel");
   indInit(1,lowerBuff,"Donchian Channel");
   indInit(2,middleBuff,"Middle Donchian");

Usamos a função IndicatorSetString aqui para definir o rótulo de texto do indicador.

IndicatorSetString(INDICATOR_SHORTNAME,"Donchian ("+IntegerToString(indPeriod)+")");

Na parte OnCalculate, faremos as seguintes etapas para calcular o indicador:

Verificamos se rates_total é menor que o período inserido pelo usuário +1; se for, o programa deve retornar zero.

   if(rates_total<indPeriod+1)
     {
      return 0;
     }

Atribuimos um valor para a variável de início usando o operador ternário ?: - se start=prev_calculated==0 for verdadeiro, o operador será definido pelo indPeriod e, se for falso, o operador será definido por prev_calculated-1.

start=prev_calculated==0? indPeriod: prev_calculated-1;

Usamos a função for para criar um laço para calcular o indicador, a expressão 1 será (bar=start), a expressão 2 será (bar < rates_total) e a expressão 3 será (bar ++) para incrementar o bar em um. O operador do laço for será o mesmo que o seguinte:

  • Cálculo de upperLine mediante a determinação do valor máximo high usando a função ArrayMaximum, que procura o maior valor no array.
  • Cálculo de lowerLine mediante a determinação do valor mínimo low usando a função ArrayMinimum, que procura o menor valor no array.
  • Cálculo de middleLine mediante a divisão da soma de upperLine e lowerLine por 2.
  • Atribuição de valores a upperBuff[bar], lowerBuff[bar] e middleBuff[bar}
   for(bar=start;bar<rates_total;bar++)
   {
      upperLine=high[ArrayMaximum(high,bar-indPeriod+1,indPeriod)];
      lowerLine=low[ArrayMinimum(low,bar-indPeriod+1,indPeriod)];
      middleLine=(upperLine+lowerLine)/2;
      
      upperBuff[bar]=upperLine-(upperLine-lowerLine);
      lowerBuff[bar]=lowerLine+(upperLine-lowerLine);
      middleBuff[bar]=middleLine;

   }

A seguir está o código completo em um bloco:

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
input int indPeriod=20; //Period
input color indColor=clrBlue; //Color
double upperBuff[];
double lowerBuff[];
double middleBuff[];
double upperLine,lowerLine,middleLine;
int start, bar;
void indInit(int index, double &buffer[],string label)
  {
   SetIndexBuffer(index,buffer,INDICATOR_DATA);
   PlotIndexSetInteger(index,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(index,PLOT_LINE_WIDTH,2);
   PlotIndexSetInteger(index,PLOT_DRAW_BEGIN,indPeriod-1);
   PlotIndexSetInteger(index,PLOT_SHIFT,1);
   PlotIndexSetInteger(index,PLOT_LINE_COLOR,indColor);
   PlotIndexSetString(index,PLOT_LABEL,label);
   PlotIndexSetDouble(index,PLOT_EMPTY_VALUE,EMPTY_VALUE);
  }
int OnInit()
  {
   indInit(0,upperBuff,"Donchian Channel");
   indInit(1,lowerBuff,"Donchian Channel");
   indInit(2,middleBuff,"Middle Donchian");
   IndicatorSetString(INDICATOR_SHORTNAME,"Donchian ("+IntegerToString(indPeriod)+")");

   return(INIT_SUCCEEDED);
  }
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(rates_total<indPeriod+1)
     {
      return 0;
     }
   start=prev_calculated==0? indPeriod: prev_calculated-1;
   for(bar=start;bar<rates_total;bar++)
   {
      upperLine=high[ArrayMaximum(high,bar-indPeriod+1,indPeriod)];
      lowerLine=low[ArrayMinimum(low,bar-indPeriod+1,indPeriod)];
      middleLine=(upperLine+lowerLine)/2;
      
      upperBuff[bar]=upperLine-(upperLine-lowerLine);
      lowerBuff[bar]=lowerLine+(upperLine-lowerLine);
      middleBuff[bar]=middleLine;
   }
   return(rates_total);
  }

O código deve ser compilado sem erros ou avisos. Em seguida, encontraremos o indicador na janela Navegador no terminal de negociação na pasta Indicador e, ao executá-lo, podemos encontrar a janela e inserir o mesmo conforme o seguinte:

parâmetros de entrada do indicador

Como podemos ver na figura anterior, temos duas entradas:

  • Period - define a duração usada no cálculo do indicador. O valor padrão é 20.
  • Color - define a cor das linhas do indicador. O valor padrão é azul.

Depois de definir os parâmetros e pressionar OK, o indicador é anexado ao gráfico:

indicador associado

Como você pode ver, tudo parece estar certo.


Expert Advisor Donchian Channel

Nesta parte, precisamos usar este Canal Donchian personalizado em um sistema de negociação, para isso criaremos um EA que pode ser usado para gerar sinais com base no movimento ou comportamento do indicador. Podemos fazer isso usando dois métodos diferentes: o primeiro é escrever o código do indicador no EA ou o segundo método é usar a função iCustom para anexar o indicador criado ao EA. Aqui, projetaremos sistemas muito simples apenas para entender o conceito e como podemos aprimorar esses sistemas com base no segundo método, conforme aprendemos como criar o Expert Advisor.

Expert Advisorv Donchian Channel Simple

Vamos começar a criar o primeiro sistema que pode ser usado para retornar um comentário no gráfico com os valores do indicador (Channel High, Channel Middle e Channel Low). Portanto, precisamos que o programa verifique e monitore continuamente esses valores e os imprima no gráfico como um comentário.

Os seguintes são os passos para criar esse tipo de EA:

Criamos uma variável de entrada do período do indicador com um valor padrão (20), mas o usuário pode atualizá-lo nas entradas do EA. 

input int indPeriod=20; //Period

Criamos uma variável global inteira chamada donChianChannel.

int donchianChannel;

Na parte OnInit(), atualizaremos o donchianChannel atribuindo a ele a função iCustom, que retorna o identificador do Canal Donchian personalizado criado. Seus parâmetros são:

  • symbol — nome do símbolo; no nosso caso, é _Symbol, ou seja, calculamos o indicador pelo símbolo do gráfico atual.
  • period — período gráfico para cálculo; o valor _period significa que o indicador será calculado no período gráfico atual.
  • name — especifica o nome de string do indicador e o caminho para ele.
  • Depois disso, especificaremos os dados de entrada do indicador, ou seja, seu período.
donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod);

Na parte OnDeinit(), usaremos a função Print para retornar uma mensagem no expert advisor com "Donchian Channel EA Removed" ao remover o EA.

Print("Donchian Channel EA Removed");

Na parte OnTick(), criaremos três arrays de channelBuff, channelBuff1, middleBuff.

double channelBuff[],channelBuff1[], middleBuff[];

Usaremos a função CopyBuffer para obter os dados de cada buffer do Canal Donchian personalizado. Seus parâmetros são:

  • indicator_handle - especifica o identificador do indicador, usaremos o identificador do donchianChannel criado para todos os três buffers.
  • buffer_num - número do buffer: 0 - channelBuff, 1 - channelBuff1 e 2 - middleBuff.
  • start_pos - posição do primeiro elemento a ser copiado. Usamos 0 para todos os três buffers.
  • count - quantidade de dados a serem copiados. Usamos 3 para todos os três buffers.
  • buffer[] - especifica o array destino a ser copiado, especificaremos três buffers (channelBuff, channelBuff1 e middleBuff).
   CopyBuffer(donchianChannel,0,0,3,channelBuff);
   CopyBuffer(donchianChannel,1,0,3,channelBuff1);
   CopyBuffer(donchianChannel,2,0,3,middleBuff);

Definimos os valores atuais de cada linha após criar uma variável do tipo double para cada uma.

   double channelHigh=channelBuff1[0];
   double channelMiddle=middleBuff[0];
   double channelLow=channelBuff[0];

Usaremos a função Comment para retornar um comentário no gráfico com três valores, cada um em uma linha separada.

Comment("Channel High: ",channelHigh,"\nChannel Middle: ",channelMiddle,"\nChannel Low: ",channelLow);

A seguir está o código completo em um bloco:

input int indPeriod=20; //Period
int donchianChannel;
int OnInit()
  {
   donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("Donchian Channel EA Removed");
  }
void OnTick()
  {
   double channelBuff[],channelBuff1[], middleBuff[];
   CopyBuffer(donchianChannel,0,0,3,channelBuff);
   CopyBuffer(donchianChannel,1,0,3,channelBuff1);
   CopyBuffer(donchianChannel,2,0,3,middleBuff);
   double channelHigh=channelBuff1[0];
   double channelMiddle=middleBuff[0];
   double channelLow=channelBuff[0];
   Comment("Channel High: ",channelHigh,"\nChannel Middle: ",channelMiddle,"\nChannel Low: ",channelLow);
  }

Após compilar este código sem erros ou avisos, podemos encontrá-lo na janela Navigator na pasta de Expert Advisor. Ao executá-lo no gráfico desejado, podemos encontrar a janela de entradas da seguinte forma:

janela de parâmetros de entrada dcSimpleEA

Após a execução, podemos encontrar o EA anexado ao gráfico, além dos níveis do indicador do Canal Donchian como um comentário, conforme o seguinte:

EA dcSimpleEA iniciado e sinal

Como podemos ver, temos o sinal desejado no gráfico, que é o comentário com três valores do indicador (Channel High, Channel Middle e Channel Low). Cada valor está em uma linha separada.

Para confirmar, podemos comparar os valores dos sinais do EA com os valores do indicador; podemos encontrar a seguinte imagem para verificar se o indicador está inserido e se os valores na janela de dados são iguais aos valores dos sinais do EA, como na imagem a seguir:

sinal dcSimpleEA coincide com os valores do indicador


Se quisermos aprimorar este EA para encontrar sinais com base nos movimentos e níveis do indicador, é isso que tentaremos fazer por meio dos seguintes sistemas de negociação (EAs), ao definir condições com base no conceito do indicador para receber sinais de compra e venda.

Expert Advisor Donchian Channel Breakout:

Nesta versão do EA, precisamos que o programa verifique continuamente todos os três valores dos indicadores e, se o preço (ask) romper o nível mais alto do canal, precisamos receber um sinal de compra como um comentário no gráfico. No outro cenário, se o preço (bid) romper o nível mais baixo do canal, também precisamos receber um sinal de venda como um comentário no gráfico. Se algo diferente acontecer, não precisamos receber nenhum sinal.

A seguir está o código completo para criar esse tipo de sistema de negociação (EA):

input int indPeriod=20; //Period
int donchianChannel;
int OnInit()
  {
   donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("Donchian Channel EA Removed");
  }
void OnTick()
  {
   double channelBuff[],channelBuff1[], middleBuff[];
   CopyBuffer(donchianChannel,0,0,3,channelBuff);
   CopyBuffer(donchianChannel,1,0,3,channelBuff1);
   CopyBuffer(donchianChannel,2,0,3,middleBuff);
   double channelHigh=channelBuff1[0];
   double channelMiddle=middleBuff[0];
   double channelLow=channelBuff[0];
   double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   if(ask>channelHigh)
     {
      Comment("Buy Signal");
     }
     else if(bid<channelLow)
     {
      Comment("Sell Signal");
     }
     else Comment(" ");
  }

As diferenças neste código são as seguintes:

Definição de ask e bid usando a função SymbolInfoDouble para retornar os valores da propriedade (ask, bid) após criar variáveis do tipo double para eles.

   double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);

Condições da estratégia:

No caso de compra

Precisamos que o programa verifique o ask e o nível mais alto do canal para determinar suas posições. Se o ask for maior que o nível mais alto do canal, esta será a condição de compra e precisamos que o EA retorne um sinal de compra como um comentário no gráfico assim que essa condição for atendida.

   if(ask>channelHigh)
     {
      Comment("Buy Signal");
     }

No caso de venda

Precisamos que o programa verifique o bid e o nível mais baixo do canal para determinar suas posições. Se o preço de venda for inferior ao nível mais baixo do canal, esta será a condição de venda e precisamos que o EA retorne um sinal de venda como um comentário no gráfico assim que essa condição for atendida.

     else if(bid<channelLow)
     {
      Comment("Sell Signal");
     }

No caso de nada

Precisamos que o EA retorne nada se algo diferente das condições de compra ou venda ocorrer.

else Comment(" ");

Após compilar este código sem erros ou avisos, podemos executá-lo no gráfico arrastando e soltando-o no gráfico desejado para obter sinais com base na estratégia, como nos exemplos a seguir:

No caso de um sinal de compra

sinal de compra dcBreakout

Como podemos ver no canto superior esquerdo do gráfico anterior, temos um sinal de compra após a quebra do nível mais alto do canal para cima.

No caso de um sinal de venda

sinal de venda dcBreakout

Como podemos ver no canto superior esquerdo do gráfico anterior, temos um sinal de venda após a quebra do nível mais baixo do canal para baixo.

No caso de nada

ausência de sinal dcBreakout

Como podemos ver, não há sinal, já que o preço se move dentro do canal, o que significa que o preço está abaixo do nível mais alto do canal e acima do nível mais baixo do canal.

Canal Donchian e Rompimento da Média Móvel:

Agora, precisamos melhorar o EA um pouco ao filtrar os sinais adicionando a média móvel às condições da estratégia, e é isso que faremos neste sistema de negociação. Portanto, precisamos receber um sinal de compra quando o preço (ask) rompe acima do nível mais alto do canal, desde que a EMA (Média Móvel Exponencial) de 200 períodos esteja abaixo do ask. No caso de um sinal de venda, precisamos ter certeza de que o preço de venda (bid) rompe abaixo do nível mais baixo do canal e, ao mesmo tempo, a EMA de 200 períodos está acima do bid. Em caso de qualquer outra coisa, precisamos receber nada.

A seguir está o código completo para criar esse tipo de sistema de negociação:

input int indPeriod=20; //Period
input int maPeriod=200; //Moving Average Period
int donchianChannel;
int EMA;
double emaArray[];
int OnInit()
  {
   donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod);
   EMA = iMA(_Symbol,_Period,maPeriod,0,MODE_EMA,PRICE_CLOSE);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("Donchian Channel EA Removed");
  }
void OnTick()
  {
   double channelBuff[],channelBuff1[], middleBuff[];
   CopyBuffer(donchianChannel,0,0,3,channelBuff);
   CopyBuffer(donchianChannel,1,0,3,channelBuff1);
   CopyBuffer(donchianChannel,2,0,3,middleBuff);
   ArraySetAsSeries(emaArray,true);
   CopyBuffer(EMA,0,0,3,emaArray);
   double channelHigh=channelBuff1[0];
   double channelMiddle=middleBuff[0];
   double channelLow=channelBuff[0];
   double EMAValue=NormalizeDouble(emaArray[0],_Digits);
   double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   if(ask>channelHigh&&ask>EMAValue)
     {
      Comment("Buy Signal","\nAsk above Channel High","\nAsk above (",maPeriod,") EMA");
     }
     else if(bid<channelLow&&bid<EMAValue)
     {
      Comment("Sell Signal","\nBid below Channel Low","\nBid Below (",maPeriod,") EMA");
     }
     else Comment(" ");
  }

As diferenças neste código são as seguintes:

Criamos outra entrada de variável inteira chamada maPeriod com um valor padrão de (200), mas o usuário pode atualizá-la conforme suas preferências.

input int maPeriod=200; //Moving Average Period

Criamos uma variável global inteira chamada EMA.

int EMA;

Criamos um array de emaArray[].

double emaArray[];

Atualizamos a variável EMA usando a função iMA para retornar o identificador do indicador de média móvel e seus parâmetros são:

  • symbol — nome do símbolo; no nosso caso, é _Symbol, ou seja, calculamos o indicador pelo símbolo do gráfico atual.
  • period — período gráfico para cálculo; o valor _period significa que o indicador será calculado no período gráfico atual.
  • ma_period — período de cálculo da média, usaremos um parâmetro de entrada personalizado (maPeriod).
  • ma_shift — especificamos (0), pois não é necessário nenhum deslocamento.
  • ma_method — tipo de média móvel, usaremos (MODE_EMA) porque precisamos de uma média móvel exponencial.
  • applied_price — tipo de preço; usamos (PRICE_CLOSE).
EMA = iMA(_Symbol,_Period,maPeriod,0,MODE_EMA,PRICE_CLOSE);

Usamos a função ArraySetAsSeries para definir AS_SERIES, seus parâmetros são:

  • array[] - usamos emaArray para especificar o array.
  • flag - direção de indexação no array, true.
ArraySetAsSeries(emaArray,true);

Usamos a função CopyBuffer para obter dados do buffer da média móvel.

CopyBuffer(EMA,0,0,3,emaArray);

Definimos o valor da EMA e o normalizamos.

double EMAValue=NormalizeDouble(emaArray[0],_Digits);

Condições da estratégia:

No caso de compra

Se o preço > alto do canal, precisamos do seguinte comentário no gráfico.

  • Sinal de compra
  • Ask acima do alto do canal
  • Ask acima do período de EMA
   if(ask>channelHigh&&ask>EMAValue)
     {
      Comment("Buy Signal","\nAsk above Channel High","\nAsk above (",maPeriod,") EMA");
     }

No caso de venda

Se o preço < baixo do canal, precisamos do seguinte comentário no gráfico.

  • Sinal de venda
  • Bid abaixo do baixo do sinal
  • Bid abaixo do período de EMA
     else if(bid<channelLow&&bid<EMAValue)
     {
      Comment("Sell Signal","\nBid below Channel Low","\nBid Below (",maPeriod,") EMA");
     }

Em caso de ausência de sinal

else Comment(" ");

Após compilar este código sem erros ou avisos, podemos encontrar sinais deste sistema de negociação da seguinte forma:

No caso de um sinal de compra

sinal de compra dc & EMABreakout

Como podemos ver no exemplo anterior, temos o sinal de compra e as condições desse sinal, ou seja, o preço está acima do nível mais alto do canal e a EMA de 200 períodos está de acordo com o que precisamos, comentado no gráfico.

No caso de um sinal de venda

sinal de venda dc & EMABreakout

Como podemos ver no exemplo anterior, temos o sinal de venda e as condições desse sinal, ou seja, o preço está abaixo do nível mais baixo do canal e a EMA de 200 períodos está de acordo com o que precisamos, comentado no gráfico.

Em caso de ausência de sinal

ausência de sinal dc & EMABreakout

Ausência de sinal. Como podemos ver, não há sinal no gráfico indicando que as condições não estão sendo atendidas, pois o preço está acima do nível mais baixo do canal e abaixo do nível mais alto do canal, mesmo que tenhamos uma configuração de venda, pois o preço está abaixo da EMA de 200 períodos.


Considerações finais

Neste artigo, vimos que o canal Donchian pode ser uma ferramenta útil e valiosa, especialmente com versões personalizadas e como parte de sistemas de negociação. Você poderá criar seus próprios Canais Donchian de acordo com suas preferências. Além disso, você conseguirá criar um sistema de negociação usando o recurso iCustom para negociar ou obter sinais com base no indicador. Se quiser, você pode aprimorar o sistema de negociação (EA) adicionando determinadas condições e usando outras ferramentas técnicas.

Espero que este artigo seja útil para você e o ajude a melhorar seus resultados de negociação. Não aplique o conteúdo deste artigo sem testar adequadamente. Não existe uma ferramenta que seja adequada para todos os traders.  

Os links abaixo o levarão a meus outros artigos. Em particular, você pode encontrar uma série de artigos sobre a criação de sistemas de negociação com base nos indicadores técnicos mais populares. Espero que você os considere úteis.

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

Arquivos anexados |
dcSimpleEA.mq5 (0.74 KB)
dcBreakout.mq5 (0.91 KB)
Redes neurais de maneira fácil (Parte 45): Ensinando habilidades para investigar estados Redes neurais de maneira fácil (Parte 45): Ensinando habilidades para investigar estados
Aprender habilidades úteis sem uma função de recompensa explícita é um dos principais desafios do aprendizado por reforço hierárquico. Anteriormente, já nos familiarizamos com dois algoritmos para resolver esse problema. Mas a questão da completa exploração do ambiente ainda está em aberto. Neste artigo, é apresentada uma abordagem diferente para o treinamento de habilidades, cujo uso depende diretamente do estado atual do sistema.
Redes neurais de maneira fácil (Parte 44): Explorando habilidades de forma dinâmica Redes neurais de maneira fácil (Parte 44): Explorando habilidades de forma dinâmica
No artigo anterior, apresentamos o método DIAYN, que oferece um algoritmo para aprender uma variedade de habilidades. O uso das habilidades adquiridas pode ser usado para diversas tarefas. Mas essas habilidades podem ser bastante imprevisíveis, o que pode dificultar seu uso. Neste artigo, veremos um algoritmo para ensinar habilidades previsíveis.
Avaliando modelos ONNX usando métricas de regressão Avaliando modelos ONNX usando métricas de regressão
A regressão é uma tarefa de prever um valor real a partir de um exemplo não rotulado. Para avaliar a precisão das previsões de modelos de regressão, são utilizadas as chamadas métricas de regressão.
Domine e utilize o testador de estratégias MQL5 de forma eficiente Domine e utilize o testador de estratégias MQL5 de forma eficiente
Os desenvolvedores MQL5 devem dominar diversas ferramentas essenciais. Entre elas, destaca-se o testador de estratégias. Este artigo serve como um guia prático para a utilização do testador de estratégias MQL5.