English Русский 中文 Español Deutsch 日本語 한국어 Français Italiano Türkçe
Moving Mini-Max: um Novo Indicador para a Análise Técnica e sua Implementação no MQL5

Moving Mini-Max: um Novo Indicador para a Análise Técnica e sua Implementação no MQL5

MetaTrader 5Exemplos | 12 fevereiro 2014, 13:23
4 074 6
investeo
investeo

Introdução

Há uma ciência, chamada finança quantitativa que permite estudar os modelos de precificação de derivativos financeiros, utilizando os métodos da física teórica e matemática.

Recentemente me deparei com um artigo que descreve um novo indicador para análise técnica que combina ideias da física quântica e leva-as ao financiamento. Eu tive interesse nele e decidi que iria ensinar como implementar indicadores baseados em artigos científicos em MQL5.

O artigo Moving Mini-Max [2] original é escrito por ZK. Silagadze é um físico quântico do Instituto Budker de Física Nuclear e da Universidade do Estado de Novosibirsk. A ligação para o artigo, bem como o código fonte MQL5 estão disponíveis no final do artigo.


Indicador

Nunca esperei que eu escrevesse essa frase, mas aqui eu vou explicar o tunelamento quântico. Supondo que a maioria dos leitores não sejam profissionais quânticos, irei descrevê-lo em termos simples, espero que você não se sinta ofendido. Em primeiro vamos definir em uma frase a ideia por trás da análise técnica das séries temporais financeiras. Estamos principalmente olhando para encontrar:

  • níveis de suporte e resistência dos preços;
  • direção das tendências de curto e longo prazo;
  • topos e bases das tendências.

A ideia original do indicador Moving Mini-Max é encontrar topos e bases no gráfico usando o análogo da partícula alfa quântica que tenta escapar de um núcleo. O problema é tomado a partir da teoria de desintegração alfa por George Gamov [1].

Uma imagem vale mais do que mil palavras, por isso, estou colando um pequeno gráfico abaixo.

Fig.1 Bola quântica imaginária no gráfico de séries temporais

Figura 1. Bola quântica imaginária no gráfico de preço forex

Imagine uma bola lançada a partir do topo da colina ou, no nosso caso, a partir de um topo recente no gráfico das séries temporais. Na mecânica clássica ela irá saltar os obstáculos e pode não ter a chance de parar na frente do obstáculo principal, uma vez que pode se prender em algum lugar no caminho.

Mas, de acordo com a mecânica quântica e a teoria da desintegração alfa, uma bola pode ter uma probabilidade muito pequena, mas diferente de zero, de tunelamento através das barreiras encontrando o seu caminho para o potencial inferior e oscilar lá.

Esta é uma analogia de encontrar um local mínimo na tabela de preços. O artigo por Z.K. Silagadze [2], propõe que, a fim de reduzir a complexidade de cálculo, em vez de resolver o verdadeiro problema de mecânica quântica ele é suficiente para imitar o comportamento quântico. Vou apresentar uma base matemática, que é apresentada no artigo original e, posteriormente, a implementação em MQL5.

Vamos ser uma série de preços para alguma janela de tempo. O Moving Mini-Max é uma transformação não linear das séries de preços:

uSi

onde e para é definido como segue:

Como você pode ver esta é uma relação recorrente, isto é, o elemento i-th é dependente do elemento i-1. As séries de moving mini-max satisfazem a condição de normalização, em que a soma de todos os elementos é igual a um

As probabilidades de tunelamento de uma bola quântica são chamadas de probabilidades de transição, porque suas probabilidades modelos de atravessar barreiras estreitas dos obstáculos pequenos imaginários da série de preços descendente:


com

O parâmetro m é uma abertura da janela de uniformização que imita a massa (inversa) da bola quântica e a sua capacidade de passar através de pequenos obstáculos. Alternativamente o moving mini-max d(si) que enfatiza máximos locais pode ser construído colocando o sinal negativo no parâmetro transmitido para a função exp():


Implementação

