English Русский 中文 Español Deutsch 日本語
preview
Construção de um modelo de restrição de tendência de velas (Parte 1): Para EAs e indicadores técnicos

Construção de um modelo de restrição de tendência de velas (Parte 1): Para EAs e indicadores técnicos

MetaTrader 5Negociação |
204 0
Clemence Benjamin
Clemence Benjamin

Conteúdo

  1. Introdução
  2. Anatomia das velas de timeframes superiores
  3. Desenvolvimento de estratégia (cruzamento de médias móveis) com código
  4. Justificativa e aplicação da restrição, incluindo código
  5. Vantagens do uso do código
  6. Considerações finais


    Introdução

    O caráter altista ou baixista das velas em timeframes mais elevados pode fornecer informações valiosas sobre a direção do mercado. Essa análise pode ser uma alternativa ao uso de médias móveis para identificar tendências de mercado. Por exemplo, uma vela diária (D1) ou de quatro horas (H4) reflete uma atividade fundamental significativa que ocorre em timeframes mais curtos, como M1 ou até mesmo em ticks. Traders podem se beneficiar aproveitando oportunidades de compra oferecidas por velas altistas em D1 e de venda durante as fases baixistas. A combinação com indicadores técnicos em timeframes mais curtos ajuda a definir pontos de entrada precisos, proporcionando uma vantagem estratégica aos traders. Ao trabalhar com uma vela diária altista, os traders devem esperar pacientemente até que as condições de mercado sejam favoráveis, antes de seguirem a tendência com segurança.

    O objetivo deste artigo é classificar de maneira eficaz a vela atual como altista ou baixista, usando código em MQL5 que estabelece a condição de venda somente em caso de vela baixista e compra em caso de vela altista.

    A finalidade deste modelo é limitar o gerador de sinais para emitir sinais que estejam conforme a tendência atual da vela. Isso pode ser comparado a uma cerca, que impede certos "animais" de entrarem em seu quintal com base no tamanho, mas permite a passagem de outros. Aplicamos um conceito semelhante para filtrar os sinais selecionados e manter apenas os mais otimizados. O modelo analisa velas e tendências de mercado em timeframes superiores, criando uma barreira virtual que permite apenas os sinais compatíveis com a tendência predominante. Essa filtragem seletiva aumenta a precisão e confiabilidade dos sinais gerados, garantindo que o usuário receba apenas as oportunidades de negociação mais vantajosas.

    Ao final deste artigo, você será capaz de:

    1. Estudar o movimento de preços em uma vela diária (D1) usando timeframes mais curtos.
    2. Criar um buffer de indicador para cruzamento de médias móveis, que inclui uma condição de restrição de tendência em timeframes superiores.
    3. Compreender o conceito de seleção dos melhores sinais em uma estratégia específica.

    Anatomia das velas de timeframes superiores

    Índice Boom 500, anatomia de uma vela D1 em M5, 13.04.24

    Fig. 1.1. Anatomia de uma vela D1 no timeframe M5 para o índice sintético Boom 500

    A imagem acima mostra uma faixa vermelha da vela D1 à esquerda e a ação do preço em M5 à direita entre os separadores de períodos diários. Observa-se um claro movimento descendente, sustentado pelo caráter baixista da vela diária, o que indica uma maior probabilidade de operações de venda. Nesta configuração, dá-se atenção especial à execução de ordens alinhada com a vela D1, refletindo a ideia de limitação com base na tendência de timeframes superiores.

    Desenvolvimento de estratégia (cruzamento de médias móveis)

    O desenvolvimento de uma estratégia de negociação exige uma combinação de análise, testes e aprimoramento contínuo. Uma estratégia de sucesso deve se basear em uma compreensão profunda do mercado, assim como em um conjunto claro de regras e diretrizes a seguir. É essencial monitorar e ajustar a estratégia conforme as condições do mercado mudam, a fim de se adaptar a novas tendências e oportunidades. Ao analisar dados constantemente, testar diferentes abordagens e ajustar conforme necessário, os traders podem aumentar suas chances de sucesso no mercado.

    Antes de abordarmos a estratégia de cruzamento de médias móveis, vamos resumir as principais dicas para o desenvolvimento de uma estratégia:

    1. Defina seus objetivos e tolerância ao risco
    2. Entenda o mercado
    3. Escolha seu estilo de negociação  
    4. Defina regras de entrada e saída  
    5. Implemente estratégias de gestão de riscos
    6. Teste a estratégia com dados históricos
    7. Otimize-a
    8. Faça trades simulados antes de operar com dinheiro real
    9.  Monitore e avalie
      Desenvolveremos um indicador básico de cruzamento de médias móveis, que exibirá uma seta e enviará uma notificação sempre que ocorrer o cruzamento. Abaixo estão as etapas dos critérios para desenvolver nossa estratégia.
      1. Estabeleça as condições da estratégia (neste caso, o cruzamento da EMA7 acima ou abaixo da EMA21)
      2. Defina o estilo de exibição do indicador, que pode ser uma seta ou qualquer figura geométrica disponível no MetaTrader 5.
      3. (Opcional) Se o indicador for configurável pelo usuário, defina as variáveis de entrada

      Decidi incluir o código final aqui sem explicações detalhadas, para focar no algoritmo de restrição — tema principal desta análise. O programa a seguir está pronto para compilação e geração de sinais de compra e venda. A seguir, analisaremos os resultados no gráfico e identificaremos o problema que o algoritmo de restrição pretende resolver.

      //Indicator Name: Trend Constraint
      #property copyright "Clemence Benjamin"
      #property link      "https://mql5.com"
      #property version   "1.00"
      #property description "A model that seek to produce sell signal when D1 candle is Bearish only and  buy signal when it is Bullish"
      
      //--- indicator settings
      #property indicator_chart_window
      #property indicator_buffers 2
      #property indicator_plots 2
      
      #property indicator_type1 DRAW_ARROW
      #property indicator_width1 5
      #property indicator_color1 0xFFAA00
      #property indicator_label1 "Buy"
      
      #property indicator_type2 DRAW_ARROW
      #property indicator_width2 5
      #property indicator_color2 0x0000FF
      #property indicator_label2 "Sell"
      
      #define PLOT_MAXIMUM_BARS_BACK 5000
      #define OMIT_OLDEST_BARS 50
      
      //--- indicator buffers
      double Buffer1[];
      double Buffer2[];
      
      double myPoint; //initialized in OnInit
      int MA_handle;
      double MA[];
      int MA_handle2;
      double MA2[];
      double Low[];
      double High[];
      
      void myAlert(string type, string message)
        {
         if(type == "print")
            Print(message);
         else if(type == "error")
           {
            Print(type+" | Trend constraint @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
           }
         else if(type == "order")
           {
           }
         else if(type == "modify")
           {
           }
        }
      
      // Custom indicator initialization function                         
      int OnInit()
        {   
         SetIndexBuffer(0, Buffer1);
         PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(0, PLOT_ARROW, 241);
         SetIndexBuffer(1, Buffer2);
         PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(1, PLOT_ARROW, 242);
         //initialize myPoint
         myPoint = Point();
         if(Digits() == 5 || Digits() == 3)
           {
            myPoint *= 10;
           }
         MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_EMA, PRICE_CLOSE);
         if(MA_handle < 0)
           {
            Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle2 = iMA(NULL, PERIOD_CURRENT, 21, 0, MODE_EMA, PRICE_CLOSE);
         if(MA_handle2 < 0)
           {
            Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         return(INIT_SUCCEEDED);
        }
      
      //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[])
        {
         int limit = rates_total - prev_calculated;
         //--- counting from 0 to rates_total
         ArraySetAsSeries(Buffer1, true);
         ArraySetAsSeries(Buffer2, true);
         //--- initial zero
         if(prev_calculated < 1)
           {
            ArrayInitialize(Buffer1, EMPTY_VALUE);
            ArrayInitialize(Buffer2, EMPTY_VALUE);
           }
         else
            limit++;
         
         if(BarsCalculated(MA_handle) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
         ArraySetAsSeries(MA, true);
         if(BarsCalculated(MA_handle2) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);
         ArraySetAsSeries(MA2, true);
         if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
         ArraySetAsSeries(Low, true);
         if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
         ArraySetAsSeries(High, true);
         //--- main loop
         for(int i = limit-1; i >= 0; i--)
           {
            if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
            
            //Indicator Buffer 1
            if(MA[i] > MA2[i]
            && MA[i+1] < MA2[i+1] //Moving Average crosses above Moving Average
            )
              {
               Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
              }
            else
              {
               Buffer1[i] = EMPTY_VALUE;
              }
            //Indicator Buffer 2
            if(MA[i] < MA2[i]
            && MA[i+1] > MA2[i+1] //Moving Average crosses below Moving Average
            )
              {
               Buffer2[i] = High[i]; //Set indicator value at Candlestick High
              }
            else
              {
               Buffer2[i] = EMPTY_VALUE;
              }
           }
         return(rates_total);
        }
      //copy the code to meta editor to compile it

        No gráfico de resultados do teste para EURUSD em 12.04.24, marca-se o início do período observado no timeframe M1. Os cruzamentos são indicados por setas: vermelhas para sinais de venda e azuis para sinais de compra. No entanto, uma análise mais ampla revela um claro movimento descendente, indicando uma vela D1 baixista. O indicador de cruzamento gera ambos os sinais (de compra e de venda), ignorando a tendência predominante. Sinais contraditórios criam uma situação desafiadora para traders que tentam se orientar no mercado. Embora o timeframe M1 indique oportunidades de curto prazo, o movimento descendente em D1 coloca em questão a sustentabilidade de qualquer movimento ascendente. Vamos resolver esse problema limitando nossos sinais à tendência D1.

        Sinais de Cruzamento de Médias Móveis

        Fig. 1.2. Indicador de cruzamento de médias móveis antes da implementação das restrições.

        O resultado para a vela D1 é baixista. As setas de compra e venda são geradas com base no cruzamento das médias móveis. Muitos desses sinais são considerados falsos ou estão desalinhados com a tendência predominante, problema que pode ser corrigido ao incluir uma restrição de tendência baseada em um timeframe superior. A tabela abaixo foi criada a partir das informações do gráfico, do início até o fechamento do dia. 

        Tipo de Sinal Quantidade
        Sinais de Venda 29
        Sinais de Compra 28
        Total 57
        Sinais Falsos e Alheios 41
        Sinais Bem-sucedidos 25


        Justificativa e aplicação da restrição

        Imagine uma mistura de grãos de milho e sorgo, onde o milho é mais grosso. Para separá-los, usamos uma peneira. Ela retém os grãos de milho, permitindo que apenas o sorgo passe. Essa analogia reflete a ideia de restrição com base em timeframes superiores. Ela age como um filtro, separando sinais específicos e mantendo apenas aqueles que estão alinhados com a tendência predominante. A restrição de um timeframe superior, assim como a peneira, reforça nosso foco, permitindo distinguir os principais elementos da tendência do mercado. Ao filtrar o ruído, conseguimos entender melhor a dinâmica principal do mercado, favorecendo a tomada de decisões mais informadas. Esse enfoque estratégico aprimora nossa capacidade de navegar nas complexidades do cenário financeiro, assegurando que estejamos alinhados com a direção geral, assim como o sorgo é separado do milho, revelando a essência do movimento de mercado.

        Vamos definir a natureza da vela D1 como critério para limitar a tendência.
        • Eu defino o sentimento de mercado atual como altista ou baixista, comparando o fechamento do dia anterior, que é similar ao preço de abertura do dia atual, com os fechamentos das velas de timeframe inferior M1.
        • Para uma vela ALTISTA:

          fechamento da última vela M1 >= fechamento da última vela D1

          Para uma vela BAIXISTA:

          fechamento da última vela M1 <= fechamento da última vela D1

          A lógica matemática demonstra que, com uma vela altista D1 como direcionador de tendência, somente sinais de compra serão gerados, e, para uma vela baixista D1, apenas sinais de venda serão permitidos.

          Optamos por usar o fechamento do timeframe curto em relação ao nosso preço de abertura D1, em vez de outros parâmetros como Bid e Ask ou o fechamento do próprio dia, pois este último não exibe setas no gráfico, como exigido pela estratégia e estilo do indicador. Ao focar no fechamento do timeframe curto em relação à abertura D1, conseguimos alinhar nossa estratégia com as sugestões visuais desejadas e com os indicadores no gráfico. Esse método aumenta a clareza e a precisão nas nossas decisões de trading, proporcionando um processo de análise mais otimizado e eficiente.  

        • A seguir, vamos revisar o código. Ele está bem estruturado e é fácil de entender.
         if(Close[1+barshift_M1[i]] >= Open[1+barshift_D1[i]] //Candlestick Close >= Candlestick Open
              )
                {
                 Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
                }
              else
                {
                 Buffer1[i] = EMPTY_VALUE;
                }

        O código acima representa o estado de uma vela altista D1. A versão espelhada do código funciona também para uma tendência baixista.

        • Abaixo está o código final, no qual a restrição de tendência é integrada ao indicador de cruzamento de médias móveis de forma fluida.
        /Indicator Name: Trend Constraint
        #property copyright "Clemence Benjamin"
        #property link      "https://mql5.com"
        #property version   "1.00"
        #property description "A model that seek to produce sell signal when D1 candle is Bearish only and  buy signal when it is Bullish"
        
        //--- indicator settings
        #property indicator_chart_window
        #property indicator_buffers 2
        #property indicator_plots 2
        
        #property indicator_type1 DRAW_ARROW
        #property indicator_width1 5/
        #property indicator_color1 0xFFAA00
        #property indicator_label1 "Buy"
        
        #property indicator_type2 DRAW_ARROW
        #property indicator_width2 5
        #property indicator_color2 0x0000FF
        #property indicator_label2 "Sell"
        
        #define PLOT_MAXIMUM_BARS_BACK 5000
        #define OMIT_OLDEST_BARS 50
        
        //--- indicator buffers
        double Buffer1[];
        double Buffer2[];
        
        double myPoint; //initialized in OnInit
        int MA_handle;
        double MA[];
        int MA_handle2;
        double MA2[];
        double Close[];
        double Close2[];
        double Low[];
        double High[];
        
        void myAlert(string type, string message)
          {
           if(type == "print")
              Print(message);
           else if(type == "error")
             {
              Print(type+" | Trend constraint @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
             }
           else if(type == "order")
             {
             }
           else if(type == "modify")
             {
             }
          }
        
        // Custom indicator initialization function                         
        int OnInit()
          {   
           SetIndexBuffer(0, Buffer1);
           PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
           PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
           PlotIndexSetInteger(0, PLOT_ARROW, 241);
           SetIndexBuffer(1, Buffer2);
           PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
           PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
           PlotIndexSetInteger(1, PLOT_ARROW, 242);
           //initialize myPoint
           myPoint = Point();
           if(Digits() == 5 || Digits() == 3)
             {
              myPoint *= 10;
             }
           MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_EMA, PRICE_CLOSE);
           if(MA_handle < 0)
             {
              Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
              Print("Runtime error = ", GetLastError());
              return(INIT_FAILED);
             }
           
           MA_handle2 = iMA(NULL, PERIOD_CURRENT, 21, 0, MODE_EMA, PRICE_CLOSE);
           if(MA_handle2 < 0)
             {
              Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
              Print("Runtime error = ", GetLastError());
              return(INIT_FAILED);
             }
           
           return(INIT_SUCCEEDED);
          }
        
        // 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[])
          {
           int limit = rates_total - prev_calculated;
           //--- counting from 0 to rates_total
           ArraySetAsSeries(Buffer1, true);
           ArraySetAsSeries(Buffer2, true);
           //--- initial zero
           if(prev_calculated < 1)
             {
              ArrayInitialize(Buffer1, EMPTY_VALUE);
              ArrayInitialize(Buffer2, EMPTY_VALUE);
             }
           else
              limit++;
           
           datetime TimeShift[];
           if(CopyTime(Symbol(), PERIOD_CURRENT, 0, rates_total, TimeShift) <= 0) return(rates_total);
           ArraySetAsSeries(TimeShift, true);
           int barshift_M1[];
           ArrayResize(barshift_M1, rates_total);
           int barshift_D1[];
           ArrayResize(barshift_D1, rates_total);
           for(int i = 0; i < rates_total; i++)
             {
              barshift_M1[i] = iBarShift(Symbol(), PERIOD_M1, TimeShift[i]);
              barshift_D1[i] = iBarShift(Symbol(), PERIOD_D1, TimeShift[i]);
           }
           if(BarsCalculated(MA_handle) <= 0) 
              return(0);
           if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
           ArraySetAsSeries(MA, true);
           if(BarsCalculated(MA_handle2) <= 0) 
              return(0);
           if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);
           ArraySetAsSeries(MA2, true);
           if(CopyClose(Symbol(), PERIOD_M1, 0, rates_total, Close) <= 0) return(rates_total);
           ArraySetAsSeries(Close, true);
           if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close2) <= 0) return(rates_total);
           ArraySetAsSeries(Close2, true);
           if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
           ArraySetAsSeries(Low, true);
           if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
           ArraySetAsSeries(High, true);
           //--- main loop
           for(int i = limit-1; i >= 0; i--)
             {
              if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
              
              if(barshift_M1[i] < 0 || barshift_M1[i] >= rates_total) continue;
              if(barshift_D1[i] < 0 || barshift_D1[i] >= rates_total) continue;
              
              //Indicator Buffer 1
              if(MA[i] > MA2[i]
              && MA[i+1] < MA2[i+1] //Moving Average crosses above Moving Average
              && Close[1+barshift_M1[i]] >= Close2[1+barshift_D1[i]] //Candlestick Close >= Candlestick Close
              )
                {
                 Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
                }
              else
                {
                 Buffer1[i] = EMPTY_VALUE;
                }
              //Indicator Buffer 2
              if(MA[i] < MA2[i]
              && MA[i+1] > MA2[i+1] //Moving Average crosses below Moving Average
              && Close[1+barshift_M1[i]] <= Close2[1+barshift_D1[i]] //Candlestick Close <= Candlestick Close
              )
                {
                 Buffer2[i] = High[i]; //Set indicator value at Candlestick High
                }
              else
                {
                 Buffer2[i] = EMPTY_VALUE;
                }
             }
           return(rates_total);
          }

        O resultado do uso do código acima é excelente.

        Restrição de tendência aplicada ao indicador de cruzamento de médias móveis

        Fig. 1.4. Restrição de tendência aplicada. Resultado notável

        Tipo de Sinal Unidades
        Sinal de Venda 27
        Sinal de Compra 1
        Total 28
        Sinais Falsos e Alheios 3
        Sinais Bem-sucedidos 25

        A tabela acima evidencia o impacto positivo da restrição de tendência com base em um timeframe superior, atuando como um filtro que resulta em mais acertos do que erros, o que o torna ideal para EAs. Comparando as tabelas de resultados anteriores e atuais, observamos que os sinais bem-sucedidos mantiveram seu valor, enquanto o número de sinais falsos diminuiu. Esse ganho em precisão demonstra a eficácia da nossa metodologia de análise de dados. Com o aprimoramento dos algoritmos e critérios, reduzimos a ocorrência de sinais falsos, aumentando a confiabilidade geral dos resultados. Esse progresso certamente contribuirá para decisões mais fundamentadas e melhores resultados nas nossas estratégias.


        Vantagens do uso do código

        As vantagens de aplicar restrições com base nas tendências de timeframes superiores aumentam a clareza sobre a direção do mercado, reduzem o excesso de operações e promovem uma abordagem mais disciplinada nas decisões de trading. Esse método também oferece uma perspectiva mais ampla, ajudando os traders a não se prenderem a flutuações de curto prazo e permitindo que alinhem suas estratégias ao movimento de longo prazo predominante. Ao focar na visão geral, os traders estão mais preparados para filtrar o ruído e tomar decisões mais embasadas. Esse método encoraja a paciência e um entendimento mais profundo da dinâmica do mercado, levando a resultados de negociação mais consistentes e lucrativos. Além disso, restrições baseadas em tendências de timeframes superiores podem funcionar como ferramentas valiosas de gestão de riscos, permitindo que traders definam pontos de entrada e saída claros com base em uma análise estratégica das condições de mercado.

        Resumindo:

        • Maior precisão dos indicadores de geração de sinais
        • Melhor gestão de riscos
        • Aumento da lucratividade
        • Redução de trabalho
        • Menos sinais desnecessários


        Considerações finais

        As velas de timeframes superiores influenciam substancialmente as tendências de timeframes inferiores, essencialmente direcionando o mercado. Com base em várias análises, recomenda-se considerar a compra durante velas diárias altistas nos timeframes menores e a venda durante velas baixistas. A integração de restrições de tendência em intervalos maiores pode ser decisiva para o desenvolvimento de EAs e indicadores que visam obter resultados positivos consistentes. Isso levanta a questão: devemos abandonar as médias móveis como ferramenta para identificar tendências? Talvez o próximo artigo lance luz sobre essa questão. Nele, vamos explorar e aprimorar ainda mais essa ideia. O artigo inclui os arquivos de código-fonte, prontos para visualização no MetaEditor, e os arquivos .ex5 para uso no MetaTrader 5.


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

        Técnicas do MQL5 Wizard que você deve conhecer (Parte 24): Médias Móveis Técnicas do MQL5 Wizard que você deve conhecer (Parte 24): Médias Móveis
        Médias Móveis são um indicador muito comum, usado e compreendido pela maioria dos traders. Exploramos possíveis casos de uso que podem não ser tão comuns dentro dos Expert Advisors montados no MQL5 Wizard.
        Funcionalidades do Assistente MQL5 que você precisa conhecer (Parte 16): Método de componentes principais com autovetores Funcionalidades do Assistente MQL5 que você precisa conhecer (Parte 16): Método de componentes principais com autovetores
        Este artigo discute o método de componentes principais, um método de redução da dimensionalidade ao analisar dados, e como ele pode ser implementado usando autovalores e vetores. Como sempre, vamos tentar desenvolver um protótipo da classe de sinais para EA que pode ser usado no Assistente MQL5.
        Do básico ao intermediário: União (I) Do básico ao intermediário: União (I)
        Neste artigo começaremos a ver o que seria uma união. Aqui faremos a lição de casa, experimentando as primeiras construções em que uma união poderia ser utilizada. Apesar de tudo, o que será visto aqui, é apenas a parte básica de todo um conjunto de conceitos e informações que ainda serão melhor exploradas em artigos futuros. O conteúdo exposto aqui, visa e tem como objetivo, pura e simplesmente a didática. De modo algum deve ser encarado como sendo, uma aplicação cuja finalidade não venha a ser o aprendizado e estudo dos conceitos mostrados.
        Otimização Automatizada de Parâmetros para Estratégias de Trading Usando Python e MQL5 Otimização Automatizada de Parâmetros para Estratégias de Trading Usando Python e MQL5
        Existem vários tipos de algoritmos para auto-otimização de estratégias de trading e parâmetros. Esses algoritmos são usados para melhorar automaticamente as estratégias de trading com base em dados históricos e atuais de mercado. Neste artigo, veremos um desses algoritmos com exemplos em Python e MQL5.