Autor Original:
Witold Wozniak
O indicador Cycle Period é uma ferramenta projetada para medir a periodicidade das mudanças de preço de um ativo financeiro. Ele armazena os valores do ciclo de mercado atual em seu buffer, que, por razões óbvias, nunca são estáveis. Esse indicador é ideal para ser utilizado em conjunto com os osciladores, permitindo que se adaptem aos ciclos de mercado que estão em constante mudança.
A criação desse indicador foi inspirada no artigo de John Ehlers "Using The Fisher Transform", publicado em novembro de 2002 na revista "Technical Analysis Of Stock & Commodities".

Para que o indicador CyclePeriod funcione corretamente em outros códigos de indicadores (por exemplo, no oscilador RVI), é necessário declarar sua variável de handle em um nível global:
//---- declaração de variáveis inteiras para os handles dos indicadores int CP_Handle;
Logo em seguida, o handle do indicador CyclePeriod deve ser obtido no bloco de inicialização do indicador RVI:
//---- obtendo o handle do indicador CyclePeriod CP_Handle=iCustom(NULL,0,"CyclePeriod",Alpha); if(CP_Handle==INVALID_HANDLE) { Print(" Falha ao obter o handle do indicador CyclePeriod"); return(1); }
Agora, temos a nova variável Alpha, que serve como parâmetro de entrada do indicador utilizado e a razão de suavização do período. Essa variável precisa ser transformada no parâmetro de entrada do indicador desenvolvido.
//+----------------------------------------------+ //| Parâmetros de entrada do indicador | //+----------------------------------------------+ input double Alpha=0.07; // Razão de suavização do indicador
O parâmetro de entrada Length deve ser removido da lista de parâmetros de entrada, transformando-o em uma variável local dentro da função OnCalculate().
O tamanho dos arrays utilizados para a suavização do indicador é fixado pelo valor do parâmetro Length:
//---- Distribuição de memória para os arrays de variáveis ArrayResize(Count,Length); ArrayResize(Value1,Length); ArrayResize(Value2,Length);
O valor deste parâmetro está mudando agora. Portanto, é melhor definir o tamanho desses arrays para não ser menor que o valor máximo previsto para essa variável.
Ao analisar os gráficos do indicador, podemos ver que esse valor não ultrapassa 100. Assim, os tamanhos dos arrays terão o mesmo valor:
//---- Distribuição de memória para os arrays de variáveis ArrayResize(Count,MAXPERIOD); ArrayResize(Value1,MAXPERIOD); ArrayResize(Value2,MAXPERIOD);
Além disso, os valores de período para a barra atual no bloco OnCalculate() devem ser obtidos do buffer do indicador personalizado CyclePeriod para que possam ser usados no lugar do antigo parâmetro de entrada Length.
//---- loop principal de cálculo do indicador for(bar=first; bar<rates_total && !IsStopped(); bar++) { //---- copiar os dados que apareceram recentemente para o array if(CopyBuffer(CP_Handle,0,rates_total-1-bar,4,period)<=0) return(RESET); Length=int(MathFloor((4.0*period[0]+3.0*period[1]+2.0*period[2]+period[3])/20.0)); if(bar<Length) Length=bar; // cortando a suavização para o número real de barras }
Nesse caso, os quatro últimos valores são retirados do buffer do indicador CyclePeriod e sua suavização linearmente ponderada é realizada. O valor obtido é então utilizado como período de suavização Length. Por fim, a linha no final do código do indicador deve ser alterada:
if(bar<rates_total-1) Recount_ArrayZeroPos(Count,MAXPERIOD);
Como resultado, obtemos o oscilador Adaptive RVI:

Publicações relacionadas
- Calendário Econômico: Monitoramento e Cache para Testes de Estratégia no MetaTrader 5
- Buffers Horários para Coleta de Dados no MetaTrader 5
- Utilitário de Informações de Séries e Taxas para MetaTrader 5: Maximize Seu Trading
- Utilitário de Informações de Barras e Taxas: Como Usar no MetaTrader 5
- Índice de Caminhada Aleatória: Um Indicador Essencial para MetaTrader 5