Uma Nova Abordagem para a Interpretação da Divergência Clássica e Oculta

22 novembro 2017, 08:49
Alexander Lasygin
0
1 861

Introdução

Os traders costumam usar métodos de análise técnica clássica. No entanto, existem muitas maneiras e abordagens diferentes, que também podem ser úteis. Neste artigo, eu sugiro um método não convencional para buscar e interpretar divergências. Com base nesta abordagem, nós criaremos uma estratégia de negociação.

Definição de Divergência/Convergência

O movimento no mercado continua enquanto os participantes do mercado tiverem vontade e dinheiro para negociar. Então, mais cedo ou mais tarde, chega um momento em que todos os participantes já estão no mercado, e não há mais ninguém para mover o preço. Tais situações podem acontecer com bastante frequência no mercado. Dependendo da direção da tendência, elas são chamadas de estado de sobrecompra ou sobrevenda do mercado.

O estado de sobrecompra pode ocorrer em mercados financeiros, de ações ou de futuros. Isso mostra que aqueles que queriam comprar ativos já compraram, então não há ninguém para mover o preço.

O estado de sobrevenda é uma situação oposta. Isso mostra que aqueles que queriam vender ativos já venderam, então não há mais ninguém para mover o preço para baixo.

O estado de sobrecompra/sobrevenda não aparece do nada. Sabe-se que o preço forma um movimento ondulatório. Os traders acompanham as mudanças de preços comparando o gráfico de preços com os gráficos de indicadores ou osciladores. Quando o comportamento do indicador é diferente da direção do movimento do preço, uma convergência é formada no mercado em baixa e a divergência é formada no mercado em alta.

Tipos de Divergência

Diferentes pesquisadores fornecem diferentes classificações de divergência/convergência do mercado. Nós usaremos aquele que divide a divergência/convergência em clássico e oculta.

Divergência Clássica

A divergência clássica pode ser identificada comparando com as atualizações do preço de Máxima/Mínima com os mesmos momentos no gráfico do indicador. Se o gráfico de preços formou outra máxima ou mínima e no gráfico do indicador isso não aconteceu, é um sinal de divergência. O mercado está sobrecomprado/sobrevendido, por isso não é aconselhável abrir negociações na direção atual da tendência.

A divergência clássica é amplamente descrita em vários recursos. Dependendo das características da divergência, ela pode ser dividida em três subclasses

  • Classe A. Ela ocorre com mais frequência do que nas outras classes. Quando a máxima/mínima do ativo for atualizada, o indicador começa a reverter, o que é uma indicação de divergência e possível reversão futura.
  • Classe B. Ela é semelhante a classe A, exceto que o preço do ativo não pode romper um extremo e formar o padrão de reversão Topo/Fundo Duplo, enquanto o indicador não atingir o seu extremo.
  • Classe C. A máxima ou mínima do preço é atualizada e o indicador forma o padrão Topo/Fundo Duplo.

A divergência/convergência pode ser repetida várias vezes seguidas, combinando diferentes classes e criando assim um modelo de reversão mais forte. Cada classe deve ser analisada separadamente em cada caso. Nós não podemos dizer inequivocamente qual é o mais forte ou o mais fraco. Nós vamos analisar os motivos para isso mais tarde.

Divergência Oculta

Esse tipo de divergência também pode ser dividido em subclasses:

  • Máximas decrescentes do preço acompanhadas de máximas ascendentes dos osciladores mostram a confirmação de uma tendência de baixa.
  • Mínimas ascendentes do preço, acompanhadas de mínimas decrescentes dos osciladores mostram a confirmação de uma tendência de alta.


Na figura acima, nós podemos ver claramente o mercado ascendente, mas o MACD formou uma nova mínima, o que não é confirmado pelo gráfico de preços. Esta discrepância sugere a presença de uma divergência altista oculta e indica o fortalecimento da tendência de alta.

Indicadores e Osciladores para a Busca de Divergências/Convergências. Como funciona?

Quais indicadores podem mostrar divergência e convergência? Um indicador técnico deve poder determinar os níveis de oferta e demanda, bem como acompanhar o momentum. Os seguintes indicadores podem ser usados ​​para os propósitos acima: osciladores, estocásticos, RSI, CCI etc. e o indicador de tendência com os elementos do oscilador - MACD. O MACD pode ser interpretado como a divergência e a convergência das médias móveis. O indicador rastreia eficientemente discrepâncias no movimento do preço e seu momentum. Muitos traders fazem suas decisões baseadas em convergência/divergência usando o MACD.