Depois de ler sobre a matemática por trás do indicador, podemos implementá-lo em MQL5. A fim de fazê-lo da melhor forma é preciso olhar a partir da última equação para cima. Se você prestar atenção as variáveis ​m e n, você vai ver que este indicador necessita da matriz elemento n+2m da série de preço para uma janela mini-max e terá tamanho lag das barras m.

Isto é por causa do indicador S i+K e S i-k no cálculo das variáveis​ Q. A variável i é incrementada a partir da 1 para n e k na incrementação a partir da 1 para m, portanto, vamos precisar do buffer n+2 m para começar. Isto pode ser alcançado ligando:

double S[];
ArrayResize(S,n+2*m);
CopyClose(Symbol(),0,0,n+2*m,S);
    

Isso irá declarar matriz de duplas, redimensioná-la para n+2m e copiar valores próximos das últimos barras n+2m da tabela de símbolos atual de partida a partir da última barra.

O próximo passo é calcular valores de Q. Se você ler atentamente a definição você vai ver que para o elemento i-th da série de preços analisados​ precisamos somar os resultados m da função exp() com as variáveis dos valores​dos preços. Portanto, precisamos fazer um ciclo de 1 a n, que vai contar todos os valores de Q:

void calcQii()
  {
   int i,k;

   for(i=0; i<n; i++)
     {
      double sqiip1=0;
      double sqiim1=0;
      double dqiip1=0;
      double dqiim1=0;

      for(k=0; k<m; k++)
        {
         sqiip1 += MathExp(2*(S[m-1+i+k]-S[i])/(S[m-1+i+k]+S[i]));
         sqiim1 += MathExp(2*(S[m-1+i-k]-S[i])/(S[m-1+i-k]+S[i]));

         dqiip1 += MathExp(-2*(S[m-1+i+k]-S[i])/(S[m-1+i+k]+S[i]));
         dqiim1 += MathExp(-2*(S[m-1+i-k]-S[i])/(S[m-1+i-k]+S[i]));       
        }
      sQiip1[i] = sqiip1;
      sQiim1[i] = sqiim1;
      dQiip1[i] = dqiip1;
      dQiim1[i] = dqiim1;

     }
  }
      

Como você pode observar a função calcQii calcula i-th Q e valores de Q ' para a janela de preço observada de tamanho n. A matriz S contém os valores de preços e sQiip1, sQiim1, dQiip1, dQiim1 são usados como variáveis de cálculos intermediários de Q e Q '.

As probabilidades são calculadas com base em variáveis​Q e Q ', portanto, podemos fazer uma outra função que faz um ciclo de 1 a n através das matrizes sQii e dQii:

void calcPii()
  {
   int i;

   for(i=0; i<n; i++)
     {
      sPiip1[i] = sQiip1[i] / (sQiip1[i] + sQiim1[i]);
      sPiim1[i] = sQiim1[i] / (sQiip1[i] + sQiim1[i]);
      dPiip1[i] = dQiip1[i] / (dQiip1[i] + dQiim1[i]);
      dPiim1[i] = dQiim1[i] / (dQiip1[i] + dQiim1[i]);
     }
  }
      

O que resta é calcular uSi e elementos sSi posteriores e colocar os resultados nas matrizes USI e DSi

void calcui()
  {
   int i;

   sui[0] = 1;
   dui[0] = 1;

   for(i=1; i<n; i++) 
     {
      sui[i] = (sPiim1[i]/sPiip1[i])*sui[i-1];
      dui[i] = (dPiim1[i]/dPiip1[i])*dui[i-1];
     }

   double uSum = 0;
   double dSum = 0;

   ArrayInitialize(uSi, 0.0);
   ArrayInitialize(dSi, 0.0);
   
   for(i=0; i<n; i++) { uSum+=sui[i]; dSum+=dui[i]; }
   for(i=0; i<n; i++) { uSi[n-1-i] = sui[i] / uSum; dSi[n-1-i] = dui[i] / dSum; }
 
   }

