English Русский 中文 Español Deutsch 日本語
Teste de padrões que surgem ao negociar cestas de pares de moedas Parte II

Teste de padrões que surgem ao negociar cestas de pares de moedas Parte II

MetaTrader 5Negociação | 22 dezembro 2017, 15:13
1 252 0
Andrei Novichkov
Andrei Novichkov

Introdução

Continuamos com o tema sobre o teste de padrões que surgem ao negociar cestas de moedas. No último artigo, examinamos um padrão sobre o rompimento de níveis de sobrecompra e sobrevenda. O rompimento destes níveis foi considerado no exemplo do indicador combinado WPR. Esta experiência pode se propagar a outros indicadores combinados construídos com base em osciladores. Pode-se supor que o resultado será semelhante.

Lembre que a avaliação da localização dos níveis de sobrecompra e sobrevenda será o resultado do teste. Para o nível de sobrecompra, este valor está na faixa de 60% - 70%, enquanto o nível de sobrevenda se encontra entre -60% e -70%. O teste de operação do padrão mostrou sua rentabilidade no timeframe H4, com todas as cestas de pares de moedas. No intervalo D1 foi fixada uma quantidade pequena de transações. Intervalo H1 mostrou uma perda significativa.

Neste artigo, vamos tentar aplicar uma média móvel (MA) aos gráficos de indicadores combinados e usar isso na negociação. Vamos usar a análise técnica padrão e as técnicas já desenvolvidas por nós.

Ferramentas de pesquisa

A ferramenta central de nossa pesquisa é o já bem conhecido indicador WPR combinado com período 20. No seu gráfico, vamos colocar uma МА com período 10. Esse período tão curto é escolhido, porque estamos interessados ​​em tendências locais.

Tal como no passado artigo, estudaremos três timeframes, isto é, H1, H4 e D1. Não esqueçamos que, partindo de como se mostrou o primeiro padrão neles, será razoável considerar o seguinte padrão, nestes timeframes. Além disso, é importante dizer que a experiência adquirida pode ser usada para pesquisas em quaisquer outros timeframes e cestas de moedas.

Terminologia básica e princípios são delineados aqui.

Padrão para pesquisa

Graças à análise técnica, este padrão é bem conhecido, além do mais, nós já o descrevemos, por isso, só lembraremos fatos básicos e nuances específicas para operar cestas de moedas:

  • O trader recebe um sinal para entrar no mercado, quando o gráfico do indicador combinado intercepta o gráfico da média móvel.

Existem apenas dois sinais:

  • Sinal para comprar pares de moedas aparece quando o gráfico da MA cruza, para cima, o gráfico do indicador combinado.
  • Sinal para vender pares de moedas aparece quando o gráfico da MA cruza, para baixo, o gráfico do indicador combinado.
  • Trader entra no mercado comprando ou vendendo a cesta de moedas para a qual é recebido o sinal.
  • Obtido um sinal oposto ao sinal de entrada, o trader sai do mercado.

Além disso, deve-se ter em mente que os sinais da média móvel tendem a estar atrasados.

Partindo da experiência ao implementar a МА nos gráficos de pares de moedas habituais, lembramos que, para médias moveis rápidas, sempre há um número suficientemente grande de sinais de entrada. Podemos esperar que, neste caso, a quantidade desses sinais não será menor. Para verificar esta afirmação, foi escrito o indicador testWPR&MA.mq5. Você pode encontrá-lo no anexo ao artigo.

//+------------------------------------------------------------------+
//|                                                      testWPR.mq5 |
//|                                        MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_minimum -100
#property indicator_maximum 100


#define LG 7

#property indicator_buffers 2
#property indicator_plots   2

input int WPR       = 20; //Period WPR
input int maperiod  = 10; //Period MA
input color   clr   = clrGreen;
input color   clrMA = clrMagenta;