No entanto, seria errado recomendar qualquer uma das ferramentas acima para trabalhar com divergência. Todo trader deve escolher um indicador adequado às suas estratégias de negociação específicas e trabalhar de forma eficiente sem sobrecarregar o gráfico de preços. Assim, a recomendação geral é a seguinte: verifique a lista de indicadores, teste-os, selecione um deles e opere com os seus sinais sem focar em outros fatores.

Além disso, a divergência pode ser facilmente determinada sem indicadores. Em primeiro lugar, você deve entender os conceitos básicos da formação de divergências.

O momentum desempenha um papel importante na formação da divergência. Nós entendemos que a diminuição da amplitude do movimento após um forte impulso é um sinal para a formação de divergências.


A figura acima mostra este exemplo. Quando uma nova baixa é formada, o tamanho da nova onda é menor que a anterior. Neste caso, nós podemos esperar uma divergência emergente.

O exemplo abaixo mostra a mesma parte do mercado com o indicador RSI confirmando a hipótese acima.


Embora a divergência possa ser facilmente determinada, esse método não está completo sem o uso de indicadores. Não vemos as linhas de convergência/divergência. Portanto, vamos considerar vários indicadores que são mais utilizados para identificar esse padrão.

O Oscilador RSI

O oscilador RSI possui os valores entre -100 e 100, que representam zonas de sobrevenda e sobrecompra, respectivamente. Todos os sinais emergentes nessas zonas são considerados fortes e os sinais de divergência são ainda mais fortes.

Entre as desvantagens deste método está o fato de que o indicador é muito sensível às flutuações de preços. Isso dificulta a identificação de topos e fundos usando este indicador. O gráfico de preços precisa ser analisado. Isso leva a um atraso na detecção do sinal.

O Oscilador Estocástico

Os parâmetros padrão a seguir são usados ​​para o oscilador:

  • Período %K: 5
  • Período %D: 3
  • Retardo: 3

Semelhante ao RSI, o oscilador estocástico possui zonas de sobrecompra e sobrevenda. A divergência ou convergência nessas zonas aumentam significativamente as chances de ter resultados positivos de negociação.

A desvantagem do estocástico é a aparição frequente de divergências, ou seja, muitos sinais falsos. Todos os sinais devem ser interpretados como um aviso de possíveis mudanças, portanto, é necessário usar técnicas adicionais para determinar os pontos de entrada no mercado.

O Oscilador MACD

O MACD é um oscilador interessante que também pode ajudar a determinar divergências. O indicador é usado com parâmetros padrão:

  • EMA rápida: 12
  • EMA lenta: 26
  • MACD SMA: 9


Uma das regras para determinar a divergência usando o MACD é a seguinte: as barras dos osciladores não devem cruzar o nível zero. A imagem abaixo mostra que, neste caso, a divergência não é óbvia, então as chances de ter uma negociação lucrativa são baixas.

Ao contrário dos indicadores anteriores, este gera menos sinais. Mas é um indicador de tendência e, portanto, informa sobre mudanças globais no mercado. Apesar de todas as vantagens, a entrada no mercado precisa ser confirmada pela análise da ação do preço (Price Action) ou padrões de velas.

O Indicador Volumes

O volume é outra característica importante. Um dos sinais de reversão mais fortes é a divergência/convergência do preço e do volume. A ideia é a seguinte:

Um movimento ascendente continua enquanto novos volumes fluem para dentro do mercado. Em um dos rompimentos de máxima, nós vemos a redução do volume, o que significa que os compradores deixam de fornecer dinheiro ao mercado. Nós podemos concluir que o preço está sobrecomprado e é provável que ocorra um movimento de baixa. A situação descrita é mostrada na figura abaixo.

Neste contexto, eu vejo OBV como um indicador mais interessante. Ele fornece bons sinais de entrada no mercado com base nesta divergência oculta.

Quanto à divergência clássica em OBV, muitas vezes ela indica apenas a desaceleração e a transição para a consolidação.


Regras para a Determinação da Divergência/Convergência. Como Operar Divergência

