Criando um indicador com opções de controle gráfico

31 dezembro 2013, 11:26
Vasily
0
1 587

Introdução

Aqueles que são familiares com os sentimentos do mercado, conhecem o indicador MACD (seu nome completo é convergência/divergência de média móvel), como uma poderosa ferramenta para análise de movimento de preço que é usada por negociantes desde os primeiros momentos do aparecimento dos métodos de análise computacionais.

Por um longo tempo estudei o indicador MACD que ganhou espaço no gráfico. Tenho visto muitos tipos diferentes deste indicador, com diferentes opções e diferentes algoritmos de cálculo, então decidi combinar todos os tipos que conheço em um indicador.

Tipos de indicadores MACD

O indicador terá linhas MACD convencionais e histograma oSMA. Vamos definir as principais modificações do MACD:
  1. O MACD Elder, também conhecido como Sistema de Impulso;
  2. MACD Elder sem verificação pela linha de movimento;
  3. O oSMA, organizado com diferentes cores para casos de crescimento e queda;
  4. Apenas o histograma oSMA é traçado;
  5. Apenas as linhas MACD são traçadas.

Configurações iniciais do indicador

Precisaremos dos seguintes parâmetros para o cálculo:

  1. O valor de uma linha MACD rápida;
  2. O valor de uma linha MACD lento;
  3. O valor de uma linha MACD de sinal;
  4. O valor da linha de verificação de tendência pelo método Elder;

Para organizar este indicador, precisaremos do seguinte:

  1. A linha MACD;
  2. A linha de sinal;
  3. O histograma OSMA de 3 cores.

Vá até o menu do Assistente MQL5:

Figura 1. Criação do indicador usando o Assistente MQL5


Figura 2. Definição dos parâmetros do indicador comum no Assistente MQL5


Figura 3. Definição das propriedades de desenho do indicador no Assistente MQL5

Criação de indicador

Temos um template inicial do indicador. Primeiro, precisamos calcular a linha MACD de nossos indicador.

Não entraremos a fundo na fórmula exata para o cálculo desta linha - usaremos a função iMACD:

int iMACD (
   string symbol,           // symbol name
   ENUM_TIMEFRAMES period,   // time period
   int fast_ema_period,    // fast averaging period
   int slow_ema_period,    // slow averaging period
   int signal_period,      // averaging period of a signal line
   ENUM_APPLIED_PRICE applied_price // type of price or a handle
   )

Esta função retorna um manipulador da cópia apropriada do indicador. Usando este manipulador, é possível obter os dados, calculados por este indicador. Os dados de um buffer de indicador (indicadores técnicos contêm os dados calculados em seus próprios buffers internos, que podem ser até 5, dependendo do indicador), pode ser copiado usando a função CopyBuffer().

Assim, geraremos uma requisição para dados MACD, usando a função iMACD:

int MACDhadling =  iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);

Ela retornará o manipulador da cópia do indicador.

Copie os dados para o buffer necessário por meio da função CopyBuffer:

int  CopyBuffer(
   int       indicator_handle,     // indicator's handle
   int       buffer_num,           // buffer number of the indicator
   int       start_pos,            // start position 
   int       count,                // number of data to copy
   double    buffer[]              // target array for the data to copy
   );

Agora vamos solicitar a linha MACD do indicador:

CopyBuffer(MACDhadling,0,0,NewData,MACDlineBuffer);

Obtemos a linha de sinal do indicador:

CopyBuffer(MACDhadling,1,0,NewData,SignallineBuffer);

Vamos coletar tudo e ver o que temos:

int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

Agora temos linhas de sinal e MACD calculado.

Vamos continuar.

Por causa do fato de os dados dos

MACDlineBuffer

e

SignallineBuffer

buffers terem sido obtidos por meio de cópia, sua indexação é a partir do final do gráfico.

Historicamente, um acesso aos dados do array de preço é realizado a partir do final dos dados. Fisicamente, os novos dados são sempre escritos no final do array, mas o índice da barra atual (incompleta) sempre é igual a zero. O índice igual a 0 no array de séries de tempo significa os dados da barra atual, que correspondem ao intervalo de tempo incompleto deste período.

Para utilizar a mesma direção de indexação em todos os buffers, devemos definir os outros buffers como séries de tempo.

