English Русский 中文 Español Deutsch 日本語
Características do Desenvolvimento de Indicadores Personalizados

Características do Desenvolvimento de Indicadores Personalizados

MetaTrader 4Exemplos | 13 abril 2016, 17:22
1 853 2
MetaQuotes
MetaQuotes
  • Para que um programa seja considerado como um indicador personalizado, deverá ter ao menos uma das duas definições abaixo:

    #property  indicator_chart_window      // um indicador é desenhado na janela do gráfico principal

    ou

    #property  indicator_separate_window   // um indicador é desenhada numa janela separada
  • Para definir a escala do indicador em janela separada, as seguintes definições são usadas:

    #property  indicator_minimum Min_Value
    #property  indicator_maximum Max_Value
    

    Onde "Min_Value" e "Max_Value" são valores correspondentes. Por exemplo, esses valores devem ser respectivamente 0 e 100 no indicador RSI personalizado.

  • O número de arrays necessários para desenhar um indicador deve ser definido da seguinte forma:

    #property  indicator_buffers N

    onde N pode assumir valores de 1 a 8.

  • A cor das linhas de um indicador é obtida através das seguintes definições:

    #property  indicator_color1  Silver
    #property  indicator_color2  Red
    ...
    #property  indicator_colorN  <SomeColor>
    

    onde N é o número de arrays de indicador definido por "#define indicator_buffer".

  • Existem funções que permitem o controle do processo de cálculo e visualização do indicador. Usamos aqui o Indicador Customizado Ichimoku Kinko Hyo para ilustrar:

    //+------------------------------------------------------------------+
    //|                                                     Ichimoku.mq4 |
    //|                      Copyright © 2004, MetaQuotes Software Corp. |
    //|                                       https://www.metaquotes.net/ |
    //+------------------------------------------------------------------+
    #property copyright "Copyright © 2004, MetaQuotes Software Corp."
    #property link      "https://www.metaquotes.net/"
     
    #property indicator_chart_window
    #property indicator_buffers 7
    #property indicator_color1 Red
    #property indicator_color2 Blue
    #property indicator_color3 SandyBrown
    #property indicator_color4 Thistle
    #property indicator_color5 Lime
    #property indicator_color6 SandyBrown
    #property indicator_color7 Thistle
    //---- parâmetros de entrada
    extern int Tenkan=9;
    extern int Kijun=26;
    extern int Senkou=52;
    //---- buffers do indicador 
    double Tenkan_Buffer[];
    double Kijun_Buffer[];
    double SpanA_Buffer[];
    double SpanB_Buffer[];
    double Chinkou_Buffer[];
    double SpanA2_Buffer[];
    double SpanB2_Buffer[];
    //---- o desenho começa em span_a
    int a_begin;
    //+------------------------------------------------------------------+
    //| Função de inicialização do indicador personalizado               |
    //+------------------------------------------------------------------+
    int init()
      {
    //----
       SetIndexStyle(0,DRAW_LINE);
       SetIndexBuffer(0,Tenkan_Buffer);
       SetIndexDrawBegin(0,Tenkan-1);
       SetIndexLabel(0,"Tenkan Sen");
    //----
       SetIndexStyle(1,DRAW_LINE);
       SetIndexBuffer(1,Kijun_Buffer);
       SetIndexDrawBegin(1,Kijun-1);
       SetIndexLabel(1,"Kijun Sen");
    //----
       a_begin=Kijun; if(a_begin&lt;Tenkan) a_begin=Tenkan;
       SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_DOT);
       SetIndexBuffer(2,SpanA_Buffer);
       SetIndexDrawBegin(2,Kijun+a_begin-1);
       SetIndexShift(2,Kijun);
       SetIndexLabel(2,NULL);
       SetIndexStyle(5,DRAW_LINE,STYLE_DOT);
       SetIndexBuffer(5,SpanA2_Buffer);
       SetIndexDrawBegin(5,Kijun+a_begin-1);
       SetIndexShift(5,Kijun);
       SetIndexLabel(5,"Senkou Span A");
    //----
       SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_DOT);
       SetIndexBuffer(3,SpanB_Buffer);
       SetIndexDrawBegin(3,Kijun+Senkou-1);
       SetIndexShift(3,Kijun);
       SetIndexLabel(3,NULL);
       SetIndexStyle(6,DRAW_LINE,STYLE_DOT);
       SetIndexBuffer(6,SpanB2_Buffer);
       SetIndexDrawBegin(6,Kijun+Senkou-1);
       SetIndexShift(6,Kijun);
       SetIndexLabel(6,"Senkou Span B");
    //----
       SetIndexStyle(4,DRAW_LINE);
       SetIndexBuffer(4,Chinkou_Buffer);
       SetIndexShift(4,-Kijun);
       SetIndexLabel(4,"Chinkou Span");
    //----
       return(0);
      }
    //+------------------------------------------------------------------+
    //| Ichimoku Kinko Hyo                                               |
    //+------------------------------------------------------------------+
    int start()
      {
       int    i,k;
       int    counted_bars=IndicatorCounted();
       double high,low,price;
    //----
       if(Bars&lt;=Tenkan || Bars&lt;=Kijun || Bars&lt;=Senkou) return(0);
    //---- inicial zero 
       if(counted_bars&lt;1)
         {
          for(i=1;i&lt;=Tenkan;i++)    Tenkan_Buffer[Bars-i]=0;
          for(i=1;i&lt;=Kijun;i++)     Kijun_Buffer[Bars-i]=0;
          for(i=1;i&lt;=a_begin;i++) { SpanA_Buffer[Bars-i]=0; SpanA2_Buffer[Bars-i]=0; }
          for(i=1;i&lt;=Senkou;i++)  { SpanB_Buffer[Bars-i]=0; SpanB2_Buffer[Bars-i]=0; }
         }
    //---- Tenkan Sen
       i=Bars-Tenkan;
       if(counted_bars>Tenkan) i=Bars-counted_bars-1;
       while(i>=0)
         {
          high=High[i]; low=Low[i]; k=i-1+Tenkan;
          while(k>=i)
            {
             price=High[k];
             if(high&lt;price) high=price;
             price=Low[k];
             if(low>price)  low=price;
             k--;
            }
          Tenkan_Buffer[i]=(high+low)/2;
          i--;
         }
    //---- Kijun Sen
       i=Bars-Kijun;
       if(counted_bars>Kijun) i=Bars-counted_bars-1;
       while(i>=0)
         {
          high=High[i]; low=Low[i]; k=i-1+Kijun;
          while(k>=i)
            {
             price=High[k];
             if(high<price) high=price;
             price=Low[k];
             if(low>price)  low=price;
             k--;
            }
          Kijun_Buffer[i]=(high+low)/2;
          i--;
         }
    //---- Senkou Span A
       i=Bars-a_begin+1;
       if(counted_bars>a_begin-1) i=Bars-counted_bars-1;
       while(i>=0)
         {
          price=(Kijun_Buffer[i]+Tenkan_Buffer[i])/2;
          SpanA_Buffer[i]=price;
          SpanA2_Buffer[i]=price;
          i--;
         }
    //---- Senkou Span B
       i=Bars-Senkou;
       if(counted_bars>Senkou) i=Bars-counted_bars-1;
       while(i>=0)
         {
          high=High[i]; low=Low[i]; k=i-1+Senkou;
          while(k>=i)
            {
             price=High[k];
             if(high&lt;price) high=price;
             price=Low[k];
             if(low>price)  low=price;
             k--;
            }
          price=(high+low)/2;
          SpanB_Buffer[i]=price;
          SpanB2_Buffer[i]=price;
          i--;
         }
    //---- Chinkou Span
       i=Bars-1;
       if(counted_bars>1) i=Bars-counted_bars-1;
       while(i>=0) { Chinkou_Buffer[i]=Close[i]; i--; }
    //----
       return(0);
      }
    //+------------------------------------------------------------------+
    
  • A função "SetIndexStyle" controla os parâmetros de desenho de um array de indicador. O modo de desenho DRAW_LINE assume que as linhas entre os valores definidos no array de indicador correspondente são desenhadas. O modo de desenho DRAW_HISTOGRAM aplicado ao indicador da janela principal possui suas características especiais também. Um histograma é desenhado entre valores correspondentes de dois arrays de índice: um que é par (aqui: SpanA_Buffer) e um que é impar (aqui: SpanB_Buffer). Onde, a cor do array de índice é usado no maior valor.

  • A função "SetIndexDrawBegin" especifica onde inicia os elementos de dados significativos do array de indicador.

  • A função "SetIndexBuffer" permite a declaração de qualquer array unidimensional do tipo "double" como um array de índice. Com isso, o sistema irá gerenciar os arrays de índice. É por esta razão que não é necessário especificar esses arrays.

    //---- buffers do indicador 
    double Tenkan_Buffer[];
    double Kijun_Buffer[];
    double SpanA_Buffer[];
    double SpanB_Buffer[];
    double Chinkou_Buffer[];
    double SpanA2_Buffer[];
    double SpanB2_Buffer[];
    

    A função ArrayResize não pode ser aplicada ao array de indicador, pois será inútil. Logo é inútil a aplicação da função ArrayInitialize nos arrays de indicador, especialmente uma função 'init', quando os arrays do indicador ainda não foram alocados. Arrays de indicador são inicializados automaticamente durante a alocação de memória e realocação. EMPTY_VALUE, ou o valor especificado pela função SetIndexEmptyValue, é usado como valor de inicialização. valores "vazios" não são exibidos.

  • A função "SetIndexLabel" define o nome exibido na dicas de ferramentas e na janela de dados, juntamente com o valor correspondente (o "ValueN" é definido por padrão, onde N é o número da arrays de índice). Se "NULL" é transferido em vez de um nome, o valor correspondente não será exibido nem nas dicas de ferramentas, nem na janela de dados. No exemplo dado, as nuvens são incubadas utilizando um histograma e limitadas por uma linha. Onde os valores da "linha" correspondente e arrays do "histograma" são os mesmos, sendo possível mostrar apenas um deles.

  • A função "IndicatorCounted" permite organizar um cálculo econômico de um indicador. Esta função retorna a quantidade de barras no momento do lançamento do indicador anteriormente, ou seja, a quantidade de barras já foi calculada(potencialmente, se não houver erros ou um encerramento antecipado durante o lançamento anterior)e não precisa de qualquer recálculo. Na reinicialização do indicador personalizado ou numa atualização significativa de dados do histórico, este montante será resetado automaticamente para 0.

  • Vamos discutir mais um exemplo. O indicador personalizado tipo oscilador chamado de Accelerator/Decelerator:

    //+------------------------------------------------------------------+
    //|                                                  Accelerator.mq4 |
    //|                      Copyright © 2005, MetaQuotes Software Corp. |
    //|                                       https://www.metaquotes.net/ |
    //+------------------------------------------------------------------+
    #property  copyright "Copyright © 2005, MetaQuotes Software Corp."
    #property  link      "https://www.metaquotes.net/"
    //---- Configurações do indicador
    #property  indicator_separate_window
    #property  indicator_buffers 3
    #property  indicator_color1  Black
    #property  indicator_color2  Green
    #property  indicator_color3  Red
    //---- buffers do indicador 
    double     ExtBuffer0[];
    double     ExtBuffer1[];
    double     ExtBuffer2[];
    double     ExtBuffer3[];
    double     ExtBuffer4[];
    //+------------------------------------------------------------------+
    //| Função de inicialização do indicador personalizado               |
    //+------------------------------------------------------------------+
    int init()
      {
    //---- 2 buffers adicionais são usados para contagem.
       IndicatorBuffers(5);
    //---- desenhando as configurações
       SetIndexStyle(0,DRAW_NONE);
       SetIndexStyle(1,DRAW_HISTOGRAM);
       SetIndexStyle(2,DRAW_HISTOGRAM);
       IndicatorDigits(Digits+2);
       SetIndexDrawBegin(0,38);
       SetIndexDrawBegin(1,38);
       SetIndexDrawBegin(2,38);
    //---- mapeamento de 4 buffers do indicador
       SetIndexBuffer(0,ExtBuffer0);
       SetIndexBuffer(1,ExtBuffer1);
       SetIndexBuffer(2,ExtBuffer2);
       SetIndexBuffer(3,ExtBuffer3);
       SetIndexBuffer(4,ExtBuffer4);
    //---- nome para as etiquetas DataWindow e indicador subwindow
       IndicatorShortName("AC");
       SetIndexLabel(1,NULL);
       SetIndexLabel(2,NULL);
    //---- inicialização feita
       return(0);
      }
    //+------------------------------------------------------------------+
    //| Oscilador Accelerator/Decelerator                                |
    //+------------------------------------------------------------------+
    int start()
      {
       int    limit;
       int    counted_bars=IndicatorCounted();
       double prev,current;
    //---- última barra contada será recontada
       if(counted_bars>0) counted_bars--;
       limit=Bars-counted_bars;
    //---- macd contados no primeiro buffer adicional
       for(int i=0; i&lt;limit; i++)
          ExtBuffer3[i]=iMA(NULL,0,5,0,MODE_SMA,PRICE_MEDIAN,i)-
                        iMA(NULL,0,34,0,MODE_SMA,PRICE_MEDIAN,i);
    //---- linha de sinal contado no segundo buffer adicional
       for(i=0; i<limit; i++)
          ExtBuffer4[i]=iMAOnArray(ExtBuffer3,Bars,5,0,MODE_SMA,i);
    //---- valores de despacho entre 2 buffers
       bool up=true;
       for(i=limit-1; i>=0; i--)
         {
          current=ExtBuffer3[i]-ExtBuffer4[i];
          prev=ExtBuffer3[i+1]-ExtBuffer4[i+1];
          if(current>prev) up=true;
          if(current&lt;prev) up=false;
          if(!up)
            {
             ExtBuffer2[i]=current;
             ExtBuffer1[i]=0.0;
            }
          else
            {
             ExtBuffer1[i]=current;
             ExtBuffer2[i]=0.0;
            }
           ExtBuffer0[i]=current;
         }
    //---- feito
       return(0);
      }
    //+------------------------------------------------------------------+
    
  • A função "IndicatorBuffers" especifica a quantidade de buffers a serem utilizados no cálculo do indicador. Geralmente, essa função é chamada se forem utilizados mais arrays de índice do que é necessário para desenhar um indicador. Com isso, o sistema gerencia os arrays adicionais.

  • A função "SetIndexDigits" gerencia a precisão da saída das informações. Neste caso, quando a diferença entre duas médias móveis é calculada, bem como uma maior diferença entre o resultado e a linha de sinal, obviamente é insuficiente a precisão padrão dentro dos 4 caracteres após o ponto.

  • A função "SetIndexDrawBegin" determina o elemento de partida significativo do array de indicador. No nosso exemplo, a linha de sinal é calculada como uma média móvel simples de uma outra média móvel simples. É por isso que os primeiros 38 valores do indicador são considerados vazios e não são desenhados.

  • A função "IndicatorShortName" define um nome abreviado do indicador a ser exibido no canto superior esquerdo da janela do indicador e na função "DataWindow". Se o nome abreviado não foi configurado, o nome do indicador personalizado será usado com o nome anterior. No exemplo dado, não há necessidade de usar a função SetIndexLabel, porque apenas um valor é de saída. Assim, o nome do indicador é o suficiente para a saída de um único valor.

  • A função "SetIndexStyle" gerencia os parâmetros de desenho do array de indicador. O modo de desenho DRAW_NONE significa que a linha não necessita ser desenhada. A questão é que histograma do indicador apresentado deve ser colorido com duas cores diferentes. Os dados do ExtBuffer0 são alocados em dois outros arrays: ExtBuffer1 e ExtBuffer2. A fim de não duplicar a saída de dados nas dicas de ferramentas ou na janela de dados, o parâmetro NULL da função SetIndexLabel é usado. O modo de desenho DRAW_HISTOGRAM, aplicado ao indicador de uma janela separada, permite desenhar o histograma entre o valor zero e o valor de um array correspondente (comparar com o desenho acima descrito de um histograma na janela principal).

  • Os parâmetros de entrada utilizados nos cálculos de indicadores e funções personalizadas devem ser definidos como "externos" e podem ser de qualquer tipo.

  • Se os parâmetros de entrada não foram definidos, o indicador personalizado correspondente será chamado na forma mais simples.

    double current_AC = iCustom( NULL, 0, "Accelerator", 0, 0 );

    A transferência dos dois primeiros valores "NULL" e "0" significa que o gráfico atual será utilizado. O nome do arquivo correspondente (sem extensão mq4) é usado como nome do indicador personalizado. Se o penúltimo parâmetro é 0, significa que estamos interessados nos dados do primeiro array de indicador. O último parâmetro sendo 0 significa que estamos interessados no valor do último elemento (isto é, o valor atual mais recente) do array de indicador solicitado.

  • Os parâmetros são transferidos na função de cálculo do indicador personalizado na ordem em que foram descritos. Por exemplo, o indicador personalizado com o nome "Ichimoku" e com parâmetros de (9,26,52) será chamado como se segue:

    iCustom( NULL, 0, "Ichimoku", 9, 26, 52, 0, shift );

    Estritamente falando, parâmetros do indicador personalizado não precisam necessariamente serem transferidos para a função. Se não houver uma variável externa definida no programa, será inútil transferir os parâmetros. Ou, se necessário, os valores iniciais podem ser utilizados na descrição dos parâmetros. Por exemplo, o mesmo indicador personalizado sem parâmetros será chamado da seguinte forma:

    iCustom( NULL, 0, "Ichimoku", 0, shift );

    Isto significa que os valores que inicializam as variáveis serão usados: "Tenkan", "Kijun", "Senkou", ou seja, 9, 26, e 52. No entanto, se um indicador personalizado com diferentes conjuntos de parâmetros é chamado num Expert Advisor, as configurações padrões são altamente recomendadas para NÃO serem usadas.