Vamos discutir os erros comuns que os traders costumam fazer ao tentar encontrar uma convergência/divergência e executar uma negociação baseada nesse padrão.

  • A presença de uma tendência é obrigatória; A divergência não funciona em mercado lateralizado.
  • Além da divergência, você deve confirmar as entradas usando Price Action ou velas japonesas (candlesticks).
  • Não espere que tenha encontrado um sinal 100%. Existe sempre a possibilidade de um erro. Portanto, ao realizar operações de negociação, você deve observar as regras gerais de negociação.
  • Não determine a divergência com base em velas que são construídas usando indicadores de notícias. Devido à alta volatilidade durante os lançamentos de notícias, tais velas geralmente produzem sinais falsos.
  • A divergência deve ser explícita. Você deve ter certeza de que o sinal está visível não só para você, mas também para os outros participantes do mercado. A chance de tomar uma decisão certa pode aumentar apenas neste caso.
  • Apenas analise os topos e fundos mais próximos. Isso dá uma compreensão mais clara da situação. Ao usar indicadores de tendência, como o MACD, a interseção da linha zero pode enfraquecer o sinal ou até mesmo cancelá-lo.

Uma Nova Abordagem

Nós consideramos regras comuns para o uso e construção do padrão de divergência. Agora, nós analisaremos o uso não convencional de divergências na negociação. Em nosso trabalho, nós não aplicaremos regras padrão e, adicionalmente, nós usaremos um indicador absolutamente não convencional.

Nós vamos conduzir nossa experiência com base no clássico Oscilador Acelerador de Bill Williams. A escolha não é acidental. A direção do indicador muda antes de qualquer alteração na força da tendência, enquanto a direção da força da tendência muda antes da alteração do preço. AO é um sinal de confirmação precoce, que oferece vantagens óbvias. Nós podemos receber sinais de divergência antes e com mais frequência. Normalmente, essa solução levaria ao aumento do ruído, mas, no nosso caso, nós temos mais sinais de entrada no mercado e sinais de desaceleração anteriores.

Nós já consideramos as regras comuns para o uso e construção de divergências. Esta variante de uso da divergência não é padrão. Nós ainda observamos essas regras comuns, ao usar uma maneira incomum de determinar os pontos de entrada.

O objetivo principal desta ferramenta é encontrar divergências, portanto suas variáveis ​​só contêm um parâmetro — o número de barras usadas para determinar a divergência.

#property indicator_separate_window
//---- Um buffer é usado para calcular e desenhar o indicador
#property indicator_buffers 2
//---- Somente uma construção gráfica é usada
#property indicator_plots 1
//---- O indicador é desenhado como uma linha
#property indicator_type1 DRAW_COLOR_HISTOGRAM
//---- A cor azul é usada para a linha do indicador
#property indicator_color1 Green,Red
//----
#property indicator_width1 2
//---- A linha do indicador é uma curva contínua
#property indicator_style1 STYLE_SOLID
//---- Exibição do rótulo do indicador
#property indicator_label1 "AC_Div"
//+------------------------------------------------------------------+
input int Bars_Calculated=1000;
//+------------------------------------------------------------------+
string shortname="";
double AC_buff[];
double Color_buff[];
int wid;
int Handle_AC;
//---
#define DATA_LIMIT 37

O indicador é inicializado com os parâmetros predefinidos do histograma multicolorido.

//+------------------------------------------------------------------+
//| Função de inicialização do indicador personalizado               |
//+------------------------------------------------------------------+
int OnInit()
 {
//---- Definição dos arrays dinâmicos como o buffer do indicador
 SetIndexBuffer(0,AC_buff,INDICATOR_DATA);
 SetIndexBuffer(1,Color_buff,INDICATOR_COLOR_INDEX);
//---- Definir da posição, a partir da qual o desenho do indicador começa
 PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,DATA_LIMIT);
//---- Inicialização de uma variável para o nome curto do indicador
 shortname="Accelerator_Divergence";
//---- Criando um nome para exibição em uma sub-janela separada e em uma dica de ferramenta
 IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//---- Definindo a precisão da exibição dos valores dos indicadores
 IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//---- Desativando o desenho de valores vazios do indicador
 PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
 PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
//--- Formando o identificador do indicador de Aceleração
 Handle_AC=iAC(NULL,0);
//--- Buscando o índice da sub-janela do gráfico
 wid=ChartWindowFind(0,shortname);
//---
 return(INIT_SUCCEEDED);
 }

O código de cálculo do indicador principal consiste em duas partes.

A primeira parte é o indicador básico.

//---- Declarando as variáveis ​​locais 
 int limit,bar,pos;
//---- Verificação se o número de barras é suficiente para os cálculos
 if(rates_total<DATA_LIMIT)
 return(0);
 int barsCalculated=MathMin(Bars_Calculated,rates_total);
//+------- Definição da direção de indexação do array ---------------+
 ArraySetAsSeries(close,true);
 ArraySetAsSeries(AC_buff,true);
 ArraySetAsSeries(low,true);
 ArraySetAsSeries(high,true);
 ArraySetAsSeries(Color_buff,true);
 ArraySetAsSeries(time,true);