ArraySetAsSeries(HistogramBuffer,false);
ArraySetAsSeries(HistogramColors,false);

Precisamos obter os dados de um histograma, que é calculado usando a subtração da linha de sinal da linha MACD:

for(int i=0;i<rates_total;i++) {="" histogrambuffer[i]="MACDlineBuffer[i]-SignallineBuffer[i];" }

Vamos combinar todos:

ArraySetAsSeries(HistogramBuffer,false);
ArraySetAsSeries(HistogramColors,false);

int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

for(int i=0;i<rates_total;i++) {="" histogrambuffer[i]="MACDlineBuffer[i]-SignallineBuffer[i];" histogramcolors[i]="1; 
  }

Criando um sistema gráfico de controle do indicador

Possuímos 5 variedades deste indicador.

Primeiro, implementamos os itens 3 e 4.

3. Apenas o histograma oSMA é traçado; 4. Apenas as linhas MACD são traçadas;

Vamos criar os botões apropriados.

Para o item 4:

ObjectCreate(0,"ShowMACD",OBJ_BUTTON,ChartWindowFind(),100,100);   //creating the button
ObjectSetInteger(0,"ShowMACD",OBJPROP_XDISTANCE,75);              //assign the coordinates
ObjectSetInteger(0,"ShowMACD",OBJPROP_YDISTANCE,5);
ObjectSetInteger(0,"ShowMACD",OBJPROP_CORNER,CORNER_RIGHT_UPPER);  // and an anchor point
ObjectSetString(0,"ShowMACD",OBJPROP_TEXT,"ShowMACD");            // button label 
ObjectSetInteger(0,"ShowMACD",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"ShowMACD",OBJPROP_XSIZE,70);                 // size of buttons 
ObjectSetInteger(0,"ShowMACD",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"ShowMACD",OBJPROP_SELECTABLE,false);         // to make it selectable

No caso da exclusão acidental do botão ou seu deslocamento na próxima marcação, o botão retornará.

Para o item 3:

ObjectCreate(0,"ShowOsMA",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_YDISTANCE,30);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetString (0,"ShowOsMA",OBJPROP_TEXT,"Show OsMA");
ObjectSetInteger(0,"ShowOsMA",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"ShowOsMA",OBJPROP_SELECTABLE,false);

Vamos criar a implementação para o caso de botão apertado e não apertado para a condição 4.

Isto requer a visão dos índices do buffer.

SetIndexBuffer(0,MACDlineBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignallineBuffer,INDICATOR_DATA);
SetIndexBuffer(2,HistogramBuffer,INDICATOR_DATA);
SetIndexBuffer(3,HistogramColors,INDICATOR_COLOR_INDEX);
if(ObjectGetInteger(0,"ShowMACD",OBJPROP_STATE)!=1)
  {
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE); // the buffer with index 0 isn't plotted
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE); // the buffer with index 1 isn't plotted
  }
else
  {
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); // the buffer with index 0 is plotted as line
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE); // the buffer with index 1 is plotted as line
  }

As linhas MACD são traçadas se o botão é pressionado, e não são traçadas se não for.

Vamos criar a implementação para o caso de botão apertado e não apertado para a condição 3.

if(ObjectGetInteger(0,"ShowOsMA",OBJPROP_STATE)!=1)
  {
   //the buffer with index 2 isn't plotted
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);
  }
else
  {
   //the buffer with index 2 is plotted as a color histogram
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_COLOR_HISTOGRAM);
  }

Vamos criar dois botões: "2color" e "Impulse" e posicioná-los no canto inferior direito do gráfico.

