Download MetaTrader 5

Tendência universal com GUI

12 abril 2017, 10:28
Dmitry Fedoseev
0
1 164

Conteúdo

Introdução

Nos dois artigos anteriores desta série, foi descrito o desenvolvimento de um oscilador universal com uma interface gráfica do usuário e, em seguida, de um canal universal baseado nele.  

O indicador de tendência universal também pode ser criado com base no oscilador universal. Para evitar a repetição, usaremos uma abordagem um pouco diferente. Talvez alguém goste mais dela.

No oscilador universal e no canal universal, todos os objetos dos controles foram criados na classe de formulário utilizando ponteiros automáticos, enquanto o controle de sua aparência e posição foi assumido por uma classe adicional. Agora será criado um componente universal da gerenciamento nos princípios descritos na série de artigos Controles de gráfico personalizados (artigo 1, artigo 2, artigo 3). No entanto, serão criados apenas os métodos necessários para a solução deste artigo específico. 

Tipos de indicadores

Não nos reduziremos aos indicadores que tradicionalmente pertencem aos de tendência. Qualquer indicador - que dependa da direção do preço (quer média móvel que oscilador RSI) - pode ser usado tanto para determinar o momento de abertura de posição, quanto para determinar a tendência. Por exemplo, se o preço for superior à média móvel, podemos assumir que há uma tendência ascendente, e vice-versa (Fig. 1).


Fig. 1. Uso da média móvel e do preço para determinar a tendência. As setas azuis para acima mostram os intervalos nos quais
é possível comprar (preço acima da média), as setas vermelhas para baixo mostram os intervalos nos quais é possível vender (preço abaixo da média).

Da mesma forma, é possível usar a inclinação da média, isto é: inclinação para cima - tendência crescente; inclinação para baixo - tendência decrescente (Fig. 2).

 
Fig. 2. Uso da inclinação da média móvel para determinar a tendência. As setas azuis para acima mostram os intervalos nos quais é possível comprar (média para cima), as setas vermelhas para baixo mostram os intervalos nos quais é possível vender (média para baixo).

Se nós definirmos a barra na qual o preço atravessou a média (numa barra o preço de fechamento estava abaixo da média e na próxima, acima), será usada a média para determinar o momento de abertura de posição. Neste caso, o sinal de negociação existe no percurso de uma da barra (Fig. 3). 

 
Fig. 3. Uso da média móvel e do preço para determinar os pontos de entrada. As setas azuis para acima mostram as barras
de compra (numa barra, o preço esteve abaixo da média, na seguinte, acima), setas vermelhas
para baixo mostram
as barras de venda
(numa barra, o preço esteve acima da média, na seguinte, abaixo)

Da mesma forma, é possível usar a inclinação da média, isto é: as barras - nas quais a média altera a direção - são de entrada (Fig. 4). 

 
Fig. 4 Uso da inclinação da média móvel para determinar os pontos de entrada. As setas azuis para acima mostram as barras
de compra (extremos inferiores da média), as setas vermelhas para baixo, barras de venda (extremos superiores)

Neste artigo, estaremos interessados nas variantes de detecção da tendência (como na Fig. 1 e Fig. 2). Eu trouxe variantes para determinar as barras de entrada a fim de comparar entender melhor o assunto.   

Geralmente o ponto de entrada é definido de acordo com os osciladores, muitas vezes, ao nível da interseção, por exemplo, o RSI (Fig. 5). A fim de determinar o ponto de entrada, o oscilador estocástico pode ser usado pelo menos de duas maneiras, isto é: segundo o cruzamento de nível e de acordo com o cruzamento das principais linhas de sinal.  

 
Fig. 5. Determinação das barras de entrada de acordo com o indicador RSI. As setas azuis mostram as barras de compra (cruzamento do nível
de 70 para cima), as setas vermelhas, as barras de venda (cruzamento do nível de 30 para baixo)

Examinemos como se pode usar osciladores para determinar a tendência. Para o estocástico, o resposta é óbvia, isto é, segundo a posição das linhas principal e de sinal, se a linha principal estiver acima da de sinal, será possível comprar; enquanto, se a principal estiver abaixo da de sinal, será possível vender (Fig. 6).


Fig. 6 Definição das linhas principal e de sinal do oscilador estocástico para determinar a tendência. As setas azuis marcam
a tendência para cima (linha principal acima da de sinal), as setas vermelhas, a tendência de queda (linha principal abaixo da de sinal)

Da mesma forma, é possível usar os níveis, a saber: se o oscilador estiver acima de um certo nível, será possível comprar, se estiver abaixo, será possível vender (Fig. 7).

 
Fig. 7. Utilização do oscilador RSI e de níveis para determinar a tendência.  As setas azuis marcam a tendência de alta
(RSI acima de 60), as setas vermelhas marcam a tendência de queda (RSI abaixo de 40)
 

Exibição da tendencia

Escolhemos a forma mais conveniente para exibir tendência. A primeira ideia que surge consiste numa linha colorida que muda de cor dependendo da tendência. Consideremos a definição da tendência segundo o oscilador RSI e os níveis de 60 e 40. Se a linha RSI estiver acima do nível de 60, será possível comprar, e, se estiver abaixo de 40, será possível vender (Fig. 7). Acontece que quando a linha do RSI está entre os níveis de 40 e 60, não se deve nem comprar nem vender. Agora alteramos os níveis de lugares, isto é: nível de compra igual a 40 (se houver valores superiores a 40, sera possível comprar), níveis de venda igual a 60 (se os valores forem inferiores a 60, sera possível vender). Neste caso, entre os níveis de 40 e 60, é possível comprar e vender (Fig. 8).

 
Fig. 8. Utilização do oscilador RSI e de níveis para determinar a tendência. Se houver níveis de compra 40 e de venda 60
haverá áreas em que é possível e comprar e vender (duas setas azuis e vermelhas).

Disto segue que a tendência deve ser exibida através de duas séries de dados. Usaremos dois indicadores de buffer, isto é: um deslocado ligeiramente acima, outro, ligeiramente abaixo (para ter a possibilidade de exibir simultaneamente dois buffers). Como os buffers serão exibidos intermitentemente, será melhor utilizar histogramas ou ícones. Selecionemos os ícones. Assim, além de cores diferentes para cada buffer, é possível utilizar vários ícones. O indicador é mostrado na Fig. 9.

 
Fig. 9. Maneira conveniente de exibir a tendência

Tal exibição da tendência permite expandir o número de indicadores a serem utilizados. Por exemplo, é possível criar indicadores que, em vez de depender da direção, só permitam/proíbam a negociação em vários intervalos. Por exemplo, você pode usar o indicador ATR ou STD. Se seu valor for superior a determinado limiar, serão exibidas ambas as setas (para cima/baixo). Assim, o indicador universal torna-se ainda mais versátil.   

Indicadores utilizados

Antes de começar a criar o indicador de tendência universal, definiremos a lista completa de indicadores segundo os quais será determinada a tendência. Assim, encontraremos o conjunto de parâmetros externos necessário (o número e tipos de variáveis). Claro, é pouco provável que todas as possíveis variantes possam ser colocadas imediatamente no indicador, uma vez que são muitas. Uma média móvel pode ser usada apenas de duas maneiras. No entanto, pode-se usar ainda mais duas médias móveis. Portanto, inicialmente, é necessário fornecer a melhor maneira que facilite a modificação do indicador.