//+--- Determinação do número de barras necessárias para o cálculo --+
 limit=rates_total-DATA_LIMIT-1;
 if(prev_calculated>0) limit=rates_total-prev_calculated;
 pos=limit;
 if(pos>barsCalculated)pos=limit;
 int to_copy;
 if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
 else
 {
 to_copy=rates_total-prev_calculated;
 if(prev_calculated>0) to_copy++;
 }
//---
 if(IsStopped()) return(0); //Verificação do sinalizador de stop
//+----- Formando o array principal ---------------------------------+
 if(CopyBuffer(Handle_AC,0,0,to_copy,AC_buff)<=0)
 {
 Print("getting Accelerator Handle is failed! Error",GetLastError());
 return(0);
 }
//+---------- Colorindo o histograma --------------------------------+
 for(bar=limit; bar>=0 && !IsStopped(); bar--)
 {
 Color_buff[bar]=0.0;
 if(AC_buff[bar]<AC_buff[bar+1])Color_buff[bar] =1.0;
 if(AC_buff[bar]>AC_buff[bar+1])Color_buff[bar] =0.0;
 }

A segunda parte inclui a busca de discrepâncias.

//+----------- Detectando divergências de alta -----------------------+
 int bars=barsCalculated;
 for(bar=pos; bar>=0 && !IsStopped(); bar--)
 {
 int l=bar+2;
 if(Extremum(AC_buff[l+1],AC_buff[l],AC_buff[l-1])<0)
 {
 int i=l;
 int counted=LastPeak(l,bars,AC_buff);
 if(counted!=-1)
 {
 if(AC_buff[i]<AC_buff[counted] && high[i]>high[counted])
 {
 DrawPriceTrendLine(time[i],time[counted],high[i],high[counted],Red,STYLE_SOLID);
 DrawIndicatorTrendLine(time[i],time[counted],AC_buff[i],AC_buff[counted],Red,STYLE_SOLID);
 }

 if(AC_buff[i]>AC_buff[counted] && high[i]<high[counted])
 {
 DrawPriceTrendLine(time[i],time[counted],high[i],high[counted],Red,STYLE_DOT);
 DrawIndicatorTrendLine(time[i],time[counted],AC_buff[i],AC_buff[counted],Red,STYLE_DOT);
 }
 }
 }
//+----------- Detectando divergências de baixa ----------------------+
 if(Extremum(AC_buff[l+1],AC_buff[l],AC_buff[l-1])>0)
 {
 int i=l;
 int counted=LastTrough(l,bars,AC_buff);
 if(counted!=-1)
 {
 if(AC_buff[i]>AC_buff[counted] && low[i]<low[counted])
 {
 DrawPriceTrendLine(time[i],time[counted],low[i],low[counted],Green,STYLE_SOLID);
 DrawIndicatorTrendLine(time[i],time[counted],AC_buff[i],AC_buff[counted],Green,STYLE_SOLID);
 }
 if(AC_buff[i]<AC_buff[counted] && low[i]>low[counted])
 {
 DrawPriceTrendLine(time[i],time[counted],low[i],low[counted],Green,STYLE_DOT);
 DrawIndicatorTrendLine(time[i],time[counted],AC_buff[i],AC_buff[counted],Green,STYLE_DOT);
 }
 }
 }
 }

Para reduzir o volume do código, as construções gráficas e a função de busca da máxima/mínima são fornecidas separadamente.

//+----- Busca da segunda máxima extrema ----------------------------+
int LastPeak(int l,int bar,double &buf[]) 
 {
 for(int i=l+5; i<bar-2; i++)
 if(Extremum(buf[i+1],buf[i],buf[i-1])<0)return (i);
 return (-1);
 }
//+----- Busca da segunda mínima extrema ----------------------------+
int LastTrough(int l,int bar,double &buf[])
 {
 for(int i=l+5; i<bar-2; i++)
 if(Extremum(buf[i+1],buf[i],buf[i-1])> 0)return (i);
 return (-1);
 }
//+-- Busca por um extremo -----------------------------------------+
int Extremum(double a,double b,double c)
 {
 if((a-b)*(b-c)<0)
 {
 if(c>b && b<0) return(1); //DN extremum
 if(c<b && b>0) return(-1);//UP extremum
 }
 return(0);
 }