ObjectCreate(0,"2color",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"2color",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"2color",OBJPROP_YDISTANCE,50);
ObjectSetInteger(0,"2color",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
ObjectSetInteger(0,"2color",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"2color",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"2color",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"2color",OBJPROP_SELECTABLE,false);
ObjectSetString (0,"2color",OBJPROP_TEXT,"MultiColor");

ObjectCreate(0,"Impulse",OBJ_BUTTON,ChartWindowFind(),100,100);
ObjectSetInteger(0,"Impulse",OBJPROP_XDISTANCE,75);
ObjectSetInteger(0,"Impulse",OBJPROP_YDISTANCE,25);
ObjectSetInteger(0,"Impulse",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
ObjectSetInteger(0,"Impulse",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"Impulse",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Impulse",OBJPROP_YSIZE,20);
ObjectSetInteger(0,"Impulse",OBJPROP_SELECTABLE,false);

Para a verificação Impulse de acordo com o sistema Elder, temos que adicionar um novo array onde os valores EldersMA serão posicionados.

Para fazer isso, temos que aumentar o número total de buffers em um +

#property indicator_buffers 4

deve ser alterado para:

#property indicator_buffers 5

e declaramos um novo buffer.

double EldersiEMA[];

Definimos ele como um buffer para cálculos internos:

SetIndexBuffer(4,EldersiEMA,INDICATOR_CALCULATIONS);

Agora vamos copiar os valores médios de movimento exponencial para o buffer:

// you can do all in single line
CopyBuffer(iMA(NULL,0,EldersEMA,0,MODE_EMA,PRICE_CLOSE),0,0,rates_total,EldersiEMA); 

Uma vez que o buffer tenha sido obtido por meio da função de cópia, sua indexação é a mesma para os outros buffers de nosso gráfico - a partir do final do gráfico.

Agora vamos escrever as condições para o OsMA de duas cores:

if (ObjectGetInteger(0,"2color",OBJPROP_STATE))
  {
   for(int i=1;i<rates_total;i++) {="" // if the histogram rises, the color is set to 0
      if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
      // if the histogram falls, the color is set to 1
      if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
     }
  }
else
  {
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   // Here are the conditions for multi-color OSMA
  }

Os índices de cor são especificados nas linhas:

#property indicator_label3  "Histogram"
#property indicator_type3   DRAW_COLOR_HISTOGRAM
#property indicator_color3  DeepSkyBlue,Red,Green

O índice da primeira cor é igual a 0, o índice da segunda é 1, e assim por diante.

Agora vamos escrever as condições para as variações do Sistema Impulse:

if (ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) // // "Impulse" button is checked
  {
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");  // checking for a trend using the MACD-Line
   for(int i=1;i<rates_total;i++) {="" // the histogram rises and MACD-line rises
      if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
      else
        {
         // the histogram falls and MACD-line falls 
         if((HistogramBuffer[i]<histogrambuffer[i-1]) && (MACDlineBuffer[i]<macdlinebuffer[i-1])) HistogramColors[i]=1;
         else HistogramColors[i]=2; // if there isn't any conditions satisfied
        }
     }
  }
else 
  {
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");  // checking for a trend using the EMA-line
   for(int i=1;i<rates_total;i++) {="" // the histogram rises and EMA-line rises
      if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
      else
        {
         // the histogram falls and EMA-line falls
         if((HistogramBuffer[i]<histogrambuffer[i-1]) && (EldersiEMA[i]<eldersiema[i-1])) HistogramColors[i]=1;
         else HistogramColors[i]=2;// if there isn't any conditions satisfied
        }
     }
  }</eldersiema[i-</histogrambuffer[i-</macdlinebuffer[i-</histogrambuffer[i-

Agora vamos adicionar as condições do Sistema Impulse às condições de plotagem OsMA:

if (ObjectGetInteger(0,"2color",OBJPROP_STATE))
  {
   for(int i=1;i<rates_total;i++) {="" if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
      if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
     }
  }
else
  {
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE))
     {
      ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");
      for(int i=1;i<rates_total;i++) {="" if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
         else
           {
            if((HistogramBuffer[i]<histogrambuffer[i-1]) && (MACDlineBuffer[i]<macdlinebuffer[i-1])) HistogramColors[i]=1;
            else HistogramColors[i]=2;
           }
        }
     }
   else 
     {
      ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");
      for(int i=1;i<rates_total;i++) {="" if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
         else
           {
            if((HistogramBuffer[i]<histogrambuffer[i-1]) && (EldersiEMA[i]<eldersiema[i-1])) HistogramColors[i]=1;
            else HistogramColors[i]=2;
           }
        }
     }
  }</eldersiema[i-</histogrambuffer[i-</macdlinebuffer[i-</histogrambuffer[i-

Agora, vamos escrever condições para prevenir aparecimentos de botão desnecessários:

if (ObjectGetInteger(0,"2color",OBJPROP_STATE)) ObjectSetString (0,"2color",OBJPROP_TEXT,"2ColorMACD");
else ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
if (ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) ObjectSetString (0,"Impulse",OBJPROP_TEXT,"Impulse");
else ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's")

apagamos o código, que altera o texto de um botão.

Vamos combinar todos:

//+------------------------------------------------------------------+
//|                                            MACD_By_CoreWinTT.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   3
//---- plot MACDline
#property indicator_label1  "MACDline"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Green
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//---- plot Signalline
#property indicator_label2  "Signalline"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//---- plot Histogram
#property indicator_label3  "Histogram"
#property indicator_type3   DRAW_COLOR_HISTOGRAM
#property indicator_color3  DeepSkyBlue,Red,Green
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2

//--- input parameters
input int      Fast=12;
input int      Slow=26;
input int      Signal=9;
input int      EldersEMA=13;
//--- indicator buffers
double         MACDlineBuffer[];
double         SignallineBuffer[];
double         HistogramBuffer[];
double         HistogramColors[];
double         EldersiEMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MACDlineBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignallineBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,HistogramBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,HistogramColors,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(4,EldersiEMA,INDICATOR_CALCULATIONS);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
   ArraySetAsSeries(HistogramBuffer,false);
   ArraySetAsSeries(HistogramColors,false);

   int MACDhadling=iMACD(NULL,0,Fast,Slow,Signal,PRICE_CLOSE);
   CopyBuffer(MACDhadling,0,0,rates_total,MACDlineBuffer);
   CopyBuffer(MACDhadling,1,0,rates_total,SignallineBuffer);

   for(int i=0;i<rates_total;i++) {="" histogrambuffer[i]="MACDlineBuffer[i]-SignallineBuffer[i];HistogramColors[i]=1; }

   ObjectCreate(0,"ShowMACD",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_YDISTANCE,5);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetString(0,"ShowMACD",OBJPROP_TEXT,"ShowMACD");
   ObjectSetInteger(0,"ShowMACD",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"ShowMACD",OBJPROP_SELECTABLE,false);

   ObjectCreate(0,"ShowOsMA",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_YDISTANCE,30);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
   ObjectSetString(0,"ShowOsMA",OBJPROP_TEXT,"Show OsMA");
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"ShowOsMA",OBJPROP_SELECTABLE,false);

   if(ObjectGetInteger(0,"ShowMACD",OBJPROP_STATE)!=1) 
     {
      PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE);
      PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE);
     }
   else 
     {
      PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);
      PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);
     }

   if(ObjectGetInteger(0,"ShowOsMA",OBJPROP_STATE)!=1) 
     {
      PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);
     }
   else 
     {
      PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_COLOR_HISTOGRAM);
     }

   ObjectCreate(0,"2color",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"2color",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"2color",OBJPROP_YDISTANCE,50);
   ObjectSetInteger(0,"2color",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"2color",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"2color",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"2color",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"2color",OBJPROP_SELECTABLE,false);
   ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");

   ObjectCreate(0,"Impulse",OBJ_BUTTON,ChartWindowFind(),100,100);
   ObjectSetInteger(0,"Impulse",OBJPROP_XDISTANCE,75);
   ObjectSetInteger(0,"Impulse",OBJPROP_YDISTANCE,25);
   ObjectSetInteger(0,"Impulse",OBJPROP_CORNER,CORNER_RIGHT_LOWER);
   ObjectSetInteger(0,"Impulse",OBJPROP_FONTSIZE,8);
   ObjectSetInteger(0,"Impulse",OBJPROP_XSIZE,70);
   ObjectSetInteger(0,"Impulse",OBJPROP_YSIZE,20);
   ObjectSetInteger(0,"Impulse",OBJPROP_SELECTABLE,false);
   ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");

   if(ObjectGetInteger(0,"2color",OBJPROP_STATE)) ObjectSetString(0,"2color",OBJPROP_TEXT,"2ColorMACD");
   else ObjectSetString(0,"2color",OBJPROP_TEXT,"MultiColor");
   if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE)) ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Impulse");
   else ObjectSetString(0,"Impulse",OBJPROP_TEXT,"Elder's");

   CopyBuffer(iMA(NULL,0,EldersEMA,0,MODE_EMA,PRICE_CLOSE),0,0,rates_total,EldersiEMA);

   if(ObjectGetInteger(0,"2color",OBJPROP_STATE))
     {
      for(int i=1;i<rates_total;i++) {="" if(HistogramBuffer[i] > HistogramBuffer[i-1]) HistogramColors[i]=0;
         if(HistogramBuffer[i] < HistogramBuffer[i-1]) HistogramColors[i]=1;
        }
     }
   else
     {
      if(ObjectGetInteger(0,"Impulse",OBJPROP_STATE))
        {
         for(int i=1;i<rates_total;i++) {="" if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (MACDlineBuffer[i]>MACDlineBuffer[i-1])) HistogramColors[i]=0;
            else
              {
               if((HistogramBuffer[i]<histogrambuffer[i-1]) && (MACDlineBuffer[i]<macdlinebuffer[i-1])) HistogramColors[i]=1;
               else HistogramColors[i]=2;
              }
           }
        }
      else 
        {
         for(int i=1;i<rates_total;i++) {="" if((HistogramBuffer[i]>HistogramBuffer[i-1]) && (EldersiEMA[i]>EldersiEMA[i-1])) HistogramColors[i]=0;
            else
              {
               if((HistogramBuffer[i]<histogrambuffer[i-1]) && (EldersiEMA[i]<eldersiema[i-1])) HistogramColors[i]=1;
               else HistogramColors[i]=2;
              }
           }

        }
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+</eldersiema[i-</histogrambuffer[i-</macdlinebuffer[i-</histogrambuffer[i-

O diagrama de blocos do algoritmo é mostrado na Figura 4:

Figura 4. O diagrama de blocos do algoritmo do indicador

O resultado é mostrado nas Figuras 5-7.

Fig. 5

Fig. 6

Fig. 7

Conclusão

Este artigo pode ser considerado como um guia para iniciantes, que começam a estudar os mercados usando a análise computacional de preços e implementação de métodos simples de controle gráfico de indicadores.

Espero que este artigo melhore suas habilidades técnicas na criação de sistemas de controle gráficos e ajude você a encontrar sua própria "visão de mercado", escondendo coisas que atrapalham.

Traduzido do russo pela MetaQuotes Software Corp.
Artigo original: https://www.mql5.com/ru/articles/42

Arquivos anexados |
Tratamento de eventos no MQL5: mudando período MA rapidamente Tratamento de eventos no MQL5: mudando período MA rapidamente

Suponha que um simples indicador MA (média móvel) com período 13 seja aplicado ao gráfico. Queremos mudar o período para 20, mas não queremos ir até a caixa de diálogo de propriedades do indicador e editar o número 13 para 20: por simples cansaço destas ações tediosas com o mouse e teclado. E, especialmente, não queremos abrir o código do indicador e modificá-lo. Queremos fazer tudo isso simplesmente pressionando um botão - "setas para cima" próximas ao teclado numérico. Neste artigo, descreverei como fazer isso.

MQL5: análise e processamento dos relatórios Commodity Futures Trading Commission (CFTC) no MetaTrader 5 MQL5: análise e processamento dos relatórios Commodity Futures Trading Commission (CFTC) no MetaTrader 5

Neste artigo, desenvolverei uma ferramenta para análise de relatório CFTC. Resolveremos o seguinte problema: desenvolver um indicador que permita usar os dados do relatório CFTC diretamente dos arquivos de dados fornecidos pela Comissão sem conversão e processamento intermediários. Além disso, ele pode ser utilizado para diferentes propósitos: organizar dados como um indicador, prosseguir com os dados em outros indicadores, em scripts para análise automatizada, em Expert Advisors para uso em estratégias de trading.

Interação entre o MetaTrader 5 e MATLAB Interação entre o MetaTrader 5 e MATLAB

Este artigo cobre os detalhes da interação entre o MetaTrader 5 e o pacote matemático MatLab. Ele mostra o mecanismo da conversão de dados, o processo de desenvolvimento de uma biblioteca universal para interagir com o desktop MatLab. Ele também cobre o uso do DLL gerado pelo ambiente MatLab. Este artigo é destinado a leitores experientes que conhecem C++ e MQL5.

Criando um indicador com buffers de indicador múltiplos para iniciantes Criando um indicador com buffers de indicador múltiplos para iniciantes

Os códigos complexos consistem em um conjunto de códigos simples. Se você está familiarizado com eles, não parece tão complicado. Neste artigo, considerarei como criar um indicador com múltiplos buffers de indicador. Como exemplo, o indicador Aroon é analisado detalhadamente, e duas versões diferentes do código são apresentadas.