Observe que o excesso de indicadores personalizados, bem como os desenvolvidos incorretamente, pode acelerar significativamente o trabalho do terminal do cliente!

Aviso: Todos os direitos destes materiais são reservados à MetaQuotes Software Corp. A reprodução total ou parcial é terminantemente proibida.

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1497

Últimos Comentários | Ir para discussão (2)
Besourosuco
Besourosuco | 12 out 2016 em 16:40

estou com uma duvida , meu indicador esta dando o sinal de compra e venda, preciso passar esta informacao para o meu EA 

como faco para meu ea ler esta informação .

 

exemplo quando meu indicador aparecer a palavra put ou call eu tomar a decisão no EA.

um parametro simples string ou integer .

 

 

obrigado! 

Daniel Andrejczuk
Daniel Andrejczuk | 12 out 2016 em 19:29

Besourosuco, boa tarde!

Veja se alguns desses tópicos ajudam! 

https://www.mql5.com/pt/articles/1456 

https://www.mql5.com/pt/articles/1457

https://www.mql5.com/pt/forum/17530

https://www.mql5.com/pt/articles/48

 

Atenciosamente,

Daniel 

Testador de Estratégias: Modos de Modelagem Durante o Teste Testador de Estratégias: Modos de Modelagem Durante o Teste
Muitos programas de análise técnica permitem testar estratégias de negociação sobre os dados do histórico. Na maioria dos casos, o teste é realizado em dados já concluídos, sem qualquer tentativa de modelar as tendências dentro de uma barra de preço, pode ser feito rapidamente, mas não suficientemente preciso.
Características dos Experts Advisors Características dos Experts Advisors
O desenvolvimento de expert advisors no sistema de negociação MetaTrader tem uma série de características.
Características e Limites do Testador no MetaTrader 4 Características e Limites do Testador no MetaTrader 4
Este artigo permite um maior conhecimento sobre os recursos e os limites do Testador de Estratégia no MetaTrader 4.
Indicador Rope por Erik Naymanf Indicador Rope por Erik Naymanf
O artigo revela como o indicador "Rope" foi criado com base na "The Small Encyclopedia of Trader" (Pequena Enciclopédia do Trader), por Erik L. Nayman. Este indicador mostra a direção da tendência, usando cálculos dos valores das tendências de alta e de baixa durante um período de tempo determinado. O artigo também conta com os princípios do desenvolvimento e cálculos do indicador, bem como exemplos do código. Outros temas abordados incluem o desenvolvimento de um Expert Advisor com base no indicador, e também, a otimização dos parâmetros externos.