//+------ Criando objetos no gráfico de preços ----------------------+
void DrawPriceTrendLine(datetime T_0,
 datetime T_1,
 double P_0,
 double P_1,
 color color_0,
 int style)
 {
 string name_2=shortname+DoubleToString(T_0,0);
 string name_0;
 name_0=shortname+"Line_Sn"+ColorToString(color_0);
//--- 
 if(ObjectFind(0,name_2)<0)
 drawLineS(name_2,T_0,T_1,P_0,P_1,color_0,style,0,true,false,0);
//+-----------+
 if(style==STYLE_DOT)
 drawLineS(name_0,T_1,T_0,P_1,P_0,clrAqua,0,3,true,true,0);
 }
//+------ Criando objetos na janela do indicador --------------------+
void DrawIndicatorTrendLine(datetime T_0,
 datetime T_1,
 double P_0,
 double P_1,
 color color_0,
 int style)
 {
 string name_1,name_0;
 int window= wid;
 name_1 = shortname+DoubleToString(T_0+wid,0);
 if(ObjectFind(0,name_1)<0)
 drawLineS(name_1,T_0,T_1,P_0,P_1,color_0,style,0,false,false,window);
//---
 if(style==STYLE_SOLID)
 {
 name_0=shortname+"Line_Pn"+ColorToString(color_0);
 drawLineS(name_0,T_1,T_0,P_1,P_0,clrMagenta,style,2,true,true,window);
 }
 }
//+------------------------------------------------------------------+
void drawLineS(string name,
 datetime t0,
 datetime t1,
 double p0,
 double p1,
 color clr,
 int style,
 int width,
 bool back,
 bool ray,
 int window)
 {
 ObjectDelete(0,name);
 ObjectCreate(0,name,OBJ_TREND,window,t0,p0,t1,p1,0,0);
 ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,ray);
 ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
 ObjectSetInteger(0,name,OBJPROP_STYLE,style);
 ObjectSetInteger(0,name,OBJPROP_WIDTH,width);
 ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
 ObjectSetInteger(0,name,OBJPROP_BACK,back);
 }
//+------------------------------------------------------------------+


Para a conveniência da análise visual, nós usamos uma linha sólida para a divergência clássica e uma linha pontilhada para a divergência oculta. A cor vermelha é usada para as divergências de baixa, e a verde é usada para divergências de alta. Os raios espessos mostram a última divergência de alta/baixa oculta no gráfico de preços, enquanto que as divergências clássicas são exibidas na janela do indicador. Além disso, eu vou explicar essas regras de visualização. O indicador ficará assim:


Princípios Básicos da Estratégia

A análise das tabelas de preços e o indicador mostraram que a linha prolongada da divergência inversa na tabela de preços e a da divergência clássica no gráfico do indicador tornam-se um nível de suporte e resistência inclinado. Um rompimento dessas linhas caracteriza novos comportamentos de mercado a curto e longo prazo.

Exemplo de rompimento das linhas de suporte formada pela divergência oculta e localizado no gráfico de preços:


No exemplo seguinte, as barras do histograma romperam as linhas de divergência clássicas na janela do indicador:


Após o rompimento, os papéis das linhas geralmente se alteram. Ou seja, um nível de suporte quebrado se transforma em uma resistência:

Nos basearemos em nossa estratégia sob estes recursos comportamentais.


Princípio de Negociação

Você pode negociar com ambas ordens pendentes e a mercado. O tempo gráfico e o tempo de negociação não são significativos. A regra principal é a convicção do rompimento das linhas. Ao negociar ordens pendentes, nós colocamos elas na Máxima/Mínima da vela de rompimento ou na vela, na qual a barra do histograma é formada. A vela deve estar na direção do rompimento. Em outras palavras, se a linha for quebrada para cima, a vela deve fechar em compra e vice-versa. 

A figura abaixo mostra um gráfico de preços, em que a divergência oculta foi quebrada com confirmação: há um sinal para abrir uma posição comprada, na qual é confirmada. Na janela do indicador, a linha de divergência clássica está rompida, então há um sinal para abrir uma posição vendida que não é confirmada mais tarde.


A figura seguinte mostra outra situação: um sinal de compra é formado quando a linha de divergência clássica na janela do indicador está rompida. O sinal é confirmado posteriormente.

Abaixo está outro exemplo interessante. Dois sinais aparecem simultaneamente em uma vela: um sinal de compra e um sinal de venda. Neste caso, nós podemos verificar os valores do oscilador. Mas mesmo que ignoremos o oscilador, nós veremos apenas os disparadores de ordem exigidos, de modo que a operação de venda seja confirmada. Além disso, há outro sinal de venda, o que intensifica o anterior. Ele permite aumentar a posição do volume e assim aumentar os lucros.