A fim de verificar se a condição de normalização é válida, pode-se adicionar as seguintes linhas:

   double result=0;
   for(i=0; i<n; i++) { /* Print("i = "+i+" uSi = "+uSi[i]); */ result+=uSi[i]; }

   Print("Result = "+ DoubleToString(result));
      

Depois que todos os cálculos foram feitos, precisamos exibi-los dentro da janela do indicador. A fim de fazê-lo, deve-se declarar pelo menos dois buffers indicadores, um para uSi e outro para matriz dSi e definir o tipo de indicador como DRAW_LINE.

    #property indicator_separate_window

    #property indicator_buffers 2
    #property indicator_plots 2
    #property indicator_type1 DRAW_LINE
    #property indicator_type2 DRAW_LINE
    #property indicator_color1 SeaGreen
    #property indicator_color2 BlueViolet

Então, chamando a função SetIndexBuffer() atribuímos as matrizes uSi e dSi a serem exibidas como INDICATOR_DATA:

   SetIndexBuffer(0,uSi,INDICATOR_DATA);
   SetIndexBuffer(1,dSi,INDICATOR_DATA);

   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);

   PlotIndexSetInteger(0,PLOT_SHIFT,-(m-1));
   PlotIndexSetInteger(1,PLOT_SHIFT,-(m-1));

Fig.2 Indicador moving mini-max

Figura 2. Indicador Moving Mini-Max Implementado

Uma das possíveis aplicações do indicador descrito no artigo é identificar as linhas de suporte e resistência e a identificação de padrões gráficos por uniformização inerente do indicador. Quanto às linhas de suporte e resistência elas são formadas pelo cruzamento do moving mini-max das séries de preços e moving mini-max de sua média móvel.

Se o preço passa pelo máximo local e cruza a média móvel temos uma resistência. Depois de implementá-lo, vi que o método está sofrendo de alguns sinais falsos, mas estou colando um código fonte de referência sobre como colocar as linhas em MQL5 usando a biblioteca ChartObjectsLines.mqh:

void SR()
{
   // if price goes through local maximum and crosses a moving average draw resistance
   int i, cnt=0;
   int rCnt=CopyClose(Symbol(),0,0,n+2*m,S);
      
   for (i=n-2; i>=0; i--)
      if (uSi[i]<uSi_MA[i] && uSi[i+1]>=uSi_MA[i+1]) 
      {
      Print("Resistance at " + i);
      CChartObjectHLine *line=new CChartObjectHLine();
      line.Create(0, "MiniMaxResistanceLine:"+IntegerToString(cnt), 0, S[i]);
      line.Color(LightSkyBlue);
      line.Width(1);
      line.Background(true);
      line.Selectable(false);
      cnt++;
      }
   // if price goes through local minimum and crosses a moving average draw support

   for (i=n-2; i>=0; i--)
      if (dSi[i]<dSi_MA[i] && dSi[i+1]>=dSi_MA[i+1]) 
      {
      Print("Support at " + i);
      CChartObjectHLine *line=new CChartObjectHLine();
      line.Create(0, "MiniMaxSupportLine:"+IntegerToString(cnt), 0, S[i]);
      line.Color(Tomato);
      line.Width(1);
      line.Background(true);
      line.Selectable(false);
      cnt++;
      }
}
      

O fato interessante do indicador é que eu vi que ele reconhece muito bem locais mínimos de curta tendência e máximo para uma determinada janela de tempo. é o suficiente para filtrar a diferença entre as maiores e as menores leituras do moving mini-maxes e marcá-las como um início de uma subida de preços de curto prazo ou tendência.

Podemos explorar esse comportamento de acordo com outros indicadores e gestão de dinheiro para fazer um Expert Advisor rentável.

Para marcar as maiores leituras sobre a janela do tempo atual, podemos usar buffers indicadores adicionais para exibir as setas para cima e para baixo cada vez que a diferença for maior. Além disso, para tornar o indicador mais atraente eu decidi usar o novo recurso do MQL5: um histograma de cores. A baixa e alta tendências são coloridas em cores diferentes, e a mudança da tendência é sinalizada por uma barra amarela.