string pair[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY"};
bool bDirect[]={false,false,false,false,true,true,true};

int h[LG];
double ind[],ma[];

int iUp,iDw;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   for(int i=0; i<LG; i++)
     {
      h[i]=iWPR(pair[i],0,WPR);
     }

   IndicatorSetString(INDICATOR_SHORTNAME,"testWPRusd");
   IndicatorSetInteger(INDICATOR_DIGITS,2);
   IndicatorSetInteger(INDICATOR_LEVELS,2);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,0,STYLE_SOLID);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,1,STYLE_SOLID);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,0,clrRed);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,1,clrRed);
   IndicatorSetInteger(INDICATOR_LEVELWIDTH,0,1);
   IndicatorSetInteger(INDICATOR_LEVELWIDTH,1,1);
   IndicatorSetDouble(INDICATOR_LEVELVALUE,0,-60);
   IndicatorSetDouble(INDICATOR_LEVELVALUE,1,60);

   ArraySetAsSeries(ind,true);
   SetIndexBuffer(0,ind);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,clr);
   PlotIndexSetString(0,PLOT_LABEL,"_tstWPRusd_");

   ArraySetAsSeries(ma,true);
   SetIndexBuffer(1,ma);
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(1,PLOT_LINE_STYLE,STYLE_SOLID);
   PlotIndexSetInteger(1,PLOT_LINE_WIDTH,1);
   PlotIndexSetInteger(1,PLOT_LINE_COLOR,clrMA);
   PlotIndexSetString(1,PLOT_LABEL,"Middle_Basket_line_MA");

   iUp=iDw=0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetValue(int shift)
  {
   double dBuf[1];
   double res=0.0;
   for(int i=0; i<LG; i++)
     {
      CopyBuffer(h[i],0,shift,1,dBuf);
      if(bDirect[i]==true)
         res+=dBuf[0];
      else
         res+=-(dBuf[0]+100);
     }//end for (int i = 0; i < iCount; i++)      
   res=res/LG;
   return (NormalizeDouble((res + 50) * 2, _Digits) );
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   if(prev_calculated==0 || rates_total>prev_calculated+1)
     {
      int rt=rates_total-WPR;
      for(int i=1; i<rt; i++)
        {
         ind[i]=GetValue(i);
        }
      rt-=maperiod;
      for(int i=1; i<rt; i++)
        {
         ma[i]=GetMA(ind,i,maperiod,_Digits);
        }
      rt--;
      for(int i=1; i<rt; i++)
        {
         if(ind[i] > ma[i] && ind[i+1] < ma[i+1]) {iUp++; continue;}
         if(ind[i] < ma[i] && ind[i+1] > ma[i+1]) {iDw++; continue;}
        }
      PrintFormat("BUY count: %d SELL count: %d",iUp,iDw);
     }
   else
     {
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

void OnDeinit(const int reason)
  {
   for(int i=0; i<LG; i++)
     {
      if(h[i]!=INVALID_HANDLE) IndicatorRelease(h[i]);
     }
   string text;
   switch(reason)
     {
      case REASON_PROGRAM:
         text="Indicator terminated its operation by calling the ExpertRemove() function";break;
      case REASON_INITFAILED:
         text="This value means that OnInit() handler "+__FILE__+" has returned a nonzero value";break;
      case REASON_CLOSE:
         text="Terminal has been closed"; break;
      case REASON_ACCOUNT:
         text="Account was changed";break;
      case REASON_CHARTCHANGE:
         text="Symbol or timeframe was changed";break;
      case REASON_CHARTCLOSE:
         text="Chart was closed";break;
      case REASON_PARAMETERS:
         text="Input-parameter was changed";break;
      case REASON_RECOMPILE:
         text="Program "+__FILE__+" was recompiled";break;
      case REASON_REMOVE:
         text="Program "+__FILE__+" was removed from chart";break;
      case REASON_TEMPLATE:
         text="New template was applied to chart";break;
      default:text="Another reason";
     }
   PrintFormat("%s",text);
  }
//+------------------------------------------------------------------+

double GetMA(const double &arr[],int index,int period,int digit) 
  {
   double m=0;
   for(int j=0; j<period; j++) m+=arr[index+j];
   m/=period;
   return (NormalizeDouble(m,digit));
  }
//+------------------------------------------------------------------+

O indicador conta o número de cruzamentos entre o indicador combinado e a média móvel para todo o histórico disponível. Colocamos o indicador no gráfico EURUSD e obtemos os dados da cesta do USD para os timeframes de nosso interesse:

  Sinais obtidos
H1 H4 D1
Buy Sell Buy Sell Buy Sell
EURUSD 8992 8992 2448 2449 550 551
Profundidade de histórico 2005.09.08 2004.10.11 2000.02.28

Vemos que há suficientes sinais. Assumimos que, em outras cestas de moedas, o panorama será semelhante, e não vamos testá-los.

A captura de tela mostra o trabalho do indicador:

Imediatamente sinais potenciais chamam a atenção. É claro que entre eles haverá muitos que são falsos, porém, é muito cedo para pensar nisso. Simplesmente marcamos com azul os sinais de entrada para compra, e com vermelho - para venda.

Para futuras pesquisas, destacamos a seguinte lógica de trabalho:

  • Obtemos o sinal de entrada, entramos. Obtendo o sinal oposto, saímos. Entramos na direção oposta. Recebendo os sinais correspondentes, repetimos a sequência.

É óbvio que, na ausência de qualquer filtragem adicional, a prática considera uma presença constante no mercado. Provavelmente, teremos de usar tal filtração, mas isso será analisado mais tarde. Por enquanto, na captura de tela, chama a atenção a variação no número de sinais:

  • claros sinais nos pontos 7 e 8 (azul);
  • bom sinal no ponto 5 (vermelho);
  • acumulação de sinais multidirecionais nos pontos 2, 3, 4 (vermelho).

Especificamos as regras para diferenciar "bons" sinais de "maus" sinais. Nas duas seguintes imagens, vemos indícios de bastante precisão que identificam "bons" sinais:

"Bom" padrão procurado (sinal)
Ausência de padrão, "mal" sinal





Nestas imagens, a linha verde representa o gráfico do WPR combinado para USD, uma linha carmesim - a média móvel, as linhas azuis verticais - bordas do padrão.

Assumimos que, para padrões de entrada, as distâncias Delta1 e Delta2 não devem ser inferiores a 5%.

No entanto, nós também utilizamos "maus" padrões, como na imagem à direita. Embora não deem sinais de entrada, alertarão para a possível alteração ou desaceleração da tendência. Assim, podem ser usados para sair do mercado ou filtrar.

Início do teste

Para trabalho futuro, precisaremos de um expert advisor cujo código pode ser encontrado no arquivo anexado testEAbasket.mq5:

//+------------------------------------------------------------------+
//|                                                 testEAbasket.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\\Trade.mqh>

#define LG 7

enum BSTATE 
  {
   BCLOSE = 0,
   BBUY   = 1,
   BSELL  = 2
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
input int wpr = 20;
input int ma  = 10;
input double lt = 0.01; //lot

string pair[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY"};
bool bDirect[]={false,false,false,false,true,true,true};

int h;
ulong  Ticket[LG];

double m[1],ml;
double w[1],wl;

BSTATE g_state;

double g_dMinSize = 5.0;

int OnInit()
  {
   h = iCustom(NULL,0,"testWPR&MA",wpr,ma);
   if (h == INVALID_HANDLE) {
      Print("Error while creating testWPReur");
      return (INIT_FAILED);
   }
   
   g_state = BCLOSE;
   
   EventSetTimer(1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   IndicatorRelease(h);
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(IsNewCandle()) 
     {
         wl = w[0];
         CopyBuffer(h,0,1,1,w);
         ml = m[0];
         CopyBuffer(h,1,1,1,m);
         if ( w[0] > m[0] && wl < ml) {
            if (g_state != BCLOSE) CloseAllPos();
            if ( w[0] - m[0] >= g_dMinSize && ml - wl >= g_dMinSize) {
               EnterBuy(lt);
               g_state = BBUY;
            }   
         }     
         if ( w[0] < m[0] && wl > ml) {
            if (g_state != BCLOSE) CloseAllPos();
            if ( m[0] - w[0] >= g_dMinSize && wl - ml >= g_dMinSize) {
               EnterSell(lt);
               g_state = BSELL;
            }   
         }            
     }      
  }
//+------------------------------------------------------------------+
  
void CloseAllPos() 
  {

   CTrade Trade;
   Trade.LogLevel(LOG_LEVEL_NO);

   for(int i=0; i<LG; i++) 
     {

      Trade.PositionClose(Ticket[i]);
     }

     g_state = BCLOSE;

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void EnterBuy(double lot) 
  {

   CTrade Trade;
   Trade.LogLevel(LOG_LEVEL_NO);

   for(int i=0; i<LG; i++) 
     {
      if(bDirect[i]) 
        { //send buy
         Trade.Buy(lot,pair[i]);
         Ticket[i]=Trade.ResultDeal();
        }
      else 
        { //send sell
         Trade.Sell(lot,pair[i]);
         Ticket[i]=Trade.ResultDeal();
        }
     }
     g_state = BBUY;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void EnterSell(double lot) 
  {

   CTrade Trade;
   Trade.LogLevel(LOG_LEVEL_NO);

   for(int i=0; i<LG; i++) 
     {
      if(bDirect[i]) 
        { //send sell
         Trade.Sell(lot,pair[i]);
         Ticket[i]=Trade.ResultDeal();
        }
      else 
        { //send buy
         Trade.Buy(lot,pair[i]);
         Ticket[i]=Trade.ResultDeal();
        }
     }
     g_state = BSELL;
  }
  
bool IsNewCandle() 
  {

   static int candle=-1;

   int t1=0;
   switch(_Period)
     {
      case PERIOD_H1:  t1 = Hour();   break;
      case PERIOD_H4:  t1 = Hour4();  break;
      case PERIOD_D1:  t1 = Day();    break;
     }
   if(t1 != candle) {candle=t1; return(true);}
   return (false);
  }
int Hour4(){return((int)Hour()/4);}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Day()
  {
   MqlDateTime tm;
   TimeCurrent(tm);
   return(tm.day);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Hour()
  {
   MqlDateTime tm;
   TimeCurrent(tm);
   return(tm.hour);
  }  

Testá-lo-emos no Testador de estratégias sobre dados relativos ao último ano, nos timeframes H1, H4 e D1. Analisaremos a cesta de moedas com USD.

Os resultados da análise são encontrados no arquivo anexado testEAbasket.zip, na forma de relatórios padrão. Imediatamente, podemos dizer que os resultados dos testes são negativos. Com as configurações atuais, o expert advisor traz perdas em todos os três timeframes. Apesar de ser negativo, é o resultado esperado. É difícil acreditar que um número tão grande de transações, definidas previamente, permitam obter um lucro significativo. A seguintes circunstâncias tiveram impacto no resultado:

  • Padrão com média móvel sempre se atrasa (por definição).
  • Na análise técnica padrão, a decisão sobre a entrada no mercado não é tomada em função do comportamento de uma única média móvel rápida.
  • No expert advisor, é considerada apenas uma filtragem mínima de sinais com base na "qualidade" dos padrões. Isso dificilmente parece suficiente, além disso, o critério de "qualidade" deste padrão é determinado apenas antecipadamente e pode ser impreciso.

E apesar do resultado negativo geral, podem ser vistos sinais que apresentam indícios favoráveis. Na primeira parte do artigo, podia-se ver que o padrão estudado trabalha bem no timeframe H4. O padrão sobre o qual estamos falando agora se apresenta relativamente bem no timeframe H1. Embora o resultado tenha sido negativo, houve lucro - a tendência de diminuição no rendimento não é tão abrupta:

Existe uma boa chance de pensar que temos hipótese se modificarmos o expert advisor em si e suas configurações de trabalho. Vemos que, durante o teste, o saldo entrou em lucro. Apesar de ter havido muitos trades, a curva tem profundas lacunas, o que revela resultados negativos sequenciais. Por outro lado, também observamos resultados positivos sequenciais! Vamos tentar melhorar a rentabilidade do padrão neste timeframe fazendo alterações no código do EA.

Correção da forma do padrão

A primeira coisa que vem à mente é uma mudança na forma do padrão, nomeadamente, nos valores dos parâmetros Delta1 e Delta2. Inicialmente, escolhemos 5%. Por que não tentar modificá-lo? Se reduzirmos essa porcentagem, estaremos aumentando o número de entradas no mercado. Se aumentarmos, o número de entradas será reduzido, mas, ao mesmo tempo, estará sendo incrementada a força e velocidade do padrão, e, portanto, o "impulso para mudar a tendência".

Sendo assim, não se deve nem aumentar nem diminuir esse valor! Também é errado pensar que o valor selecionado é ideal. Mas, se começarmos a otimizá-lo nesta fase, corremos o risco de obter um valor que funcione bem num intervalo de tempo separado, num determinado timeframe e num certo par de moedas. Em outras palavras, não há garantia de que o valor resultante será universal.

Embora isso seja assim, faz sentido dar mais um passo nessa direção. Delta1 e Delta2 devem ser limitados no "topo" definindo seu valor máximo. Podemos racionalizar e justificar isso uma vez que um padrão grande demais já em si pode esgotar completamente a dinâmica do movimento. E, então, após entrar no mercado, o trader terá de esperar um movimento lateral ou mudança de tendência, em vez da continuação do movimento. Além disso, um padrão grande pode terminar perto dos lados opostos da faixa do WPR combinado, o que também é muito ruim para abertura de posição juntamente com a continuação da tendência existente.

Portanto, assumimos que o valor máximo para Delta1 e Delta2 será 10%. Assim, a magnitude do padrão em si será Delta1 + Delta2 = 20%. Isso não é muito. Fazemos alterações no expert:

1. Adicionamos uma variável global:

double g_dMaxSize = 10.0;

2. Alteramos a função de processamento de eventos do temporizador:

void OnTimer()
  {
   if(IsNewCandle())
     {
      wl=w[0];
      CopyBuffer(h,0,1,1,w);
      ml=m[0];
      CopyBuffer(h,1,1,1,m);
      double d1 = MathAbs(w[0] - m[0]);
      double d2 = MathAbs(ml - wl);
      if(w[0]>m[0] && wl<ml) 
        {
         if(g_state!=BCLOSE) CloseAllPos();
         if(d1 >= g_dMinSize && d2 >= g_dMinSize &&
            d1 <= g_dMaxSize && d2 <= g_dMaxSize) 
           {
            EnterBuy(lt);
            g_state=BBUY;
           }
        }
      if(w[0]<m[0] && wl>ml) 
        {
         if(g_state!=BCLOSE) CloseAllPos();
         if(d1 >= g_dMinSize && d2 >= g_dMinSize &&
            d1 <= g_dMaxSize && d2 <= g_dMaxSize) 
           {
            EnterSell(lt);
            g_state=BSELL;
           }
        }
     }
  }


Continuamos o teste com o expert advisor modificado no timeframe H1. Seu resultado pode ser encontrado no arquivo anexado testEAbasket1.zip. Resultados:


Imediatamente, são visíveis alterações positivas. Apesar do resultado ser negativo, a perda é muito menor em termos absolutos. Mudou a tendência de perda do depósito passando para um movimento lateral, oscilante, instável. Embora haja rebaixamentos profundos, existem pontos de recuperação. Claro, este teste é completamente insuficiente para tirar conclusões definitivas, mas é possível reconhecer que o uso do filtro para os valores máximos Delta1 e Delta2 é justificado e positivo. Portanto, anexamos as alterações no código do EA.

No futuro, não vamos alterar os valores obtidos para Delta1 e Delta2. Repito, não se pode dizer que esses valores são ideais. Mas, tendo em mente que, posteriormente, será necessário transferi-los para outros timeframes e outras cestas, por enquanto ficamos satisfeitos com o resultado.

Segundo filtro

O próximo passo é óbvio:

  • Deve-se entrar cuidadosamente no mercado juntamente com a tendência quando o gráfico do WPR combinado (ou qualquer outro oscilador) se aproxima de seus limites.

Trata-se de uma conhecida regra implementada na utilização de indicadores técnicos padrão, ela pode ser estendida aos indicadores combinados. Em artigos anteriores, já falamos sobre o fato de que, neste caso, existe uma possível reversão, desaceleração significativa ou movimento lateral da tendência. Resta tornar realidade estas ideias no segundo filtro do expert advisor.

O WPR combinado varia na faixa de -100% a +100%. Não vamos nos concentrar nestes números, uma vez que o indicador se aproxima destes limites, mas nunca os atinge. No entanto, já conhecemos os limites de sobrevenda/sobrecompra. No artigo anterior, examinamos o rompimento e definimos a localização destes limites. Eles não serão utilizados aqui.

Bem, definamos a tarefa com mais precisão.

  • O trader NÃO deve comprar quando o gráfico do WPR combinado atinge ou rompe a borda de sobrecompra de baixo para cima.
  • O trader NÃO deve comprar quando o gráfico do WPR combinado atinge ou rompe a borda de sobrevenda de cima para baixo.

Definimos as limites de sobrecompra na faixa 60% - 70%, enquanto, a sobrevenda na gama -60% ... -70%. Para o novo filtro, tomamos os valores inferiores das bordas: 60% e -60%. Digamos que, para comprar, a curva do WPR combinado se deve encontrar abaixo da borda do filtro, enquanto, para venda, acima dela. Ou seja, nós não vamos tentar encontrar um padrão "completo" de cruzamento feito pela média móvel, e nós nos limitaremos à filtragem usada na análise técnica padrão:

  • Vamos considerar apenas a posição relativa - acima/abaixo - entre a média móvel e o indicador.

Para implementação, vamos fazer alterações mínimas no bloco de código relativas aos critérios de entrada no mercado:

       if(w[0]>m[0] && wl<ml) 
        {
         if(g_state!=BCLOSE) CloseAllPos();
         if(d1 >= g_dMinSize && d2 >= g_dMinSize &&
            d1 <= g_dMaxSize && d2 <= g_dMaxSize && w[0] < 60) 
           {
            EnterBuy(lt);
            g_state=BBUY;
           }
        }
      if(w[0]<m[0] && wl>ml) 
        {
         if(g_state!=BCLOSE) CloseAllPos();
         if(d1 >= g_dMinSize && d2 >= g_dMinSize &&
            d1 <= g_dMaxSize && d2 <= g_dMaxSize && w[0] > -60) 
           {
            EnterSell(lt);
            g_state=BSELL;
           }
        }


Vamos testar o expert no intervalo de tempo previamente selecionado e timeframe H1. Aqui estão os resultados do teste:


Todos os resultados estão no arquivo anexado testEAbasket2.zip. Vemos que os resultados não diferem muito dos anteriores, embora haja algum progresso no sentido de melhorar a situação.

Qual pode ser a razão para isso? Talvez os níveis de sobrevenda/sobrecompra não estejam sendo detectados com suficiente precisão. Talvez a quantidade de transações filtradas seja pequena. Talvez ambas as razões.

Será que o resultado obtido demostra a futilidade do filtro aplicado? Bem, não demostra isso não. Essa conclusão só pode ser feita após usar o filtro em todas as cestas, todos os timeframes e intervalos de tempo superiores a um ano. Portanto, deixamos este filtro no código do EA, mas pomos em causa seu uso.

Fim do trabalho como padrão

Cumprimos nossos planos de trabalhar com o padrão descrito acima em uma cesta com USD. A versão final do expert advisor utilizada pode ser encontrada no arquivo anexado testEAbasketFinal.mq5. A parir dos testes realizados podemos concluir:

  • Este padrão não deve ser utilizado como um sinal para entrar no mercado.

Surge a pergunta: será que vale a pena realizar testes nas cestas restantes? Com muito alta probabilidade o resultado é previsível.

A principal consideração que nos permite realizar testes em outras cestas é que os padrões baseados no rompimento da MA não são utilizados como um sinal separado para abordar uma análise técnica padrão na negociação real. Por isso, agora tentamos usar, como um filtro, o padrão de cruzamento entre o WPR combinado e a média móvel. Como sinal de entrada principal, vamos considerar o padrão de rompimento - pelo indicador combinado - de níveis de sobrevenda/sobrecompra. Nosso objetivo é descobrir como um filtro desse tipo afeta a rentabilidade.

Uso deste padrão como um filtro

Voltemos para a tarefa inicial.

  • O WPR combinado rompe, de baixo para cima, o nível de sobrevenda. O rompimento é registrado no fechamento da vela. Para entrar no mercado comprando, a média móvel deve se encontrar "abaixo" do gráfico do indicador combinado.
  • Para entrar no mercado vendendo, o indicador combinado deve estar "abaixo" do gráfico da média móvel.
  • Para sair do mercado, usa-se o fato de o gráfico atingir o WPR combinado perto do zero 0%.

É fácil ver que será novamente utilizada a versão "simplificada" do padrão, isto é, filtro "acima - abaixo" aplicado à localização mútua da média móvel e o gráfico do WPR combinado.

Para testar, alteramos o expert advisor testEAbasket.mq5. Adicionamos a ele os dados brutos para descrever o nível de sobrevenda/sobrecompra e as condições para aplicar o padrão como um filtro:

input int SELLPROFIT =   0;
input int SELL1LIMIT =  70;
input int SELL2FROM  =  60;
input int SELL2TO    =  50;

input int BUYPROFIT  =   0;
input int BUY1LIMIT  = -70;
input int BUY2FROM   = -60;
input int BUY2TO     = -50;

//...................................................................

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(IsNewCandle())
     {
      wl=w[0];
      CopyBuffer(h,0,1,1,w);
      ml=m[0];
      CopyBuffer(h,1,1,1,m);

      if(g_state==BBUY && (w[0]>=BUYPROFIT))
        {
         CloseAllPos();
        }
      if(g_state==BSELL && (w[0]<=SELLPROFIT))
        {
         CloseAllPos();
        }
      if(g_state==BCLOSE && w[0]>=BUY2FROM && w[0]<=BUY2TO && wl<=BUY1LIMIT && w[0] > m[0])
        {
            EnterBuy(lt);
            return;        
        }
        
       
      if(g_state==BCLOSE && w[0]<=SELL2FROM && w[0]>=SELL2TO && wl>=SELL1LIMIT && w[0] < m[0])
        {
            EnterSell(lt);
            return;        
        }
    }
  }

O código de completo do expert advisor pode ser encontrado no arquivo anexado testEAbasket1.mq5.

Para testar, usamos o timeframe H1. Neste timeframe, foi registrado o número máximo de transações, e o resultado foi fortemente negativo. Este resultado pode ser visto no último artigo, por isso não repetiremos o teste aqui.

Realizamos o teste com ajuda do padrão deste artigo, como um filtro no intervalo anual. Temos o seguinte resultado:

O uso do padrão deste artigo como um filtro deu resultados claramente positivos! Obtivemos uma curva bastante suave, com uma clara tendência de incremento do lucro. Infelizmente, não há tantos trades quanto gostaríamos. Além disso, ao implementar o expert advisor em timeframe grandes, esse número diminui ainda mais.

O relatório de teste completo se encontra no arquivo anexado Tester_EURUSD_Filter.zip.

Fim do artigo

Terminamos o teste de padrões que surgem na aplicação de indicadores combinados com base em osciladores para uma única cesta de moedas tomada separadamente. Ele foi baseado no WPR combinado; os resultados podem ser propagados aos indicadores RSI e Stoch.

Porém, temos de admitir que ainda estamos longe de quaisquer implementações práticas dos padrões. As estatísticas acumuladas não são suficientes. Isso vale também para os intervalos de teste e os parâmetros dos padrões em si. A seleção do período da MA, neste artigo, continua em discussão.

Contudo, temos resultados interessantes.

  1. Estimamos a localização dos níveis de sobrevenda/sobrecompra e verificamos a perspectiva de trabalho com eles.
  2. Avaliamos as perspectivas de implementação do padrão de cruzamento entre o gráfico do indicador combinado e o da média móvel.
  3. Consideramos a possibilidade de utilização conjunta dos padrões das duas questões anteriores.

Podemos dizer que demos o primeiro passo para a aplicação deste método, para efeitos práticos.

Programas utilizados no artigo:

 # Nome
Tipo
 Descrição
1 testWPR&MA.mq5 Indicador
Indicador para verificar o número de cruzamentos entre o gráfico do indicador combinado e o da média móvel.
2
testEAbasket.mq5 Conselheiro
Expert para teste.
3
testEAbasket.zip Arquivo Relatórios padrão - em formato html - sobre o trabalho do expert advisor testEABasket.mq5 com uma cesta baseada no USD.
 4 testEAbasket1.zip Arquivo Relatórios padrão - em formato html - sobre o trabalho do expert advisor testEABasket.mq5 com uma cesta baseada no USD, e primeiro filtro.
5
testEAbasket2.zip Conselheiro Relatórios padrão - em formato html - sobre o trabalho do expert advisor testEABasket.mq5 com uma cesta baseada no USD, e dois filtros.
 6  testEAbasketFinal.mq5 Conselheiro
Versão final do expert advisor testEAbasket.mq5.
7 testEAbasket1.mq5
Conselheiro Expert para teste.
 8  Tester_EURUSD_Filter.zip Arquivo Arquivo com relatórios de teste do expert advisor testEAbasket1.mq5.


Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/3818

Arquivos anexados |
testWPRuMA.mq5 (6.02 KB)
Tester_EURUSD.zip (276.97 KB)
testEAbasket1.mq5 (5.14 KB)
testEAbasket.mq5 (5.29 KB)
testEAbasket1.zip (148.42 KB)
testEAbasket2.zip (145.62 KB)
testEAbasket.zip (581.26 KB)
Decompondo as entradas em indicadores Decompondo as entradas em indicadores
Diferentes situações acontecem na vida do trader. Muitas vezes, tentamos restaurar uma estratégia por meio do histórico de trades bem-sucedidos, no entanto, ao observar o histórico de perdas procuramos aperfeiçoar e melhorá-la. E, de fato, em ambos os casos, comparamos as transações com indicadores conhecidos. Este artigo sugere métodos de comparação de lotes de trades com uma série de indicadores.
R quadrado como uma estimativa da qualidade da curva de saldo da estratégia R quadrado como uma estimativa da qualidade da curva de saldo da estratégia
Este artigo descreve a construção do R² - critério de otimização personalizado. Esse critério pode ser usado para estimar a qualidade da curva de saldo de uma estratégia e para selecionar as estratégias mais consistentes e lucrativas. O trabalho discute os princípios de sua construção e os métodos estatísticos utilizados na estimativa de propriedades e qualidade desta métrica.
Indicador NRTR e módulos de negociação baseados nele para o Assistente MQL5 Indicador NRTR e módulos de negociação baseados nele para o Assistente MQL5
Este artigo descreve o indicador NRTR e módulos de negociação criados com sua ajuda. Para estes fins, é criado um módulo de sinais de negociação que permite criar estratégias baseadas nas combinações do NRTR e indicadores adicionais que confirmam a tendência.
Mini-emulador do mercado ou Testador de estratégias manual Mini-emulador do mercado ou Testador de estratégias manual
O mini-emulador do mercado é um indicador projetado para emulação parcial do trabalho no terminal. Presumivelmente, ele pode ser usado no teste de estratégias "manuais" de análise e negociação no mercado.