Um sinal de venda clássico:

A figura abaixo mostra um sinal de venda (que depois é cancelado pelo oscilador) e dois sinais de compra.


Os stops loss são definidos abaixo do extremo local mais próximo. O take profit é definido em níveis de suporte/resistência. Os níveis de suporte/resistência podem ser definidos em nossas linhas durante a negociação de contra tendência. Mas, neste caso, tenha cuidado, uma vez que a situação do mercado pode mudar dramaticamente e você pode precisar ajustar o nível de take profit.

Em intervalos de tempo mais baixos (М1-М15), o preço retorna frequentemente à linha após a fuga, formando o padrão 1-2-3 que intensifica o sinal. Portanto, se o mercado não estiver ativo o suficiente, você deve esperar até que o preço quebre a máxima ou mínima da vela, confirmando a entrada no mercado. Claro, a interpretação clássica da divergência também é válida. Embora o oscilador não seja tão importante quanto em outras estratégias e é usado principalmente para construções gráficas, ainda é recomendado levar em consideração o comportamento do oscilador na negociação. O indicador AO é usado em uma ampla variedade de estratégias. Uma combinação do AO e a abordagem descrita podem aumentar significativamente a eficácia de tais estratégias.

Para testar a viabilidade de nossa estratégia, vamos criar um Expert Advisor de negociação usando ordens pendentes. O principal problema é que não podemos usar uma simples chamada de indicador dentro do Expert Advisor. Nesse caso, o indicador não irá desenhar nada na janela do indicador. Uma vez que precisamos das construções gráficas, nós inseriremos parte do código do indicador no código do EA.

input double InpLots =0.1;           // Lotes
input int InpTakeProfit =150;        // Take Profit (em pips)
input int InpStopLoss =60;           // StopLoss (em pips)
input int InpTrailingStop =25;       // Nível do Stop Móvel (em pips)
input int InpOffset =5;              // Distância do preço (em pips)
input int InpDellOorder =30;         // Distância para remoção da ordem (em pips)
//---
int ExtTimeOut=10;                   // intervalo de tempo entre as operações de negociação em segundos
int barsCalculated=1000;
datetime t=0;
datetime time[];


Além das variáveis ​​tradicionais, como Lotes, TakeProfit, StopLoss e TrailingStop, nós adicionamos o Offset e DellOorder. O primeiro define a distância (pip) entre a ordem e Máxima/Mínima do rompimento da vela. Se a ordem ainda não tiver sido disparada e o preço alterar a direção oposta na distância da DellOorder (pip), a ordem deve ser excluída.

Este Expert Advisor não é original, então nós só discutiremos os principais pontos. Nós não usaremos filtros de negociação, mas nós modificamos o código original.

//+------------------------------------------------------------------+
//| Cálculo Básico                                                   |
//+------------------------------------------------------------------+
 for(int bar=1; bar>0 && !IsStopped() && t!=time[0]; bar--)
 {
 int l=bar+1;
 int p1=0,p2=0;
 //+----------- Detectando divergências de alta -----------------------+
 if(Extremum(m_buff_ind[l+1],m_buff_ind[l],m_buff_ind[l-1])<0)
 {
 int i=l;
 int counted=LastPeak(l,bars,m_buff_ind);
 if(counted!=-1)
 {
 if(m_buff_ind[i]<m_buff_ind[counted] && high[i]>high[counted] && !d1)
 { drawLine("Buy_1",time[i],time[counted],m_buff_ind[i],m_buff_ind[counted],Red,1); d1=true;}
 //---
 if(m_buff_ind[i]>m_buff_ind[counted] && high[i]<high[counted] && !d2)
 {
 p1=ArrayMaximum(high,i-1,5);p2=ArrayMaximum(high,counted-2,5);
 drawLine("Buy_2",time[p1],time[p2],high[p1],high[p2],Red,0);d2=true;
 }
 }
 }
 //+----------- Detectando divergências de baixa ----------------------+
 if(Extremum(m_buff_ind[l+1],m_buff_ind[l],m_buff_ind[l-1])>0)
 {
 int i=l;
 int counted=LastTrough(l,bars,m_buff_ind);
 if(counted!=-1)
 {
 if(m_buff_ind[i]>m_buff_ind[counted] && low[i]<low[counted] && !d3)
 { drawLine("Sell_1",time[i],time[counted],m_buff_ind[i],m_buff_ind[counted],Green,1);d3=true;}
 //---
 if(m_buff_ind[i]<m_buff_ind[counted] && low[i]>low[counted] && !d4)
 {
 p1=ArrayMinimum(low,i-1,5);p2=ArrayMinimum(low,counted-2,5);
 drawLine("Sell_2",time[p1],time[p2],low[p1],low[p2],Green,0);d4=true;
 }
 }
 }
 if(d1 && d2 && d3 && d4)break;
 t=time[0];
 }