Algumas variantes de uso podem ser idênticas, embora possa não parecer tão óbvio. Por exemplo,o uso para determinar a tendência das duas médias móveis (rápida e lenta) torna desnecessária a variante para determinar a tendência de acordo com o preço e a média. Se, para a média rápida, for definido o período 1, ela será igual ao preço. Por isto cada indicador tem de ser tratado separadamente. Além disso, é necessário considerar diretamente cada uma da variantes de implementação de cada indicador.

iAC (Accelerator Oscillator)

O indicador não tem parâmetros, é idêntico ao indicador OsMA em determinados parâmetros, por isso não será usado.  

iAD (Accumulation/Distribution)

Indicador muito específico. O intervalo de valores do indicador não é definido, sua linha é demasiado quebrada, o que não é adequado para determinar a tendência sem um tratamento apropriado (por exemplo, utilizando a suavização). Ele não será usado. 

iADX (Average Directional Index)

Variante 1. Posição das linhas do PDI e MDI. PDI acima do MDI — tendência em alta, PDI abaixo do MDI — tendência em baixa.

Parâmetros

  1. int adx_period. 

Variante 2. Não depende de direção. A posição da linha do ADX em relação a um determinado nível. ADX acima do nível — compra e venda permitidas. Além do parâmetro do indicador, é preciso um parâmetro adicional para o nível. 

 Parâmetros:

  1. int adx_period — período;
  2. double level — nível. 

iADXWilder (Average Directional Index by Welles Wilder)

Tudo o mesmo, como no ADX.

iAlligator (Alligator)

O indicador representa três médias móveis com diferentes períodos e diferentes deslocamentos. É possível criar diversas maneiras de usar este indicador, mas nos limitaremos a um objetivo.

Variante 1. Se a linha rápida (lábios) estiver acima da média (dentes) e a média estiver acima da lenta (mandíbula) — a tendência será ascendente, se a localização das linhas for o contrário, a tendência será de queda.   

Parâmetros

    1. int jaw_period — período de mandíbulas; 
    2. int jaw_shift — deslocamento de mandíbulas; 
    3. int teeth_period — período de dentes;
    4. int teeth_shift — deslocamento de dentes; 
    5. int lips_period — período para lábios; 
    6. int lips_shift — deslocamento dos lábios;
    7. ENUM_MA_METHOD ma_method — tipo de suavização; 
    8. ENUM_APPLIED_PRICE applied_price — tipo de preço.

iAMA (Adaptive Moving Average)

O indicador é uma média móvel. Nós vamos usar as duas versões de uso de todas as médias.

Variante 1. Inclinação da linha. Além dos parâmetros padrão do indicador, exigido parâmetro que determina o deslocamento do segundo ponto do indicador em relação ao qual verificada a inclinação. 

Parâmetros

    1. int ama_period — período do AMA; 
    2. int fast_ma_period — período da média rápida;
    3. int slow_ma_period — período da média lenta; 
    4. int ama_shift — deslocamento horizontal do indicador; 
    5. ENUM_APPLIED_PRICE  applied_price — tipo de preço;
    6. int shift2 — deslocamento do ponto em relação ao qual é verificada inclinação

Variante 2. Duas linhas: rápida e lenta. Linha rápida acima da lenta — tendência em alta, rápida abaixo da lenta — tendência em baixa. Requer dois conjuntos iguais de parâmetros padrão. 

Parâmetros

    1. int ama_period1 — período AMA; 
    2. int fast_ma_period1 — período da média rápida;
    3. int slow_ma_period1 — período da média lenta; 
    4. int ama_shift1 — deslocamento horizontal do indicador; 
    5. ENUM_APPLIED_PRICE  applied_price1 — tipo de preço;
    6. int ama_period2 — período AMA; 
    7. int fast_ma_period2 — período da média rápida;
    8. int slow_ma_period2 — período da média lenta; 
    9. int ama_shift2 — deslocamento horizontal do indicador; 
    10. ENUM_APPLIED_PRICE  applied_price2 — tipo de preço.
Nota: as variáveis com o número 1 no final são utilizadas para a linha rápida, com o número 2, para a lenta. 


O indicador não tem parâmetros, é idêntico ao indicador MACD em determinados parâmetros, por isso não será usado.   

iATR (Average True Range)

O indicador não depende da direção; será usada uma variante.

Variante 1: não dependente da direção. Posição da linha do ATR em relação ao nível. ATR acima do nível — compra e venda permitidas. Além do parâmetro do indicador, é preciso um parâmetro adicional para o nível. 

 Parâmetros:

  1. int ma_period — período;
  2. double level — nível.  

iBearsPower (Bears Power) e iBullsPower (Bulls Power)

Os indicadores BearsPower e BullsPower são assimétricos, quer dizer, eles devem ser utilizados em pares, isto é, um para sinais de compra, outro para sinais de venda. Para determinar a tendência em alta, utilizaremos o BullsPower, para a tendência em baixa, o BearsPower. Usaremos duas variantes: de acordo com a posição do indicador em relação ao nível e de acordo com a inclinação.

Variante 1. Se o BullsPower estiver acima do nível especificado, serão permitidas as compras, se o BearsPower estiver abaixo do valor negativo deste mesmo nível, serão permitidas as vendas. Além dos parâmetros padrão, é preciso um parâmetro adicional para o nível.

Parâmetros:

    1. int ma_period — período;
    2. double level — nível.   

Variante 2. Direção do indicador. Para esta variante, exigido um parâmetro adicional que determina o deslocamento do segundo ponto em relação ao qual determinada a inclinação.

Parâmetros:

    1. int ma_period — período;
    2. int shift2 — deslocamento do segundo ponto.   

iBands (Bollinger Bands)

O indicador é um canal.

Variante 1. Se o preço cruzar para cima a borda superior, começará uma tendência em alta; se o preço cruzar para baixo a linha central, a tendência é cancelada. Da mesma forma, o indicador funciona na direção oposta para a linha inferior e a tendência em baixa.  

Parâmetros:

    1. int bands_period — período para calcular a linha média;
    2. int bands_shift — deslocamento horizontal do indicador; 
    3. double — número de desvios padrão; 
    4. ENUM_APPLIED_PRICE  applied_price — tipo de preço.

iCCI (Commodity Channel Index)

O indicador é um oscilador numa sub-janela. Como a linha do indicador é bastante quebrada, mesmo para períodos grandes, não será usada a variante com inclinação.

Variante 1. Posição em relação ao nível. Se o indicador estiver acima do nível, a tendência será para cima, se o indicador estiver abaixo do valor negativo deste mesmo nível, a tendência será para baixo. 

Parâmetros:

    1. int ma_period — período de média; 
    2. ENUM_APPLIED_PRICE  applied_price — tipo de preço ou handle;  
    3. double level — nível.   

iChaikin (Chaikin Oscillator)

A aplicação do indicador é semelhante com a implementação do indicador CCI.

Variante 1. Posição em relação ao nível. Se o indicador estiver acima do nível, a tendência será para cima, se o indicador estiver abaixo do valor negativo deste mesmo nível, a tendência será para baixo. 