Para utilizar o histograma de cores entre dois buffers devemos usar dois buffers de dados e um buffer para os índices de cor. Por favor, observe como definir planos. Existem cinco buffers indicadores no total, e três cores são definidas para o histograma de cores.

//+------------------------------------------------------------------+
//|                                                MovingMiniMax.mq5 |
//|                                      Copyright 2011, Investeo.pl |
//|                                               http://Investeo.pl |
//+------------------------------------------------------------------+
#property copyright   "Copyright 2011, Investeo.pl"
#property link        "http://Investeo.pl"

#property description "Moving Mini-Max indicator"
#property description "proposed by Z.K. Silagadze"
#property description "from Budker Institute of Nuclear Physics"
#property description "and Novosibirsk State University"
#property description "Original paper can be downloaded from:"
#property description "http://arxiv.org/abs/0802.0984"

#property version     "0.6"
#property indicator_separate_window

#property indicator_buffers 5
#property indicator_plots 3

#property indicator_type1 DRAW_COLOR_HISTOGRAM2
#property indicator_type2 DRAW_ARROW
#property indicator_type3 DRAW_ARROW

#property indicator_color1 Chartreuse, OrangeRed, Yellow
#property indicator_color2 RoyalBlue
#property indicator_color3 RoyalBlue

#property indicator_width1 5
#property indicator_width2 4
#property indicator_width3 4

Por favor, note que histograma leva dois buffers do tipo INDICATOR_DATA e um INDICATOR_COLOR_INDEX. Os buffers devem ser configurados com precisão na seguinte ordem, os buffers de dados vem em primeiro lugar, depois de que um buffer do índice de cor é definido.

   SetIndexBuffer(0,uSi,INDICATOR_DATA);
   SetIndexBuffer(1,dSi,INDICATOR_DATA);
   SetIndexBuffer(2,trend,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(3,upArrows,INDICATOR_DATA);
   SetIndexBuffer(4,dnArrows,INDICATOR_DATA);
   
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0);
   
   PlotIndexSetInteger(1,PLOT_ARROW,234);
   PlotIndexSetInteger(2,PLOT_ARROW,233); 

Buffers 0,1,2 são para histograma de cores, buffers 3 e 4 são para exibição seta.

O algoritmo de coloração é como se segue:

   if (upind<dnind) 
    { 
      for (i=0; i<upind; i++) trend[i]=0;
      for (i=upind; i<dnind; i++) trend[i]=1;
      for (i=dnind; i<n; i++) trend[i]=0 ;
    } else
    {
      for (i=0; i<dnind; i++) trend[i]=1;
      for (i=dnind; i<upind; i++) trend[i]=0;
      for (i=upind; i<n; i++) trend[i]=1;
   }
   
   trend[upind] = 2;
   trend[dnind] = 2;
      

Estou colando a imagem do resultado final:

Figura 2. Versão final do indicador do Moving Mini-Max

Figura 3. Versão final do indicador do Moving Mini-Max

é preciso lembrar que os valores de tendência baixa e alta são calculados para uma determinada janela de tempo cada vez que chega uma nova barra, esta é a razão para chamar o indicador moving mini-max.

Embora ele retarde as barras m dá surpreendentemente boa visão para a tendência da janela de tempo atual e interpretação de como o mercado 'respira'.

Estou convencido de que este indicador pode ser rentável.

Conclusão

Eu apresentei a matemática por trás de um novo indicador para a análise técnica e sua implementação em MQL5.

O artigo original por Z.K. Silagadze está disponível em http://arxiv.org/abs/0802.0984. O código fonte em anexo está disponível para download.

Espero apresentar indicadores técnicos mais interessantes e sua implementação MQL5 no futuro.

Referências:

1. G.Gamov, Theory of alpha decay.
2. Z.K. Silagadze, Moving Mini-Max - a new indicator for technical analysis.

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