//---
 }

Nós entendemos que o extremo do indicador não será necessariamente um extremo no gráfico de preços. Portanto, para corrigir as distorções relacionadas em nossos gráficos, nós adicionamos duas funções ArrayMinimum e ArrayMaximum (destacadas). Essas funções permitem identificar Máxima e a Mínima na parte do gráfico de preços onde o indicador extremo é formado. Além disso, para eliminar as pequenas flutuações do indicador ao redor da linha zero e os falsos sinais associados, nós modificamos a fórmula para determinar a máxima/mínima. Agora, ela só leva em consideração os valores dos indicadores com um potencial comum (positivo ou negativo).

//+-- Busca por um extremo -----------------------------------------+
int Extremum(double a,double b,double c)
 {
 if(((a-b)*(b-c)<0) && ((a>0 && b>0 && c>0) || (a<0 && b<0 && c<0)))
 {
 if(c>b && b<0) return(1); //DN extremum
 if(c<b && b>0) return(-1);//UP extremum
 }
 return(0);
 }
//+------

Nós também usamos a função ObjectGetValueByTime para determinar o valor da linha em uma determinada coordenada de tempo. Esta função é usada muitas vezes. Por conveniência, ela será adicionada separadamente.

//+------------------------------------------------------------------+
//|Retorna o valor do preço para o tempo especificado do objeto especificado|
//+------------------------------------------------------------------+
double CSampleExpert::ValueByTime(string label,int i)
 {
 double p=0.0;
//---
 p=ObjectGetValueByTime(0,label,time[i],0);
 return(p);
 }
//+------------------------------------------------------------------+

Como nós já mencionamos, nós não usaremos filtros de negociação. Nós não pretendemos criar um robô de negociação completo, nós queremos apenas avaliar a eficácia da estratégia. Portanto, o módulo de sinais é muito simples. Nós determinamos se a linha está rompida na direção desejada e em que direção o preço (o indicador) está se movendo atualmente.

//+------------------------------------------------------------------+
//| Verificando as condições para abrir uma posição vendida          |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortOpened(void)
 {
 bool res=false;
//---
 double pp1=EMPTY_VALUE,pp2=EMPTY_VALUE,pp3=EMPTY_VALUE,
 pp4=EMPTY_VALUE,pp5=EMPTY_VALUE,pp6=EMPTY_VALUE;
//---
 if(ObjectFind(0,"Sell_2")!=-1)
 {
 pp1=ValueByTime("Sell_2",1);
 pp2=ValueByTime("Sell_2",2);
 pp3=ValueByTime("Sell_2",3);
 }
 if(ObjectFind(0,"Sell_1")!=-1)
 {
 pp4=ValueByTime("Sell_1",1);
 pp5=ValueByTime("Sell_1",2);
 pp6=ValueByTime("Sell_1",3);
 }
//--- Verificando a possibilidade de uma posição vendida (SELL) 
 if((pp1!=EMPTY_VALUE && close[1]<pp1 && close[2]>pp2&&close[0]<close[1])||
 (pp4!=EMPTY_VALUE && m_ind_1>m_ind_0 && ((m_ind_1<pp4 && m_ind_2>pp5) ||(m_ind_2<pp5 && m_ind_3>pp6))))
 {
 //--- Nós precisamos encerrar o EA em qualquer caso
 res=true;
 }
//--- resultado
 return(res);
 }
//+------------------------------------------------------------------+


A parte acima mostra um bloco para entrar em posições vendidas. As entradas compradas são semelhantes.

Depois de receber um sinal (rompimento da linha), nós estabelecemos uma ordem apropriada na distância InpOffset do extremo da vela que era máxima ou mínima perto da vela de rompimento. Se esta vela for um rompimento, a ordem é colocada diretamente nesta vela. 