Parâmetros:

    1. int fast_ma_period — período rápido;  
    2. int ow_ma_period — período lento; 
    3. ENUM_MA_METHOD ma_method — tipo de suavização; 
    4. ENUM_APPLIED_VOLUME  applied_volume — volume a ser utilizado; 
    5. double level — nível. 

iDEMA (Double Exponential Moving Average)

O indicador é uma média móvel e é usado da mesma forma como o anteriormente estudado.

Variante 1. Inclinação da linha. 

Parâmetros

    1. int ma_period — período de média;
    2. ENUM_APPLIED_PRICE  applied_price — tipo de preço;
    3. int ma_shift — deslocamento horizontal do indicador; 
    4. int shift2 — deslocamento do ponto em relação ao qual é verificada a inclinação

Variante 2. Duas linhas: rápida e lenta.

Parâmetros

    1. int ma_period1 — período de média;
    2. ENUM_APPLIED_PRICE  applied_price1 — tipo de preço;
    3. int ma_shift1 — deslocamento horizontal do indicador; 
    4. int ma_period2 — período de média;
    5. ENUM_APPLIED_PRICE  applied_price2 — tipo de preço;
    6. int ma_shift2 — deslocamento horizontal do indicador.
Nota: as variáveis com o número 1 no final são utilizadas para a linha rápida, com o número 2, para a lenta. 

iDeMarker (DeMarker)

O indicador representa um oscilador - numa sub-janela - que muda entre 0 e 1. O nível neutro do indicador é o nível de 0,5. A linha quebrada do indicador não é apropriada para a variante com inclinação.

Variante 1. Posição em relação ao nível. O nível para venda será definido através dos parâmetros, enquanto o nível para compra será calculado de forma simétrica em relação ao nível de 0,5. 

Parâmetros:

  1. int ma_period — período de média;
  2. double level — nível de venda.

iEnvelopes (Envelopes)

O indicador é um canal como as bandas de Bollinger, mas ele é aplicado mais facilmente.

Variante 1. Se o preço estiver acima da borda superior do canal, será permitida a compra, se estiver abaixo da borda inferior, será permitida a venda.  

Parâmetros:

  1. int ma_period — período para calcular a linha média;
  2. int ma_shift — deslocamento horizontal do indicador; 
  3. ENUM_MA_METHOD ma_method — tipo de suavização;
  4. ENUM_APPLIED_PRICE applied_price — tipo de preço ou; 
  5. double deviation — desvio das bordas a partir da média da linha.  

iForce (Force Index)

O indicador representa o oscilador numa sub-janela que muda e torno do nível 0. Toda aplicação do indicador é semelhante como no indicador CCI.

Variante 1. Posição em relação ao nível. 

Parâmetros: 

  1. int ma_period — período de média; 
  2. ENUM_MA_METHOD ma_method — tipo de suavização; 
  3. ENUM_APPLIED_VOLUME applied_volume — tipo de volume para cálculo;
  4. double level — nível.    

iFractals (Fractals)

O indicador não tem parâmetros.

Variante 1. A definição ocorre no tipo do último fractal. Se o último fractal estiver acima, são colocadas posições de compra, se estiver abaixo, de venda.  

iFrAMA (Fractal Adaptive Moving Average)

O indicador é uma média móvel usada da mesma forma como o AMA. 

Variante 1. Inclinação da linha. 

Parâmetros

  1. int ma_period — período de média; 
  2. int ma_shift — deslocamento horizontal do indicador; 
  3. ENUM_APPLIED_PRICE  applied_price — tipo de preço;
  4. int shift2 — deslocamento do ponto em relação ao qual é verificada a inclinação

Variante 2. Duas linhas: rápida e lenta.

Parâmetros

    1. int ma_period1 — período de média; 
    2. int ma_shift1 — deslocamento horizontal do indicador; 
    3. ENUM_APPLIED_PRICE  applied_price1 — tipo de preço;
    4. int ma_period2 — período de média; 
    5. int ma_shift2 — deslocamento horizontal do indicador; 
    6. ENUM_APPLIED_PRICE  applied_price2 — tipo de preço.
Nota: as variáveis com o número 1 no final são utilizadas para a linha rápida, com o número 2, para a lenta. 

iGator (Gator Oscillator)

Este indicador é calculado com base no indicador Alligator. Todas as informações - que ele fornece - podem ser obtidas diretamente a partir do indicador Alligator, mas não vamos usá-lo. 

iIchimoku (Ichimoku Kinko Hyo)

Quanto a este indicador, apenas um par de linhas podem ser de interesse: Tenkan Kijun e nuvem. Na nuvem podem ser divididas duas linhas que mudam sua posição (quer uma quer a outra no topo). Afinal, há duas variantes de uso do indicador.

Variante 1. Posição das linhas Tenkan e Kijun. Se a linha Tenkan (vermelha) estiver acima da linha Kijun (azul), a tendência será para cima, se a Tenkan estiver abaixo da linha Kijun, a tendência será para baixo.

Parâmetros: 

    1. int tenkan_sen — período Tenkan-sen; 
    2. int kijun_sen — período Kijun-sen; 
    3. int senkou_span_b — período Senkou Span B.  

Variante 2. Na direção da nuvem. A nuvem é definida por duas linhas, isto é: SpanA e SpanB. Se a linha SpanA estiver acima da linha SpanB, a tendência será para cima, caso contrário, a tendência será para baixo.

Parâmetros: 

    1. int tenkan_sen — período Tenkan-sen; 
    2. int kijun_sen — período Kijun-sen; 
    3. int senkou_span_b — período Senkou Span B.  

Não utilizaremos este indicador por causa de sua alta especificidade. 

iMomentum (Momentum)

O indicador é um oscilador numa sub-janela. A linha do indicador é muito quebrada, portanto, não é adequado para determinar a tendência segundo a inclinação. Ficamos só com a variante segundo o nível.

Variante 1. Nível. Nível neutro: 100. Além dos parâmetros padrão do indicador, será exigido parâmetro para o nível de venda, enquanto o nível para compra será calculado de forma simétrica em relação ao nível de 100.

Parâmetros:

    1. int mom_period — período de média; 
    2. ENUM_APPLIED_PRICE applied_price — tipo de preço ou handle;
    3. double level — nível de venda.  

iMFI (Money Flow Index)

O indicador representa um oscilador - numa sub-janela - que muda entre 0 e 100. Nível neutro: 50. Uma linha quebrada não é adequada para determinar a tendência segundo a direção.

Variante 1. De acordo com o nível. Além dos parâmetros padrão, será exigido parâmetro para o nível de venda, enquanto o nível para compra será calculado de forma simétrica em relação ao nível de 50. Se a linha do indicador estiver acima do nível de compra, a tendência será para cima, se estiver abaixo do valor de venda, a tendência será para baixo. 

Parâmetros: 

    1. int ma_period — período de média;
    2. ENUM_APPLIED_VOLUME applied_volume — tipo de volume para cálculo;
    3. double level — nível de venda.  

iMA (Moving Average)

Esta é uma média móvel habitual.

Variante 1. Inclinação da linha.

Parâmetros

    1. int ma_period — período de média; 
    2. int ma_shift — deslocamento horizontal do indicador; 
    3. ENUM_MA_METHOD ma_method — tipo de suavização; 
    4. ENUM_APPLIED_PRICE applied_price — tipo de preço;
    5. int shift2 — deslocamento do ponto em relação ao qual é verificada inclinação