Arquivos anexados |
movingminimax.mq5 (7.34 KB)
Últimos Comentários | Ir para discussão (6)
Danilo Coscioni
Danilo Coscioni | 2 abr 2016 em 16:09
Muito Interessante. Obrigado por compartilhar com tal detalhamento
Ethos Trader
Ethos Trader | 24 mar 2021 em 22:38
The current version of Metatrader 5 does not support this indicator. I ask to evaluate the possibility of a new update. Grateful.
Roberto_Ev
Roberto_Ev | 7 nov 2021 em 18:40

Ethos Trader  O código do Moving Mini-Max está funcionado sim, mas deve fazer uma correção a partir da linha 225:


//|    -----   Erro: Foi substituido pelas linhas a baixo   -----    |

//|   double result=0;
//|****  Original:    for(i=0; i<n; i++) { Print("i = "+i+" uSi = "+uSi[i]);  result+=uSi[i]; }
//|    ----------------------------------------------------------    |

   double result=0;
     for(i=0; i<n; i++) // Desliguei isso  --- >>  { Print("i = "+(string)i+" uSi = "+(string)uSi[i]);  result+=uSi[i]; }


   // Desliguei isso  --- >> Print("Result = "+DoubleToString(result));
   
  }


Helio Precinoti
Helio Precinoti | 4 fev 2022 em 12:13
Meus parabéns pelo trabalho.
Estou testando o indicador e ele aparece para todos os ativos que exceto para o índice, seja cheio, mini ou do contrato corrente. Alguma sugestão sobre o que ocorre ou como devo proceder para que apareça o indicador para o índice?
Obrigado.
andrenduarte
andrenduarte | 11 mar 2022 em 16:53
Helio Precinoti #:
Meus parabéns pelo trabalho.
Estou testando o indicador e ele aparece para todos os ativos que exceto para o índice, seja cheio, mini ou do contrato corrente. Alguma sugestão sobre o que ocorre ou como devo proceder para que apareça o indicador para o índice?
Obrigado.
Encontrou alguma solução? O indicador realmente parece muito interessante, reprinta algumas vezes, mas é bem fiel
O jogador de negociação baseado no histórico de acordo O jogador de negociação baseado no histórico de acordo
O reprodutor de negócio. Apenas quatro palavras, não há necessidade de explicação. Pensamentos sobre uma pequena caixa com botões vêm à mente. Pressione um botão - ele reproduz, move a alavanca - a velocidade da reprodução muda. Na realidade, é bastante similar. Neste artigo, quero mostrar meu desenvolvimento que reproduz o histórico de negócio quase como em tempo real. O artigo cobre algumas nuances de OOP, trabalhando com indicadores e gráficos de gerenciamento.
Conectando NeuroSolutions Neuronets Conectando NeuroSolutions Neuronets
Além da criação de neuronets, o suite de software NeuroSolutions permite exportá-los como DLLs. Este artigo descreve o processo de criação de um neuronet, gerando um DLL e conectando-o a um Expert Advisor para negociação no MetaTrader 5.
Gráficos e diagramas em HTML Gráficos e diagramas em HTML
Hoje é difícil encontrar um computador que não tenha um WEB-browser instalado. Por um longo tempo os browsers têm evoluído e melhorado. Este artigo discute o modo simples e seguro de criar gráficos e diagramas, com base nas informações obtidas a partir do terminal de cliente MetaTrader 5 para exibí-los no navegador.
A Implementação de um Modo Multi-currency (múltiplas moedas) no MetaTrader 5 A Implementação de um Modo Multi-currency (múltiplas moedas) no MetaTrader 5
Por um longo tempo a análise de várias moedas e negociação de várias moedas foi de interesse das pessoas. A oportunidade para implementar um regime de várias moedas completo tornou-se possível apenas com o lançamento público do MetaTrader 5 e a linguagem de programação MQL5. Neste artigo, propomos um modo para analisar e processar todos os ticks de entrada para diversos símbolos. Como ilustração, vamos considerar um indicador RSI de várias moedas do índice de dólar USDx.