//+------------------------------------------------------------------+
//| Abertura de uma posição por sellstop                             |
//+------------------------------------------------------------------+
bool CSampleExpert::OpenSellStop(void)
 {
 bool res=false;
//--- Buscando uma barra com o menor mínima entre as velas mais próximas
 int i=ArrayMinimum(low,0,3);
//---
 if(ShortOpened())
 {
 double offset=InpOffset;                          // distância da parte inferior da vela para colocar uma ordem, pips
 double limit_price=m_symbol.Bid();
 double price=low[i]-offset*m_adjusted_point;;
 double tp =price-m_take_profit;
 double sl =price+m_stop_losse;
 //--- verifica o saldo da conta
 if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL_STOP,InpLots,price)<0.0)
 printf("We do not have money. Free margin = %f",m_account.FreeMargin());
 else
 {
 //--- Abre uma posição
 if(m_trade.OrderOpen(Symbol(),ORDER_TYPE_SELL_STOP,InpLots,limit_price,price,sl,tp))
 {res=true; printf("Position by %s to be opened",Symbol());}
 else
 {
 printf("Error occurred while opening position SELL STOP %s : '%s'",Symbol(),m_trade.ResultComment());
 printf("Open parameters: price=%f,TP=%f",price,tp);
 }
 }
 }
//--- resultado
 return(res);
 }
//+------------------------------------------------------------------+

Se a ordem não tiver sido acionada e o preço se alterou na direção oposta a uma distância maior do que o InpDellOorder, a ordem deve ser excluída.

//+------------------------------------------------------------------+
//| Excluindo ordens desnecessárias                                  |
//+------------------------------------------------------------------+
bool CSampleExpert::DelOrder(ulong ticket,string type)
 {
 bool res=false;
 if(m_trade.OrderDelete(ticket))
 printf("Position by %s to be opened",Symbol());
 else
 {
 res=true;// Definindo o sinalizador que indica que a ordem não foi excluída
 printf("Error occurred while deleting the order"+type+" %s : '%s'",Symbol(),m_trade.ResultComment());
 }
 return(res);
 }
//+------------------------------------------------------------------+

Voltemos ao nosso objetivo principal, ou seja, para a avaliação da estratégia. A dificuldade na avaliação de estratégias que trabalham com construções gráficas é que elas só podem ser avaliadas no modo visual. A otimização no modo automatizado não é possível. É um processo demorado. Portanto, vamos executar o Expert Advisor no GBPUSD H1, começando no início de 2017. Vamos usar as configurações padrão.

Aqui está o resultado:




Este método dificilmente pode ser chamado de totalmente objetivo. No entanto, os resultados obtidos mostram que a estratégia tem um bom potencial. A longo prazo, após novas melhorias, ele pode se transformar em uma estratégia valiosa.


Conclusões

Essa abordagem nos permitiu criar uma estratégia completamente viável, que, no entanto, permite o uso de outras ferramentas. As desvantagens desta estratégia incluem a construção incorreta e ocasional das linhas do indicador e a necessidade de corrigi-las manualmente. Isso dificulta a automatização da estratégia e, como resultado, a análise. No entanto, a pesquisa mostrou que não só estratégias clássicas podem existir.

Programas usados ​​no artigo:

#NomeTipo Descrição 
1Accelerator_DivIndicador

O indicador que determina a divergência/convergência explícita e oculta com base no indicador Acelerador

2TestExpertExpert Advisor

Um EA para o testador de estratégia


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

Arquivos anexados |
MQL5.zip (10.12 KB)
Otimizando uma estratégia usando o gráfico do saldo e comparando os resultados com o critério "Balance + max Sharpe Ratio" Otimizando uma estratégia usando o gráfico do saldo e comparando os resultados com o critério "Balance + max Sharpe Ratio"

Neste artigo, nós ainda consideramos um outro critério personalizado de otimização de uma estratégia de negociação com base na análise do gráfico de saldo. A regressão linear é calculada usando a função da biblioteca ALGLIB.

Expert Advisor Multiplataforma: Stops personalizados, Breakeven e Stop Móveis Expert Advisor Multiplataforma: Stops personalizados, Breakeven e Stop Móveis

Este artigo discute como os níveis de stop personalizados podem ser configurados em um expert advisor multiplataforma. Ele também discute um método fortemente relacionado ao assunto na qual envolve a possibilidade de definir a evolução do nível de stop ao longo do tempo.

Arbitragem triangular Arbitragem triangular

O artigo é dedicado ao popular método de negociação arbitragem triangular. O assunto é analisado em muitos detalhes, são discutidos os aspectos positivos e negativos da estratégia, é desenvolvido o código pronto para usar do expert.

Lógica Difusa nas estratégias de negociação Lógica Difusa nas estratégias de negociação

O artigo considera um exemplo de aplicação da lógica difusa para construir um sistema de negociação simples, usando a biblioteca Fuzzy. São propostas melhorias ao sistema através da combinação da lógica difusa, algoritmos genéticos e redes neurais.