Variante 2. Duas linhas: rápida e lenta.

Parâmetros

  1. int ma_period1 — período de média; 
  2. int ma_shift1 — deslocamento horizontal do indicador; 
  3. ENUM_MA_METHOD ma_method1 — tipo de suavização; 
  4. ENUM_APPLIED_PRICE applied_price1 — tipo de preço;
  5. int ma_period2 — período de média; 
  6. int ma_shift2 — deslocamento horizontal do indicador; 
  7. ENUM_MA_METHOD ma_method2 — tipo de suavização; 
  8. ENUM_APPLIED_PRICE applied_price2 — tipo de preço.
Nota: as variáveis com o número 1 no final são utilizadas para a linha rápida, com o número 2, para a lenta. 


iOsMA (Moving Average of Oscillator (MACD histogram)

O oscilador OSMA é um histograma numa sub-janela. Pode haver duas variantes: segundo o nível e segundo a direção.

Variante 1. De acordo com o nível. Se o histograma estiver acima do nível, serão permitidas as compras, se estiver abaixo do valor negativo desse mesmo nível, serão permitidas as vendas.

Parâmetros: 

  1. int fast_ema_period — período da média rápida; 
  2. int slow_ema_period — período da média lenta; 
  3. int signal_period — período de média ;
  4. ENUM_APPLIED_PRICE  applied_price — tipo de preço ou handle; 
  5. double level — nível.

Variante 2. De acordo com a direção. Se o histograma estiver inclinado para cima, serão permitidas as compras, se, para baixo, as vendas. Isso requer um parâmetro adicional para o deslocamento do segundo ponto em relação ao qual é verificada a direção.  

Parâmetros:

  1. int fast_ema_period — período da média rápida; 
  2. int slow_ema_period — período da média lenta; 
  3. int signal_period — período de média ;
  4. ENUM_APPLIED_PRICE  applied_price — tipo de preço ou handle; 
  5. int shift2 — deslocamento do segundo ponto para definir a direção. 

iMACD (Moving Averages Convergence-Divergence)

O indicador MACD exibe - numa sub-janela - um histograma e uma linha de sinal. O indicador pode ser usado de três maneiras diferentes: segundo o nível do histograma, segundo suas direção e posição em relação à linha de sinal. No entanto, este último é um caso especial de verificação do indicador OsMA segundo o nível (no valor de nível 0) e, portanto, não será usado.  

Variante 1. De acordo com o nível. Se o histograma estiver acima do nível, serão permitidas as compras, se estiver abaixo do valor negativo desse mesmo nível, serão permitidas as vendas.

Parâmetros: 

  1. int fast_ema_period — período da média rápida; 
  2. int slow_ema_period — período da média lenta; 
  3. int signal_period — período de média ;
  4. ENUM_APPLIED_PRICE  applied_price — tipo de preço ou handle; 
  5. double level — nível.

Variante 2. De acordo com a direção. Se o histograma estiver inclinado para cima, serão permitidas as compras, se, para baixo, as vendas. Isso requer um parâmetro adicional para o deslocamento do segundo ponto em relação ao qual é verificada a direção.  

Parâmetros:

  1. int fast_ema_period — período da média rápida; 
  2. int slow_ema_period — período da média lenta; 
  3. int signal_period — período de média ;
  4. ENUM_APPLIED_PRICE  applied_price — tipo de preço ou handle; 
  5. int shift2 — deslocamento do segundo ponto para definir a direção. 

iOBV (On Balance Volume)

Este indicador, bem como o indicador de AD, não tem uma gama específica de valores e é muito quebrado. Não será usado. 

iSAR (Parabolic Stop And Reverse System)

O indicador desenha uma linha a partir dos pontos. Dependendo da direção do preço, a linha está localizada quer acima que abaixo do preço.

Variante 1. Posição em relação ao preço. Preço acima do indicador — tendência em alta, preço abaixo do indicador — tendência em baixa. 

Parâmetros:

  1. double step — incremento na alteração do preço — fator de aceleração;
  2. double maximum — incremento máximo. 

iRSI (Relative Strength Index)

Oscilador numa sub-janela. Variante de implementação semelhante à utilizada com indicador MFI.

Variante 1. De acordo com o nível.

Parâmetros: 

  1. int ma_period — período de média; 
  2. ENUM_APPLIED_PRICE  price — tipo de preço;
  3. double level — nível de venda.  

iRVI (Relative Vigor Index)

Oscilador numa sub-janela com linha de sinal. O valor varia em torno de zero.

Variante 1. De acordo com o nível. Se acima do nível, compras, se abaixo do valor negativo do nível, vendas.

Parâmetros:

    1. int ma_period — período de média;
    2. double level — nível.  

Variante 2. Linha principal e de sinal.

Parâmetros:

    1. int ma_period — período de média.  

iStdDev (Standard Deviation)

Indicador que não depende da direção. Semelhante ao indicador ATR.

Variante 1. De acordo com o nível. 

Parâmetros: 

    1. int ma_period — período de média; 
    2. int ma_shift — deslocamento horizontal do indicador; 
    3. ENUM_MA_METHOD ma_method — tipo de suavização; 
    4. ENUM_APPLIED_PRICE applied_price — tipo de preço;
    5. double level — nível.  

iStochastic (Stochastic Oscillator)

Oscilador numa sub-janela com linhas de sinal. 

Variante 1. Inclinação da linha principal. 

Parâmetros:

  1. int Kperiod — período K;
  2. int Dperiod — período D;
  3. int slowing — suavização final; 
  4. ENUM_MA_METHOD ma_method — tipo de suavização; 
  5. ENUM_STO_PRICE price_field — preço;
  6. int shift2 — deslocamento do segundo ponto para definir a inclinação. 

Variante 2. De acordo com o nível. O valor do indicador varia de 0 a 100; nível neutro de 50. Exigido parâmetro para o nível de venda, enquanto o nível para compra é calculado. 

Parâmetros:

  1. int Kperiod — período K;
  2. int Dperiod —  período D;
  3. int slowing — suavização final; 
  4. ENUM_MA_METHOD ma_method — tipo de suavização; 
  5. ENUM_STO_PRICE price_field — preço;
  6. double level — nível.

Variante 3. Posição das linhas principal e de sinal.

Parâmetros:

  1. int Kperiod — período K;
  2. int Dperiod — período D;
  3. int slowing — suavização final; 
  4. ENUM_MA_METHOD ma_method — tipo de suavização; 
  5. ENUM_STO_PRICE price_field — preço.

iTEMA (Triple Exponential Moving Average)

Outra média móvel.

Variante 1. Inclinação da linha.

Parâmetros

  1. int ma_period — período de média; 
  2. int ma_shift — deslocamento horizontal do indicador; 
  3. ENUM_APPLIED_PRICE applied_price — tipo de preço;
  4. int shift2 — deslocamento do ponto em relação ao qual é verificada inclinação

Variante 2. Duas linhas: rápida e lenta.

Parâmetros

  1. int ma_period1 — período de média; 
  2. int ma_shift1 — deslocamento horizontal do indicador; 
  3. ENUM_APPLIED_PRICE applied_price1 — tipo de preço;
  4. int ma_period2 — período de média; 
  5. int ma_shift2 — deslocamento horizontal do indicador; 
  6. ENUM_APPLIED_PRICE applied_price2 — tipo de preço.
Nota. As variáveis com o número 1 no final são utilizadas para a linha rápida, com o número 2, para a lenta. 

iTriX (Triple Exponential Moving Averages Oscillator)

Oscilador numa sub-janela. Uma variante tem a ver com a inclinação da linha, e, para variar, como uma segunda opção usaremos variante com duas linhas, isto é, rápida e lenta 

Variante 1. Inclinação da linha.

Parâmetros

  1. int ma_period — período de média; 
  2. int ma_shift — deslocamento horizontal do indicador; 
  3. ENUM_APPLIED_PRICE applied_price — tipo de preço;
  4. int shift2 — deslocamento do ponto em relação ao qual é verificada inclinação
Nota: a função iTriX não tem parâmetro ma_shift, mas seja como for o indicador pode ser deslocado. Em qualquer caso, o deslocamento não será executado através do parâmetro shift (ele será definido como 0 para todos os indicadores), mas sim por meio do cálculo do índice de barra.

Variante 2. Duas linhas: rápida e lenta.

Parâmetros

  1. int ma_period1 — período de média; 
  2. int ma_shift1 — deslocamento horizontal do indicador; 
  3. ENUM_APPLIED_PRICE applied_price1 — tipo de preço;
  4. int ma_period2 — período de média; 
  5. int ma_shift2 — deslocamento horizontal do indicador; 
  6. ENUM_APPLIED_PRICE applied_price2 — tipo de preço.
Nota. As variáveis com o número 1 no final são utilizadas para a linha rápida, com o número 2, para a lenta. 

iWPR (Williams' Percent Range)

O indicador é idêntico à linha principal do estocástico durante a desaceleração 1, mas com uma escala invertida. Ele não será usado.

iVIDyA (Variable Index Dynamic Average)

Outra média móvel.

Variante 1. Inclinação da linha.

Parâmetros

  1. int cmo_period — período CMO 
  2. ema_period — período de suavização 
  3. ma_shift — deslocamento horizontal do indicador 
  4. ENUM_APPLIED_PRICE applied_price  — tipo de preço
  5. int shift2 — deslocamento do ponto em relação ao qual é verificada inclinação
Variante 2. Duas linhas: rápida e lenta.

Parâmetros

  1. int ma_period1 — período de média; 
  2. int ma_shift1 — deslocamento horizontal do indicador; 
  3. ENUM_APPLIED_PRICE applied_price1 — tipo de preço;
  4. int ma_period2 — período de média; 
  5. int ma_shift2 — deslocamento horizontal do indicador; 
  6. ENUM_APPLIED_PRICE applied_price2 — tipo de preço.
Nota: as variáveis com o número 1 no final são utilizadas para a linha rápida, com o número 2, para a lenta. 

iVolumes (Volumes)

A leitura do indicador não depende da direção do preço. O indicador pode ser usado como o indicador ATR ou DST.

Variante 1. Nível. Se o valor do indicador estiver acima do nível, serão permitidas compras e vendas. 

Parâmetros:

  1. ENUM_APPLIED_VOLUME  applied_volume — tipo de volume;
  2. double level — nível.  

Definidos os indicadores e as formas de usá-los, escrevemos uma enumeração de todos os tipos. Na pasta Includes, criamos a pasta UniTrend, nela criamos o arquivo UniTrendDefines.mqh com enumeração: 

enum EType{    Type_ADX_PDIMDI,          // posição das linhas do PDI e MDI do indicador ADX    Type_ADX_Level,           // posição das linhas do ADX em relação ao nível    Type_ADXW_PDIMDI,         // posição das linhas do PDI e MDI do indicador ADX Wilder    Type_ADXW_Level,          // posição das linhas do ADX em relação ao nível no indicador ADX Wilder    Type_Alligator,           // Alligator    Type_AMA_Dir,             // direção do AMA          Type_AMA_2MA,             // dois AMA    Type_ATR_Level,           // ATR    Type_BuBe_Level,          // Bulls/Bears Power e nível    Type_BuBe_Dir,            // direção do Bulls/Bears Power    Type_Bands,               // bandas de Bollinger      Type_CCI_Level,           // CCI e nível    Type_Chaikin_Level,       // oscilador Chaikin e nível    Type_DEMA_Dir,            // direção DEMA        Type_DEMA_2MA,            // dois DEMA        Type_DeMarker_Level,      // DeMarker e nível    Type_Envelopes,           // Envelopes    Type_Force_Level,         // oscilador Force e nível    Type_Fractals,            // Fractais    Type_FrAMA_Dir,           // direção FrAMA        Type_FrAMA_2MA,           // dois FrAMA    Type_Ichimoku_TK,         // Ichimóku: Tenkan e Kijun    Type_Ichimoku_SASB,       // Ichimóku: nuvem          Type_Momentum_Level,      // Momentum e nível    Type_MFI_Level,           // MFI e nível    Type_MA_Dir,              // direção do MA          Type_MA_2MA,              // dois MA    Type_OsMA_Dir,            // direção do OsMA    Type_OsMA_Level,          // OsMA e nível    Type_MACD_Dir,            // direção MACD    Type_MACD_Level,          // MACD e nível    Type_SAR,                 // SAR    Type_RSI_Level,           // RSI e nível    Type_RVI_Level,           // RVI e nível    Type_RVI_MS,              // linas principal e de sinal do RVI    Type_STD_Level,           // desvio padrão e nível    Type_Sto_Dir,             // direção do estocástico    Type_Sto_Level,           // estocástico e nível    Type_Sto_MS,              // linas principal e de sinal do estocástico            Type_TEMA_Dir,            // direção do TEMA    Type_TEMA_2MA,            // dois TEMA    Type_TriX_Dir,            // direção do TriX    Type_TriX_2MA,            // dois TriX    Type_VIDyA_Dir,           // direção do VIDyA    Type_VIDyA_2MA,           // dois VIDyA    Type_Volumes              // volume        

};

Parâmetros externos

Analisadas as descrições acima no que diz respeito aos indicadores, pode ser determinado o conjunto necessário de parâmetros externos. A tabela 1 mostra todos os parâmetros necessários e seus tipos. Basicamente serão envolvidas variáveis prefixadas com "f_" (a partir do ingl. fast — rápido). Para as variantes com médias móveis rápida e lenta, é usado o segundo grupo de parâmetros com o prefixo "s_" (a partir do ingl. slow — lento).

Tabela 1. Parâmetros externos e seus tipos  

Tipo Nome
int  f_period1
int  f_shift1
int  f_period2
int  f_shift2
int  f_period3
int  f_shift3
ENUM_MA_METHOD  f_method
ENUM_APPLIED_PRICE  f_price
ENUM_APPLIED_VOLUME   f_volume
ENUM_STO_PRICE  f_sto_price
double  f_level
int  f_dot2shift
double  f_step 
double  f_maximum 
int  s_period1
int  s_shift1
int  s_period2
int  s_shift2
int  s_period3
int 
s_shift3
ENUM_MA_METHOD  s_method
ENUM_APPLIED_PRICE  s_price
int mult 
int  level_digits 
int  sar_step_digits 
int  sar_maximum_digits 

Além dos parâmetros listados nas descrições dos indicadores, na parte inferior da tabela, existem vários parâmetros adicionais:

  • mult — fator de multiplicação dos parâmetros medidos em pontos, dependendo do número de caracteres nas cotações. Os valores de alguns indicadores, como o MACD e o OsMA, têm a dimensão do preço, por isso, é mais confortável definir seu nível em pontos. Assim, será conveniente ajustar os parâmetros de acordo com o número de caracteres nas cotações.
  • level_digits — número de casas decimais no parâmetro do nível. Na interface gráfica do usuário, para definir o valor do nível, é usado o controle CSpinBox (campo de entrada com os botões "+" e "-"), por isso seria conveniente - para diferentes indicadores - estabelecer a mudança mínima (a quantidade para a qual muda o valor pressionando o botão "+" ou "-").
  • sar_step_digits — número de casas decimais para o parâmetro step.
  • sar_maximum_digits — número de casas decimais para o parâmetro maximum do indicador SAR.
Imediatamente é difícil definir os valores adequados para os parâmetros level_digits, sar_step_digitssar_maximum_digits, por isto,  adicionamos as constantes ao arquivo UniTrendDefines.mqh, logo após, será fácil ajustar seus valores:
#define ADX_LEVEL_DIGITS         0 // para o indicador ADX
#define ADXW_LEVEL_DIGITS        0 // para o indicador ADX Wilder
#define ATR_LEVEL_DIGITS         1 // para o indicador ATR
#define BUBE_LEVELS_DIGITS       1 // para os indicadores Bulls/Bears Power
#define CCI_LEVEL_DIGITS         0 // para o indicador CCI 
#define CHAIKIN_LEVEL_DIGITS     0 // para o oscilador Chaikin
#define DEMARKER_LEVEL_DIGITS    2 // para o indicador Demarker  
#define FORCE_LEVEL_DIGITS       3 // para o indicador Force 
#define MOMENTUM_LEVEL_DIGITS    2 // para o indicador Momentum 
#define MFI_LEVEL_DIGITS         0 // para o indicador 
#define OSMA_LEVBEL_DIGITS       2 // para o indicador OsMA
#define MACD_LEVEL_DIGITS        2 // para o indicador MACD
#define RSI_LEVEL_DIGITS         0 // para o indicador RSI
#define RVI_LEVEL_DIGITS         2 // para o indicador RVI
#define STD_LEVEL_DIGITS         1 // para o indicador STD
#define STO_LEVEL_DIGITS         0 // para o indicador Stochastic
#define BANDS_LEVEL_DIGITS       1 // para Bandas de Bollinger
#define ENVELOPES_LEVEL_DIGITS   2 // para o indicador Envelopes
#define SAR_STEP_DIGITS          3 // para o indicador SAR (parâmetro step)
      #define SAR_MAXIMUM_DIGITS       2 // para o indicador SAR (parâmetro maximum)
Para os indicadores ATR, Bulls/Bears, OsMA, MACD, STD, o valor do nível será definido em pontos. 

Com base na tabela 1, criaremos a estrutura:

struct SExtParams{
   int                 f_period1;
   int                 f_shift1;
   int                 f_period2;
   int                 f_shift2;
   int                 f_period3;
   int                 f_shift3;
   long                f_method;
   long                f_price;
   long                f_volume;
   long                f_sto_price;
   double              f_level;
   int                 f_dot2shift;
   double              f_step;  
   double              f_maximum;  
   int                 s_period1;
   int                 s_shift1;
   int                 s_period2;
   int                 s_shift2;
   int                 s_period3;
   int                 s_shift3;
   long                s_method;
   long                s_price;
   int                 mult;
   int                 level_digits;
   int                 sar_step_digits;
   int                 sar_maximum_digits;      
            };

A combinação de parâmetros numa estrutura permite separá-los do resto do código, o que será muito conveniente ao modificar o indicador durante a adição de novos tipos de detecção de tendência, se os parâmetros disponíveis forem insuficientes. Isto também simplifica consideravelmente a transferência de parâmetros para as funções e métodos.

Como o indicador criado no artigo exibirá a tendência como linhas de ícones (isto é igual para todos os indicadores), não será difícil adicionar ao indicador a função de notificação sobre o início da tendência. Uma vez que há quem esteja interessado apenas na notificação quer sobre a tendência que está sendo formada (leituras na barra formada) quer sobre o surgimento de uma nova tendência (na barra formada), escreveremos a enumeração para selecionar o tipo de notificação:

enum EAlerts{
   Alerts_off=0, // notificação desativada
   Alerts_Bar0=1, // notificação sobre a barra que está sendo formada
   Alerts_Bar1=2 // notificação sobre a barra formada
            };  

Criação do indicador

A criação de classes para indicadores universais foi considerada em detalhe nos artigos Oscilador universal com uma interface gráfica do usuário e Canal universal com interface gráfica do usuário. Examinemos as peculiaridades de sua criação em relação a este caso.

Todos os métodos acima listados para determinar a tendência são divididos em duas categorias, isto é, com um ou dois indicadores. Num grupo, após carregar o indicador, é necessário verificar um identificador, enquanto noutro grupo, dois identificadores. Isto significa que, na classe base, haverá duas subclasses com formas diferentes para verificar os identificadores. Por sua vez, essas subclasses terão suas subclasses, nas quais serão determinadas as tendências.

Classe base:

class CUniTrend{
   protected:
  
      int m_handle1;
      int m_handle2;
      
      string m_name;
      string m_help;
      
      int m_ci;
      
      double m_b1[1];
      double m_b2[1];      
      double m_b3[1];    
      double m_b4[1];
            
      int m_shift;
      int m_shift1;    
      int m_shift2;
      int m_shift3;
      
      int m_dot2shift;
      
      double m_level;      
      
   public:
  
      void CUniTrend(){
         m_handle1=INVALID_HANDLE;
         m_handle2=INVALID_HANDLE;
      }
      
      void ~CUniTrend(){
         if(m_handle1!=INVALID_HANDLE){
            IndicatorRelease(m_handle1);
         }
         if(m_handle2!=INVALID_HANDLE){
            IndicatorRelease(m_handle2);
         }        
      }
  
      virtual int Calculate( const int rates_total,
                     const int prev_calculated,
                     double & upBuffer[],
                     double & dnBuffer[]
      ){
         return(rates_total);
      }
      
      virtual bool Calculated(){
         return(false);
      }
      
      virtual bool CheckHandles(){
         return(true);
      }      
      
      string Name(){
         return(m_name);
      }    
      string Help(){
         return(m_help);
      }
            };

Na seção protected, são declaradas várias variáveis ​​auxiliares que serão úteis nas subclasses (também chamadas de classes filhas). No construtor, são inicializadas as variáveis ​​para os identificadores dos indicadores, enquanto, no destruidor, é realizada a liberação dos identificadores. Os outros métodos são virtuais.

Subclasse para a variante com um indicador:

class CUniTrend1:public CUniTrend{
   public:
      bool Calculated(){
         if(BarsCalculated(m_handle1)>0){
            return(true);
         }  
         else{
            return(false);
         }    
      }
      
      bool CheckHandles(){
         return(m_handle1!=INVALID_HANDLE);
      }
            };

Na classe há dois métodos reais, isto é: CheckHandle() — para verificar se foi possível carregar o indicador, e Calculated() — para saber se foi calculado completamente o indicador e se é possível atualizar o conteúdo dos buffers que refletem a tendência.

Subclasse para a variante com dois indicadores:

class CUniTrend2:public CUniTrend{
   public:
      bool Calculated(){
         if(BarsCalculated(m_handle1)>0 && BarsCalculated(m_handle2)>0){
            return(true);
         }  
         else{
            return(false);
         }    
      }      
      
      bool CheckHandles(){
         return(m_handle1!=INVALID_HANDLE && m_handle2!=INVALID_HANDLE);
      }
            };

Todas as classes com diferentes variantes de definição da tendência serão subclasses em relação à classe CUniTrend1 ou CUniTrend2. Consideremos uma subclasse:

class CUniTrend_ADX_PDIMDI:public CUniTrend1{
   private:  
   public:
  
      void CUniTrend_ADX_PDIMDI( bool use_default,
                                 bool keep_previous,
                                 SExtParams & par){
        
         // definição de parâmetros por padrão
        
         if(use_default){
            if(keep_previous){
               if(par.f_period1==PARAMETER_EMPTY)par.f_period1=14;
            }
            else{
               par.f_period1=14;
            }      
         }          
         // carregamento do indicador
         m_handle1=iADX(Symbol(),Period(),par.f_period1);
         // formação do nome do indicador e da cadeia de caracteres com dica sobre os parâmetros
         m_name=StringFormat( "iADX_PDIMDI(%i)",
                              par.f_period1
                            );
  
         m_help=StringFormat( "adx_period - f_period1(%i)",
                              par.f_period1
                            );
      }
      
      int Calculate( const int rates_total,
                     const int prev_calculated,
                     double & upBuffer[],
                     double & dnBuffer[]
      ){
         int start;
        
         if(prev_calculated==0){
            start=1;
         }
         else{
            start=prev_calculated-1;
         }
      
         for(int i=start;i<rates_total;i++){
        
            upBuffer[i]=EMPTY_VALUE;        
            dnBuffer[i]=EMPTY_VALUE;
        
            m_ci=rates_total-i-1;
            
            if(CopyBuffer(m_handle1,PLUSDI_LINE,m_ci,1,m_b1)==-1){
               return(0);
            }
            
            if(CopyBuffer(m_handle1,MINUSDI_LINE,m_ci,1,m_b2)==-1){
               return(0);
            }
            
            if(m_b1[0]>m_b2[0]){
               upBuffer[i]=1;
            }
            else if(m_b1[0]<m_b2[0]){
               dnBuffer[i]=-1;            
            }
            
         }      
      
         return(rates_total);
      }
            };

No construtor de classe, os principais locais base estão comentados, enquanto o método Calculate() é semelhante com a função padrão OnCalculate() do indicador, a criação do código para esta função é semelhante com a criação do código do indicador.

No apêndice do artigo, todas as classes dos indicadores estão localizadas no arquivo Include/UniTrend/UniTrendIndicators.mqh.

Agora que temos todas as classes, é possível criar um indicador simples para determinar a tendência, assim como fizemos nos artigos sobre o oscilador universal e o canal universal. O indicador pronto sem interface gráfica pode ser encontrado - no apêndice - no arquivo Indicators/iUniTrend.mq5.

Criação da GUI

Todas as classes da interface gráfica do usuário estão localizadas nos arquivos UniTrendForm.mqh e UniTrendControl.mqh. No arquivo UniTrendForm.mqh, está localizada a classe de formulário, enquanto, no arquivo UniTrendControl.mqh, as classes do controle universal para inserir os parâmetros dos indicadores. Não vale a pena considerar em detalhe a classe do formulário, uma vez que isto já foi visto nos artigos sobre a criação do oscilador universal e canal universal e examinado em detalhe no artigo Controles de gráfico personalizados. Parte 3. Formulários". Consideremos a criação do controle universal. 

A base do controle universal é a classe base CUniTrendControl. Na seção public da classe, estão localizados apenas os métodos virtuais, na seção protected, estão localizados alguns métodos auxiliares para trabalhar com listas suspensas, isto é: métodos para preencher listas usando variantes, e métodos para definir os pontos selecionados para as listas. Abaixo está o código de classe base com os comentários:

class CUniTrendControl{
   protected:
      
      /* Função de cálculo da alteração mínima do valor segundo
         o número de casas decimais para o parâmetro do nível
      */
      double SolveChange(int d){
         return(NormalizeDouble(1.0/pow(10,d),d));  
      }
      
      // preenchimento da lista usando variantes ENUM_MA_METHOD
      void AddVariantsMethod(CComBox & cb){
         for(int i=0;i<ArraySize(e_method);i++){
            cb.AddItem(EnumToString((ENUM_MA_METHOD)e_method[i]));
         }
      }
      
      // preenchimento da lista usando variantes ENUM_APPLIED_PRICE
      void AddVariantsPrice(CComBox & cb){
         for(int i=0;i<ArraySize(e_price);i++){
            cb.AddItem(EnumToString((ENUM_APPLIED_PRICE)e_price[i]));
         }
      }      
      
      // preenchimento da lista usando variantes ENUM_APPLIED_VOLUME
      void AddVariantsVolume(CComBox & cb){
         for(int i=0;i<ArraySize(e_volume);i++){
            cb.AddItem(EnumToString((ENUM_APPLIED_VOLUME)e_volume[i]));
         }
      }  
      
      // preenchimento da lista usando variantes ENUM_STO_PRICE     
      void AddVariantsStoPrice(CComBox & cb){
         for(int i=0;i<ArraySize(e_sto_price);i++){
            cb.AddItem(EnumToString((ENUM_STO_PRICE)e_sto_price[i]));
         }
      }      
      
      // obtenção do índice para ENUM_MA_METHOD  
      int MethodIndex(long val){
         for(int i=ArraySize(e_method)-1;i>=0;i--){
            if(e_method[i]==val){
               return(i);
            }
         }
         return(-1);
      }
      
      // obtenção do índice para ENUM_APPLIED_PRICE
      int PriceIndex(long val){
         for(int i=ArraySize(e_price)-1;i>=0;i--){
            if(e_price[i]==val){
               return(i);
            }
         }
         return(-1);
      }  
      
      // obtenção do índice para ENUM_APPLIED_VOLUME   
      int VolumeIndex(long val){
         for(int i=ArraySize(e_volume)-1;i>=0;i--){
            if(e_volume[i]==val){
               return(i);
            }
         }
         return(-1);
      }  
      
      // obtenção do índice para ENUM_STO_PRICE     
      int StoPriceIndex(long val){
         for(int i=ArraySize(e_sto_price)-1;i>=0;i--){
            if(e_sto_price[i]==val){
               return(i);
            }
         }
         return(-1);
      }      
      
   public:
      
      // inicialização dos controles
      virtual void Init(SExtParams & par){}
      
      // definição de valores
      virtual void SetValues(SExtParams & par){}      
      
      // obtenção de valores
      virtual void GetValues(SExtParams & par){}
      
      // exibição dos controles
      virtual void Show(int x,int y){}      
      
      // ocultamento dos controles
      virtual void Hide(){}      
      
      // número de controles pra o cálculo da altura do formulário
      virtual int ControlsCount(){
         return(0);
      }
      
      // manipulação de eventos
      virtual int Event(int id,long lparam,double dparam,string sparam){
         return(0);
      }
      
};
    

Consideremos uma subclasse para a variante para determinar a tendência segundo a linha do ADX e segundo o nível (dois controles):

class CUniTrendControl_ADX_Level: public CUniTrendControl{
   private:
  
      // ponteiro para os controles simples
      CSpinInputBox m_f_period1;
      CSpinInputBox m_f_level;
  
   public:
  
      // inicialização dos controles
      void Init(SExtParams & par){
         m_f_period1.Init("f_period1",SPIN_BOX_WIDTH,1," adx_period");
         m_f_period1.SetMinValue(1);
         m_f_period1.SetReadOnly(false);
         m_f_level.Init("f_level",COMBO_BOX_WIDTH,this.SolveChange(par.level_digits)," level");
         m_f_level.SetMinValue(0);
         m_f_level.SetReadOnly(false);
      }
  
      // definição de valores
      void SetValues(SExtParams & par){        
         m_f_period1.SetValue(par.f_period1);
         m_f_level.SetValue(par.f_level);
      }
  
      // obtenção de valores
      void GetValues(SExtParams & par){
         par.f_period1=(int)m_f_period1.Value();
         par.f_level=m_f_level.Value();
      }    
  
      // exibição dos controles
      void Show(int x,int y){
         m_f_period1.Show(x,y);
         y+=20;
         m_f_level.Show(x,y);
      }      
  
      // ocultamento dos controles
      void Hide(){
         m_f_period1.Hide();
         m_f_level.Hide();
      }
  
      // número de controles pra o cálculo da altura do formulário
      int ControlsCount(){
         return(2);
      }
  
      // manipulação de eventos dos controles
      int Event(int id,long lparam,double dparam,string sparam){
         int e1=m_f_period1.Event(id,lparam,dparam,sparam);
         int e2=m_f_level.Event(id,lparam,dparam,sparam);
         if(e1!=0 || e2!=0){
            return(1);
         }
         return(0);
      }
};
    

Uma variável do tipo SExtParams é transferida para os métodos SetValues() e GetValues(), em cada subclasse são utilizados apenas os campos necessários. É preciso definir a mudança mínima para o controle, isto é feito ao inicializar o controle, é por isto que a estrutura com parâmetros também é transferida para o método Init(). Em geral, a criação de subclasses atende a todos os princípios de criação de controles descritos no artigo Controles de gráfico personalizados. Parte 1. Criação do elemento de controle, exceto que, neste caso, não serão criados todos os métodos, mas sim apenas os necessários. 

Adição da interface gráfica do usuário ao indicador

Esta fase de criação é muito semelhante à fase correspondente durante a criação de um indicador universal de tendência e ao criar um canal universal. Consideremos apenas as diferenças.

Anteriormente, quando o indicador funcionava usando valores por padrão (UseDefault=true), todos os parâmetros inicializavam usando valores -1. Agora, tal varitante não é uma opção, porque o parâmetro do nível - para alguns indicadores - pode ser negativo. Portanto, a inicialização das variáveis é realizada utilizando os valores da constante PARAMETER_EMPTY declarada no arquivo UniTrendDefines.mqh. A constante tem o valor INT_MAX (valor que está fora dos valores reais dos níveis).

Existe outra pequena diferença na função OnTimer(), isto é: para verificar se o indicador está calculado, é chamado o método Calculated(), porque, para algumas variantes de tendência, é necessário verificar um indicador, enquanto, para outras, dois. Isto pode ser sabido apenas dentro da classe do indicador.

Como resultado obtemos mais um indicador universal muito conveniente (Fig. 10).

Fig. 10. Indicador universal com interface gráfica do usuário
Fig. 10. Indicador universal com interface gráfica do usuário

Repare que, além de exibir o nome da variante selecionada na lista no formulário, o tipo de indicador a ser usado é exibido na sub-janela do indicador no canto superior esquerdo. Não apenas é exibido o tipo, mas também os valores de todos os parâmetros (entre parênteses). Se o valor de nível for definido em pontos, será registrada a expressão do valor real do nível (Fig. 11).

 
Fig. 11. Exibição do parâmetro a ser definido em pontos

É possível encontrar o indicador pronto no apêndice, o nome do arquivo é Indicators/iUniTrendGUI.mq5.  

Conclusão 

No total, o indicador inclui 46 opções diferentes para definir a tendência. Uma interface gráfica que permite tanto mudar rapidamente os parâmetros dos indicadores e seus tipos, quanto explorar convenientemente o histórico. A presença de uma função de notificação faz com que o indicador seja viável para um uso prático real.

Uma nova abordagem na criação de uma interface gráfica tem as suas vantagens e os seus inconvenientes. Entre os inconvenientes pode ser observado o grande volume de código e, portanto, maior volume de trabalho. Ao contrário das classe que gerenciam a visibilidade dos controles (como no oscilador universal e o canal universal), neste caso, para cada variante de definição da tendência, foi criado um controle completo. No entanto, uma separação e uma independência mais claras entre o código que faz parte do controle e o de código que faz parte do formulário simplificaria consideravelmente o desenvolvimento, bem como expansão futura do indicador, se necessário.

Anexo

O apêndice inclui uma pasta com todos os arquivos necessários. Todos eles estão organizados por pastas de mesma forma como eles têm de ser colocados no terminal. 

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

Arquivos anexados |
files.zip (31.13 KB)
Interfaces Gráficas X: Atualizações para a tabela Renderizada e otimização do código (build 10) Interfaces Gráficas X: Atualizações para a tabela Renderizada e otimização do código (build 10)

Nós continuamos a complementar a tabela renderizada (CCanvasTable) com novas funcionalidades. A tabela terá agora: o realce das linhas quando o mouse estiver em cima; possibilidade de adicionar um array de ícones para cada célula e um método para trocá-los; possibilidade de definir ou modificar o texto da célula durante a execução do programa, e muito mais.

Padrões disponíveis para negociação de cestas de moedas. Parte II Padrões disponíveis para negociação de cestas de moedas. Parte II

Continuação da conversa sobre padrões que podem ser detectados pelo trader ao operar pares de moedas. Esta parte descreve os padrões formados durante o uso combinado de indicadores de tendência. Como ferramentas de análise são usados indicadores construídos com base num índice de moeda.

Receitas MQL5 - sinais de negociação de pivô Receitas MQL5 - sinais de negociação de pivô

No artigo, é apresentado o processo de desenvolvimento e implementação de uma classe-robô de sinais com base em pivôs, isto é, níveis de reversão. Com base nesta classe é construída uma estratégia usando a Biblioteca padrão. São consideradas as possibilidades de desenvolver uma estratégia de pivôs adicionando filtros.

Os Expert Advisors prontos a partir do Assistente MQL5 funcionam no MetaTrader 4 Os Expert Advisors prontos a partir do Assistente MQL5 funcionam no MetaTrader 4

No artigo, propõe-se um emulador simples do ambiente de negociação MetaTrader 5 para o MetaTrader 4. Com sua ajuda é possível transferir e adaptar as classes de negociação da biblioteca padrão. Como resultado, os EAs gerados no Assistente do MetaTrader 5 podem ser compilados e executados sem alterações no MetaTrader 4.