Os indicadores das tendências micro, média e principal

Dmitriy Skub | 10 fevereiro, 2014

Introdução

No prefácio de seu livro "Pattern, Price & Time: Using Gann Theory in Trading Systems" James Hyerczyk escreveu:

"Minha experiência em negócios futuros tem me mostrado que, com demasiada frequência, os comerciantes se tornaram viciados em qualquer padrão, preço ou o tempo em sua análise. Eles tendem a ponderar sua análise de uma forma sem equilíbrio. Os erros mais comuns são sistemas construídos em torno do tempo para entrada e para saída do preço, ou o preço para entrada e hora para saída. Além disso, os comerciantes que usam padrões muitas vezes entram ou saem por preços mais pobres ou com o tempo ruim. Estas observações forneceram mais evidências de que a combinação de todos os três métodos seja necessária para o sucesso no mercado. é nesta premissa que eu baseei meu livro".

Não se pode concordar com esta afirmação. Vamos tentar entender como usar alguns desses métodos na prática. O assunto deste artigo é investigar a possibilidade de automação do comércio e a análise, com base em algumas das ideias descritas no livro, sob a forma de indicadores e EAs. Portanto, para entender melhor o material, recomenda-se ler o livro (ou pelo menos a primeira parte dele - o modelo) antes de ler este artigo.


1.1 A micro tendência

O gráfico de uma tendência menor é mostrado na Figura 1. Vamos considerar brevemente as regras para a construção de uma tendência menor:


Figura 1. Tendências menores

Figura 1. Tendências menores

Quando a direção do movimento do gráfico é alterada, forma-se os chamados picos menores e fundos. Os fundos menores na Figura 1 são marcados pela etiqueta de preço esquerda em vermelho, e os picos menores são marcados com etiqueta de preço direita em verde.

Se, durante o movimento ascendente, a direção foi alterada para baixo mas não chegou a última parte inferior, então temos um movimento corretivo. Caso contrário, houve uma mudança na direção. Este é o mesmo para o movimento ascendente.

Portanto, o preço alterna entre os fundos e picos. Tais movimentos são chamados balanços. Ao mesmo tempo, movimentos de correção podem ser gerados.

Aqui estão em resumo as regras para a construção da linha do indicador da micro tendência. Uma descrição mais detalhada pode ser encontrada na primeira parte do livro. O gráfico deste indicador gráfico se assemelha ao de um indicador de zigue-zague bem conhecido. Mas, ao contrário dele, não é redesenhado após o encerramento de uma outra barra, e não tem parâmetros ajustáveis externos que afetam a construção da linha.


1.2. O indicador GannMicroTrend

Vamos desenvolver indicadores que mostram o gráfico da micro.tendência. A aparência deve ser a mesma que na Figura 1. Vamos também incluir a saída para a visualização da última posição dos picos e fundos em relação ao tempo. Este indicador está localizado no arquivo GannMicroTrend.mq5, anexado a este artigo.

Para exibir essas informações, use a biblioteca descrita no artigo Crie sua própria cotação de mercado usando as classes da biblioteca padrão. Para fazer isso, no início do texto do nosso indicador, adicione a diretriz #incluir:

#include  <TextDisplay.mqh>

Supõe-se que o arquivo acima está localizado na pasta \ MQL5 \Include.

O indicador deve armazenar nas variáveis globais, os parâmetros da tendência atual e os parâmetros do pico e fundos mais recentes. Além disso, deve haver a possibilidade de especificar a profundidade do cálculo para o número dado de barras no histórico.

Para fazer isso, adicione os parâmetros externos especificados:

input int     MaxBars = 1000;
input bool    IsSaveTrendParams = true;
//---------------------------------------------------------------------
input bool    ShowInfo = true;
input int     UpDownInfoShift = 1;
input int     LeftRightInfoShift = 1;
input color   TitlesColor = LightCyan;
input color   TopFieldsColor = Green;
input color   LowFieldsColor = Brown;
//---------------------------------------------------------------------
input color   UpTrendColor = LightGreen;
input color   DnTrendColor = LightPink;
input int     LineWidth = 4;
//---------------------------------------------------------------------
input color   UpStopLossColor = Green;
input color   DnStopLossColor = Brown;
input int     StopLossWidth = 1;

O propósito desses parâmetros é mostrado na seguinte tabela:

O nome do parâmetro

O propósito do parâmetro

MaxBars

O número máximo de barras no histórico do qual o indicador é extraído. Se for 0, então, todas as barras disponíveis no histórico são contadas e extraídas.

IsSaveTrendParams

Se for exato, então os parâmetros para a tendência atual e os parâmetros dos últimos picos e fundos são armazenados em variáveis ​globais.

ShowInfo

Se for exato, então a janela do gráfico mostra as coordenadas dos últimos picos e fundos.

UpDownInfoShift

Um deslocamento vertical de cima para baixo do local de saída de informações.

LeftRightInfoShift

Um deslocamento horizontal da esquerda para a direita do local de saída de informações.

TitlesColor

A cor dos cabeçalhos durante a saída de informações.

TopFieldsColor

A cor do texto durante a saída dos parâmetros do último pico.

LowFieldsColor

A cor do texto durante a saída dos últimos fundos.

UpTrendColor

A cor do desenho de linha do movimento ascendente.

DnTrendColor

A cor do desenho de linha do movimento descendente.

LineWidth

A largura das linhas de tendência.

UpStopLossColor

A cor da etiqueta de preço certo indicando os picos.

DnStopLossColor

A cor da etiqueta de preço certo indicando os fundos.

StopLossWidth

O tamanho da etiqueta de preço indicando os picos e fundos.


Construiremos a linha de tendência usando os objetos gráficos do tipo CChartObjectTrend a partir do conjunto de classes padrões. Os picos secundários serão marcados pela etiqueta de preço esquerda - pelos objetos do tipo CChartObjectArrowLeftPrice, enquanto que os fundos secundários - pelos objetos do tipo CChartObjectArrowRightPrice. Todos esses objetos estão contidos nas classes da biblioteca padrão que acompanham o terminal MetaTrader 5.

Uma vez que no futuro talvez precisemos da manipulação das linhas de tendência, assim como os picos/fundos, vamos armazená-los em uma lista de objetos do tipo CList, também a partir de um conjunto de classes padrões. Para fazer isso, adicione ao início do indicador as diretrizes da inclusão dos arquivos de cabeçalho:

#include  <Arrays\List.mqh>
#include  <ChartObjects\ChartObjectsLines.mqh>
#include  <ChartObjects\ChartObjectsArrows.mqh>

Em seguida, adicione os objetos de listas:

CList*  trend_list_Ptr = NULL;  // list of the trend lines
CList*  up_list_Ptr = NULL;     // list of the peaks
CList*  dn_list_Ptr = NULL;     // list of the bottoms

Agora temos todos os elementos necessários para a construção do indicador.

A função OnInit do indicador é a seguinte:

int OnInit()
{
  trend_list_Ptr = new CList();
  if(CheckPointer(trend_list_Ptr) != POINTER_DYNAMIC)
  {
    Print("Error of creating the object CList #1");
    return(-1);
  }

  up_list_Ptr = new CList();
  if(CheckPointer(up_list_Ptr) != POINTER_DYNAMIC)
  {
    Print("Error of creating the obkect CList #2");
    return(-1);
  }

  dn_list_Ptr = new CList();
  if(CheckPointer(dn_list_Ptr) != POINTER_DYNAMIC)
  {
    Print("Error of creating the object CList #3");
    return(-1);
  }

  if(InitGraphObjects() != 0)
  {
    Print("Error of creating the object TableDisplay");
    return(-1);
  }

  return(0);
}

Aqui são criados os indicadores para o objeto de listas, então o êxito da criação é verificado. Se o indicador não é válido, uma mensagem de erro é recebida e com isso o trabalho do indicador está concluído. O lugar onde ocorreu o erro pode ser identificado pelo número com o caractere #. Em seguida, a tabela para exibir os parâmetros para os últimos picos e fundos é inicializada. Isto é feito no código de função InitGraphObjects.

A parte principal do nosso indicador - é o manipulador de eventos na necessidade de realizar cálculos. Esta é a função OnCalculate. Vamos considerá-la parte por parte. A primeira parte - a verificação da necessidade de recalcular toda a parte exibida do indicador. Essa necessidade surge, por exemplo, quando o indicador é iniciado no primeiro gráfico, quando baixar e atualizar histórico no gráfico, quando uma mudança no prazo ocorreu. Em todos estes casos, o valor do argumento prev_calculated é igual a zero.

Isto é verificado da seguinte forma:

int index, start = prev_calculated - 1;

if(prev_calculated == 0)
{
  if(CheckPointer(trend_list_Ptr) != POINTER_INVALID)
  {
    trend_list_Ptr.Clear();
  }
  if(CheckPointer(up_list_Ptr) != POINTER_INVALID)
  {
    up_list_Ptr.Clear();
  }
  if(CheckPointer(dn_list_Ptr) != POINTER_INVALID)
  {
    dn_list_Ptr.Clear();
  }

//  Determine the bar number of the beginning of calculations:
  if(MaxBars > 0 && rates_total > MaxBars)
  {
    start = rates_total - MaxBars;
  }
  else
  {
    start = 0;
  }
  time_prev = 0;
  trend_prev = 0;
}

Se houver a necessidade de recalcular o indicador inteiro, então limpamos a lista de linhas de tendência e as listas de picos/fundos. Além disso, esses objetos gráficos também são excluídos do gráfico. Em seguida, determinamos o número da barra a partir do qual é necessário para se iniciar o cálculo do indicador - a variável inicial. Se o valor da variável externa MaxBars é maior do que zero e menor do que o número de barras no gráfico rates_total, então a barra de partida para o cálculo será igual a:

    start = rates_total - MaxBars;
    

Lembre-se que a indexação das barras de uma time-series começa do zero (a barra recente).

Se o valor da variável externa MaxBars é igual a zero (o que significa que precisamos calcular o indicador em todas as barras do gráfico) ou maior do que o número de barras do gráfico, então precisamos recalcular todos os valores do indicador para todas as barras do gráfico, ou seja, inicial é igual a zero.

Em seguida, há um ciclo de cálculo da linha de tendência e as posições dos picos/fundos secundários. A análise dos valores mínimos e máximos dos preços das barras de acordo com as regras acima é bastante simples e não requer nenhuma explicação adicional (veja o texto de origem no arquivo GannMicroTrend.mq5).

Para desenhar as seções de uma linha de tendência usamos a seguinte função:

//---------------------------------------------------------------------
//  Drawing of a section
//---------------------------------------------------------------------
void  CreateCut(datetime _dt1, double _prc1, datetime _dt2, double _prc2, color _clr, int _wd)
{
  string  name = GetUniqName(prefix + " ");
  CChartObjectTrend*  trend_obj = new CChartObjectTrend();
  if(CheckPointer(trend_obj) != POINTER_INVALID)
  {
    trend_obj.Create(0, name, 0, _dt1, _prc1, _dt2, _prc2);
    trend_obj.Color(_clr);
    trend_obj.Width(_wd);
    trend_list_Ptr.Add(trend_obj);
  }
}
    

Aqui usamos a função para obter dentro do gráfico um nome único GetUniqName, descrito em detalhes no artigo Crie sua própria cotação de mercado utilizando as classes da biblioteca padrão.. No caso de uma construção bem sucedida da linha de tendência do objeto gráfico, seus parâmetros são especificados (cor e espessura da linha) e esse objeto é adicionado à lista de linhas chamando o CList:: Adicionar método.

Para extrair a posição dos picos/fundos secundários, usamos as funções CreateUpStopLoss/CreateDnStopLoss, respectivamente. Elas são semelhantes à função CreateCut e adicionam os objetos criados para as suas listas.

Após a finalização do cálculo, os parâmetros dos últimos fundos e picos são mostrados. Aqui usamos as listas criadas no passo anterior. Nós obtemos estas listas já classificadas por tempo de acordo com o seu aumento e por chamando o CList:: Método GetLastNode, obtém-se o mais recente objeto de um pico ou um fundo.

O resultado do trabalho do indicador descrito é apresentado na figura seguinte:

Figura 2. O indicador de uma tendência menor

Figura 2. O indicador de uma tendência menor


2.1. A tendência média

O gráfico da evolução média reflete o movimento do mercado, delineado por duas barras (movimentos de duas barras). O gráfico de uma tendência média é mostrado na Figura 2. Vamos considerar brevemente as regras para a construção do gráfico das tendências médias:

Figura 3. A tendência intermediária

Figura 3. A tendência média

O único indicador da reversão de tendência média ascendente - é o cruzamento do nível de pico médio. Da mesma forma, o único indicador da reversão descendente - é o cruzamento do nível de fundo médio.

Se a tendência média é ascendente e o mercado faz um balanço médio descendente, mas não anula o fundo anterior do balanço médio, é uma correção. Se a tendência média é descendente e o mercado faz um balanço médio ascendente, mas não anula o pico anterior do balanço médio, também é uma correção.


2.2. O indicador GannMicroTrend

Vamos desenvolver indicadores que mostram o gráfico da tendência média. A aparência deve ser a mesma que na Figura 2. Além disso, as posições dos últimos picos e fundos devem ser exibidas na tela. Este indicador pode ser encontrado no arquivo anexado ao artigo GannMiddleTrend.mq5.

Neste indicador, para a restituição dos elementos do gráfico, usaremos o buffer indicador e o tipo de desenho DRAW_COLOR_SECTION. Vamos precisar disso mais tarde no desenvolvimento da EA. Para acessar os dados desse indicador da EA, usamos o indicador buffer.

Os parâmetros do indicador na tela de exibição são especificados pelas seguintes diretrizes:

#property indicator_buffers    2
#property indicator_plots      1
#property indicator_type1      DRAW_COLOR_SECTION
#property indicator_color1     LightGreen, LightPink
#property indicator_width1     4

Aqui especificamos sequencialmente:

Na função de inicialização OnInit ligamos o alocado para os indicadores buffers e especificamos alguns outros parâmetros indicadores.

Isto é feito pelo seguinte fragmento do código:

SetIndexBuffer(0, DataBuffer, INDICATOR_DATA);
SetIndexBuffer(1, ColorBuffer, INDICATOR_COLOR_INDEX);

IndicatorSetInteger(INDICATOR_DIGITS, Digits( ));
IndicatorSetString(INDICATOR_SHORTNAME, "GannMiddleTrend");
PlotIndexSetString(0, PLOT_LABEL, "GannMiddleTrend");
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);

Aqui especificamos sequencialmente:

O indicador é semelhante em estrutura e em parâmetros externos ao indicador da micro tendência GannMicroTrend. A diferença é que ele usa uma atribuição direta dos valores no buffer indicador e o buffer de cor, em vez de usar objetos gráficos. Portanto, não vamos nos alongar nos detalhes de implementação.

O resultado do trabalho do indicador é mostrado na figura seguinte:

Figura 4, O indicador de tendência intermediária

Figura 4, O indicador de tendência intermediária

Como pode ser visto, coincide com o desenho à mão na Figura 3.


3.1. A tendência principal

O gráfico da evolução principal reflete o movimento do mercado, delineado por três barras (movimentos de três barras). A aparência do gráfico de uma tendência principal é mostrado na Figura 5. Vamos considerar em resumo as regras para a construção da tendência principal:

Figura 5. A tendência principal

Figura 5. A tendência principal

O único indicador da reversão de tendência principal ascendente - é o cruzamento do nível de pico principal. Da mesma forma, o único indicador da reversão descendente - é o cruzamento do nível de fundo principal.

Se a tendência principal é ascendente e o mercado forma um balanço descendente, mas não anula o balanço do fundo anterior, é uma correção. Se a tendência principal é descendente e o mercado forma um balanço ascendente, mas não anula o balanço do pico anterior, é também uma correção.


3.2. O indicador GannMainTrend

Vamos desenvolver indicadores que mostram o gráfico da tendência principal. A aparência deve ser a mesma que na Figura 5. Além disso, as posições dos últimos picos e fundos devem ser exibidas na tela. Este indicador está localizado no arquivo GannMainTrend.mq5, anexo a este artigo.

O indicador é idêntico na sua estrutura e parâmetros externos ao indicador de tendência média GannMiddleTrend, portanto, não vamos nos alongar nos detalhes da implementação. O resultado do trabalho do indicador é mostrado na figura seguinte:

Figura 6. O indicador da tendência principal

Figura 6. O indicador da tendência principal


4. Comércio usando a tabela de balanços

Então, nós temos um instrumento para analisar o mercado em termos do Modelo - os indicadores das micro, média e principais tendências. Agora vamos tentar desenvolver um sistema de comércio simples com base nas oscilações de preços.

No livro de James Hyerczyk, ele propõe a seguinte estratégia:

Vamos ilustrar isso em um desenho:

Figura 7. Balanço de negociação

Figura 7. Balanço de negociação

Em níveis extremamente elevados de preços, recomenda-se considerar a possibilidade de ir curto e, em níveis extremamente baixos de preços, as possibilidades de ir longo. A Figura 7 ilustra o gráfico da tendência média. Vamos identificar as seções com os movimentos de longo prazo pelo gráfico da tendência principal. Vamos identificar as seções do mercado "estagnado" pelo gráfico de tendência média. A posição será monitorada pelo gráfico de tendência média.

Aqui está o que a mesma seção se parece no gráfico de tendência principal:

Figura 8. A seção na tabela de tendência principal

Figura 8. A seção na tabela de tendência principal

Um movimento descendente de longo prazo (balanço) é entre o pico principal 1.36913 e o fundo principal 1.18758. Este movimento leva 1815.5 pontos de quatro dígitos. Em seguida, vem a seção do mercado "estagnado" com uma tendência quase horizontal de 1.24664-a 1.21495 (ver Figura 7). Este movimento leva 316.9 pontos. Depois disso, o preço rompe o nível do pico intermediário do último balanço sobre o gráfico de tendência intermediária e sobe.

Montamos a parada inicial logo abaixo do fundo intermediário e do mais recente balanço 1.21495, e monitoramos a posição no gráfico da tendência intermediária. Como resultado desse comércio, vamos obter um lucro de cerca de 1.31186-1.23966 = 722.0 pontos.


5. Classe de sinais de comércio para uso no Assistente MQL5

Antes de criar o código para a implementação do nosso sistema de negociação, vamos imaginar esquematicamente todo o percurso do comércio. Considere a seguinte ilustração:

Figura 9. Posições comerciais longas

Figura 9. Posições comerciais longas

O ajuste da posição de COMPRA consiste no seguinte:

O ajuste da posição de VENDA consiste em imagens espelhadas de ação:


Assim, para construir um Expert Advisor, precisamos dos seguintes componentes: um módulo para gerar sinais de compra/venda, um módulo de rastreamento da parada de posição aberta e, possivelmente, um módulo responsável pela posição de "pirâmide" (gestão de dinheiro).

Ao escrever esta parte, foram utilizados os seguintes artigos: Assistente MQL5: Como criar um módulo de sinais de comércio, Assistente MQL5: Como criar um módulo de rastreamento de posições abertas, Assistente MQL5: Como criar um módulo de gerenciamento de risco e dinheiro.

O desenvolvimento do módulo responsável pela geração de sinais de transação consiste no seguinte:

#include <Expert\ExpertSignal.mqh>
Insira esta diretriz no início do nosso módulo de geração de sinal de comércio.
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signal based on swings on charts                           |
//| of the middle and main trends according to Gann (iCustom)        |
//| Type=Signal                                                      |
//| Name=TGannBreakSignal                                            |
//| Class=TGannBreakSignal                                           |
//| Page=                                                            |
//| Parameter=MinMainSwingContinuance,int,5                          |
//| Parameter=MinMainSwingSize,double,300.0                          |
//| Parameter=MinMiddleSwingContinuance,int,3                        |
//| Parameter=MaxMiddleSwingSize,double,200.0                        |
//| Parameter=OpenPriceSpace,double,5.0                              |
//| Parameter=StopLossSpace,double,5.0                               |
//+------------------------------------------------------------------+
// wizard description end

Aqui vemos o parâmetro Título, o qual especifica o nome do módulo que aparece na lista MetaEditor' durante a geração do EA (ver descrição abaixo). Um parâmetro importante - Tipo, que determina que o dado módulo é um módulo de geração de sinal. Além disso, os parâmetros externos e seus valores padrões estão presentes.

Todas essas linhas são adicionadas imediatamente após a diretriz de inclusão do arquivo padrão ExpertSignal.mqh.

class TGannBreakSignal : public CExpertSignal
  {
private:
   int               min_main_swing_continuance;    // minimum swing duration time of the main tren
   double            min_main_swing_size_points;    // minimum swing amplitude on the chart of the main trend
   int               min_middle_swing_continuance;  // minimum swing duration time on the chart of the middle trend
   double            max_middle_swing_size_points;  // maximum swing amplitude of the chart of the middle trend
   double            open_price_space;              // distance between the open price and peak/bottom
   double            stop_loss_space;               // distance between the stop loss price and peak/bottom

   datetime          main_swing_lf_datetime;        // time of left point of a swing on the chart of the main trend
   double            main_swing_lf_price;           // price of left point of a swing on the chart of the main trend
   datetime          main_swing_rt_datetime;        // time of right point of a swing on the chart of the main trend
   double            main_swing_rt_price;           // price of right point of a swing on the chart of the main trend
   int               main_swing_continuance;        // swing duration time on the chart of the main trend
   double            main_swing_size_points;        // swing amplitude (in points) on the chart of the main trend

   datetime          middle_swing_lf_datetime;      // time of left point of a swing on the chart of the middle trend
   double            middle_swing_lf_price;         // price of left point of a swing on the chart of the middle trend
   datetime          middle_swing_rt_datetime;      // time of right point of a swing on the chart of the middle trend
   double            middle_swing_rt_price;         // price of right point of a swing on the chart of the middle trend
   int               middle_swing_continuance;      // swing duration time on the chart of the middle trend
   double            middle_swing_size_points;      // swing amplitude (in points) on the chart of the middle trend

   int               handle_main_swing;
   int               handle_middle_swing;
   double            main_swing_buff[];
   double            middle_swing_buff[];
   datetime          time_buff[];
   double            price_buff[];
public:
                     TGannBreakSignal();   // constuctor
                    ~TGannBreakSignal();   // destructor
   //   Settings:
   void              MinMainSwingContinuance(int _cont);
   void              MinMainSwingSize(double _size);
   void              MinMiddleSwingContinuance(int _cont);
   void              MaxMiddleSwingSize(double _size);
   void              OpenPriceSpace(double _space);
   void              StopLossSpace(double _space);

   int               GetMainSwingContinuance();    // gets swing duration time on the chart of the main trend
   double            GetMainSwingSizePoints();     // gets swing amplitude (in 4-digit points) on the chart of the main trend
   int               GetMiddleSwingContinuance();  // gets swing duration time on the chart of the middle trend
   double            GetMiddleSwingSizePoints();   // gets swing amplitude (in 4-digit points) on the chart of the middle trend
   
   // overloaded methods of the CExpertSignal class:
   virtual bool      ValidationSettings();
   virtual bool      CheckOpenLong(double &price,double &sl,double &tp,datetime &expiration);
   virtual bool      CheckOpenShort(double &price,double &sl,double &tp,datetime &expiration);
   virtual bool      InitIndicators(CIndicators *indicators);

   //   Additional methods:
protected:
   //   Sets swing parameters of the main trend
   void              SetMainSwingParameters(datetime _lf_dt,double _lf_price,datetime _rt_dt,double _rt_price);
   //   Sets swing parameters of the middle trend
   void              SetMiddleSwingParameters(datetime _lf_dt,double _lf_price,datetime _rt_dt,double _rt_price);
   // Gets swing parameters of the main trend
   int               GetMainSwing();                  
   // Gets swing parameters of the middle trend
   int               GetMiddleSwing( );                
  };

O objetivo dos membros de dados é claro a partir dos comentários. Considere alguns dos métodos da classe.

Primeiro de tudo, precisamos redefinir os métodos da classe base. O primeiro método é usado para verificar a exatidão dos parâmetros externos específicos da EA:

//---------------------------------------------------------------------
// Validation of settings
//---------------------------------------------------------------------
bool TGannBreakSignal::ValidationSettings()
  {
   if(this.min_main_swing_continuance<=0)
     {
      Print("Wrong Parameter: min_main_swing_continuance = ",
           this.min_main_swing_continuance);
      return(false);
     }
   if(this.min_main_swing_size_points<=0.0)
     {
      Print("Wrong Parameter: min_main_swing_size_points = ",
            DoubleToString(this.min_main_swing_size_points,1));
      return(false);
     }
   if(this.min_middle_swing_continuance<=0)
     {
      Print("Wrong Parameter: min_middle_swing_continuance = ",
             this.min_middle_swing_continuance);
      return(false);
     }
   if(this.max_middle_swing_size_points<=0.0)
     {
      Print("Wrong Parameter: max_middle_swing_size_points = ",
             DoubleToString(this.max_middle_swing_size_points,1));
      return(false);
     }

   return(true);
  }

Aqui, fazemos uma simples verificação dos parâmetros externos para correção. é claro que a amplitude do balanço (em pontos) e a sua duração em barras não pode ser menor ou igual a zero. Em caso de parâmetros externos incorretamente especificados, o método retorna falso.

Em seguida, vamos considerar os métodos de geração de sinais para a abertura de posições.

A seleção para a necessidade de abrir uma posição longa é feita pelo seguinte método, herdado da classe base:

//---------------------------------------------------------------------
// Checks conditions to open long position
//---------------------------------------------------------------------
bool TGannBreakSignal::CheckOpenLong(double &_price,double &_sl,
                                         double &_tp,datetime &_expiration)
  {
   if(this.GetMainSwing()==-1)
     {
      return(false);
     }

   if(this.GetMiddleSwing()==-1)
     {
      return(false);
     }

// If the main swing upward, exit
   if(this.main_swing_rt_price>=this.main_swing_lf_price)
     {
      return(false);
     }

// If the middle weak swing isn't formed, exit:
   if(this.middle_swing_rt_price>=this.middle_swing_lf_price)
     {
      return(false);
     }

// Check swing parameters on the main trend chart
   if(this.main_swing_continuance<this.min_main_swing_continuance ||
     this.main_swing_size_points<this.min_main_swing_size_points)
     {
      return(false);
     }

// Check swing parameters on the middle trend chart
   if(this.middle_swing_continuance<this.min_middle_swing_continuance ||
      this.middle_swing_size_points>this.max_middle_swing_size_points)
     {
      return(false);
     }

   double unit=this.PriceLevelUnit();

// If the price has crossed the peak of the weak middle swing, set signal to open long position:
   double delta=this.m_symbol.Bid()
             -(this.middle_swing_lf_price+this.open_price_space*unit);
   if((delta>=0.0) && (delta<(10.0*unit)))
     {
      _price=0.0;
      _sl = this.m_symbol.NormalizePrice(this.middle_swing_rt_price - stop_loss_space*unit);
      _tp = 0.0;

      return(true);
     }

   return(false);
  }

Em primeiro lugar, dois métodos para a obtenção dos parâmetros dos últimos balanços são chamados para os gráficos das tendências principais e intermediárias - TGannBreakSignal::GetMainSwing e TGannBreakSignal::GetMiddleSwing. Se esses métodos foram bem sucedidos, então podemos analisar os parâmetros dos balanços.

Uma vez que estamos verificando a presença de um sinal para abrir uma posição longa, as oscilações devem ser decrescentes. Nós comparamos as posições dos pontos A e B (ver Fig. 9) - se o ponto B tem um preço mais baixo do que o ponto A, então, as oscilações de preço foram decrescentes.

Em seguida, verificar a presença de pontos C e D (ver Figura 9). Além disso, o ponto D deve ter um preço mais baixo do que o ponto C. Se esta condição for satisfeita, então vamos verificar os parâmetros de balanços das tendências principais e intermediárias. A duração e a magnitude do movimento está verificada.

Se todas as verificações anteriores foram bem sucedidos, então, a última verificação é realizada - com ou sem o preço ter cruzado o pico da oscilação intermediária. Se o fez, em seguida, preencher o valor de parada e retornar o resultado verdadeiro.

A seleção para a necessidade de abrir uma posição curta é feita pelo seguinte método, herdado da classe base: CheckOpenShort, que executa as verificações semelhantes as do método TGannBreakSignal:: CheckOpenLong, mas em uma imagem espelhada no eixo do preço.

Assim, analisamos a estrutura e os métodos básicos do módulo responsáveis pela geração de sinais de negociação. O módulo descrito está anexado a este artigo no arquivo GannTrendSignal.mqh.

O segundo módulo que vamos precisar - é o módulo de rastreamento de parada de uma posição aberta. Este módulo também é desenvolvido com base nas classes padrões, e consiste no seguinte:

Isto é feito da seguinte forma:

#include <Expert\ExpertTrailing.mqh>

Inserir esta diretriz no início do módulo de posição posterior.

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Trailing on peaks/bottoms on the chart of the middle trend |
//| Type=Trailing                                                    |
//| Name=MiddleTrend                                                 |
//| Class=MiddleTrendTrailing                                        |
//| Page=                                                            |
//| Parameter=StopLossSpace,double,5.0                               |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+

Aqui, o tipo de parâmetro é definido igual ao valor de "Rastreamento" - isso indica que este módulo deve ser usado para apoiar a posição (rastreamento). Além disso, os parâmetros externos e seus valores padrões estão presentes.

Todas essas linhas são adicionadas imediatamente após a diretriz de inclusão do arquivo padrão ExpertTrailing.mqh.

class MiddleTrendTrailing : public CExpertTrailing
  {
private:
   datetime          middle_swing_lf_datetime;  // time of left point of a swing on the chart of the main trend
   double            middle_swing_lf_price;     // price of left point of a swing on the chart of the main trend
   datetime          middle_swing_rt_datetime;  // time of right point of a swing on the chart of the main trend
   double            middle_swing_rt_price;     // price of right point of a swing on the chart of the main trend
   double            stop_loss_space;           // the distance between peak/bottom and stop loss price

   int               handle_middle_swing;
   double            middle_swing_buff[];
   datetime          time_buff[];
   double            price_buff[];
public:
                     MiddleTrendTrailing();     // constructor
                    ~MiddleTrendTrailing();     // destructor
private:
   int               GetMiddleSwing();          // get parameters of the middle swing

public:
   //   Settings:
   void              StopLossSpace(double _space);
   //   Overloaded methods of CExpertTrailing class:
   virtual bool      ValidationSettings();
   virtual bool      InitIndicators(CIndicators *indicators);
   virtual bool      CheckTrailingStopLong(CPositionInfo *position,double &sl,double &tp);
   virtual bool      CheckTrailingStopShort(CPositionInfo *position,double &sl,double &tp);
  };
    

Os métodos básicos, redefinidos em nossa classe - MiddleTrendTrailing:: CheckTrailingStopLong e MiddleTrendTrailing:: CheckTrailingStopShort. Esses dois métodos verificam as condições de modificação da parada-perda para uma posição longa e curta, respectivamente.

Considere o método MiddleTrendTrailing:: CheckTrailingStopLong mais detalhado:

//--------------------------------------------------------------------+
// Checks conditions of trailing stop for long position               |
//--------------------------------------------------------------------+
bool MiddleTrendTrailing::CheckTrailingStopLong(CPositionInfo *_position,double &_sl,double &_tp)
  {
   if(_position==NULL)
     {
      return(false);
     }

   if(this.GetMiddleSwing()==-1)
     {
      return(false);
     }

   double sl_req_price = this.m_symbol.NormalizePrice(MathMin(middle_swing_lf_price,middle_swing_rt_price)
                      - this.stop_loss_space * this.m_adjusted_point );
   if(_position.StopLoss() >= sl_req_price )
     {
      return(false);
     }

   _tp = EMPTY_VALUE;
   _sl = sl_req_price;

   return(true);
  }

Primeiro vamos chamar o método para a obtenção dos parâmetros do último balanço para o gráfico de tendência média - TGannBreakSignal:: GetMiddleSwing. Se este método tiver êxito (retornou um valor zero), é possível analisar os parâmetros dos balanços.

Em seguida, calcula-se o nível de preço para colocar a parada-perda na base dos parâmetros do balanço obtido. Se o nível de parada-perda calculado é menor do que o atual (para a posição longa), então preenchemos a parâmetro do método_sl novo valor sl_req_price e retorna verdadeiro. Caso contrário, retorna falso - isso sugere que o nível de parada-perda não requer modificação.

O método de verificação da necessidade de modificar a parada-perda por posições curtas é construído de forma análoga.

Assim, analisamos a estrutura e os métodos básicos do módulo responsáveis pelo rastreamento de uma posição aberta (rastreamento). O módulo descrito está anexo a este artigo no arquivo GannTrailing.mqh.


A geração de EA na base dos sinais de comércio


A geração do EA por um modelo usando o "Masters MQL5", é uma tarefa bastante simples. Trata-se de uma sequência de passos:

Usando os comandos do menu principal MetaEditor'a File / New, chame o controlador da geração de EA. A tela mostra uma janela de diálogo da seguinte exibição:

Figura 10. Criação de diálogo Expert Advisor pronto em MQL5 Assistente

Figura 10. Criação de diálogo Expert Advisor pronto em MQL5 Assistente

Selecione a opção "botão de rádio" com a inscrição "EA (Gerar)" e clique no botão "Próximo" - ir para a próxima etapa de geração da EA.


Nesta etapa, nós especificamos os parâmetros gerais da EA - o nome, o número "mágico", etc. A seguinte janela de diálogo é exibida:

Figura 11. Propriedades gerais do Expert Advisor

Figura 11. Propriedades gerais do Expert Advisor

Especificar o valor do parâmetro EveryTick em verdadeiro - precisamos do trabalho da EA para cada tick, o número "mágico" pode ser deixado inalterado. Pressione o botão "Próximo" e siga para a próxima etapa.


Neste passo, especifique os parâmetros dos sinais para a EA. Primeiro, selecione o tipo particular de um sinal da lista:

Figura 12. A seleção do módulo de sinais de comércio

Figura 12. A seleção do módulo de sinais de comércio

Selecione o nome do nosso sinal, escrito anteriormente, e o diálogo do seguinte tipo aparece na tela:

Figura 13. Parâmetros de entrada do módulo de sinais do mercado

Figura 13. Parâmetros de entrada do módulo de sinais do mercado

Aqui podemos corrigir o necessário para padronizarmos os valores dos parâmetros Novamente, pressione o botão "Próximo" e siga para a próxima etapa.


Nesta etapa, selecione o tipo de rastreamento para apoiar a posição aberta. Podemos escolher qualquer um da lista, mas vamos selecionar o método de rastreamento-parada desenvolvido anteriormente:

Figura 14. Selecionar o tipo de posição de rastreamento

Figura 14. Selecionar o tipo de posição de rastreamento

Obtemos a seguinte janela de diálogo:

Figura 15. Especificação dos parâmetros de rastreamento

Figura 15. Especificação dos parâmetros de rastreamento

Aqui, podemos ajustar os valores padrões para os parâmetros externos especificados. Pressione o botão "Próximo" e siga para a próxima etapa.


Figura 16. Especificação dos parâmetros de gestão de dinheiro

Figura 16. Especificação dos parâmetros de gestão de dinheiro

Aqui podemos selecionar os parâmetros para a gestão do capital (o método de cálculo do lote de trabalho). Deixar como está - a negociação com um volume de comércio fixo. Pressionar o botão "Concluído" obtém uma EA gerada pronta com um nome especificado, algoritmo de posição de abertura, rastreamento e as regras de gestão de capital.

Testar a EA gerada para se certificar de que está funcionando:

Figura 17. Testar o Expert Advisor criado

Figura 17. Testar o Expert Advisor criado

Podemos ver que as tendências que foram corretamente identificadas, foram tiradas completamente (na medida em que este método permite). Além disso, foram utilizados os parâmetros padrões especificados por considerações gerais.


Conclusão

De fato consideramos apenas a primeira parte da teoria de Gann e sua aplicação em sistemas de comércio e análise de mercado - o modelo. Parece que os melhores resultados da sua aplicação são conseguidos durante esses períodos de tempo, em que a divisão do gráfico em barras corresponde à organização natural do comércio.

Para os mercados de ações - isso é comércio usando intervalos diários, semanais e mensais. Para os mercados de moeda - isso é comércio usando intervalos de sessões. Para os mercados de mercadorias - isso é o comércio utilizando não apenas os intervalos diários, semanais e mensais, mas também flutuações periódicas no mercado.


Pós-conclusão

Eu decidi fazer uma pequena pesquisa extra, não diretamente relevante para o tema, mas com respeito a ideia de Gann. Mais especificamente, à questão: O preço, durante o seu movimento, marca os chamados níveis "redondos"? Ou seja, os níveis de preços, terminando com os números 50 e 100 para as moedas euro e ações (para o iene japonês, um nível de preço "redondo" é um que termina em 40).

Para isso, vamos construir um diagrama de distribuição de picos/fundos nos últimos números após o ponto decimal. Para as cotações de cinco dígitos, existem os três últimos dígitos depois do ponto decimal (o último dígito - décimos de um ponto). Usaremos o gráfico de tendência intermediária para barras diárias.

Em um eixo circular, marcamos os últimos dígitos do preço, de zero a cinquenta (redondo para os décimos de um ponto), enquanto que no eixo vertical - o número de picos/fundos formados nesses níveis. Construí-lo separadamente para os picos, fundos e a figura total.

Aqui está o que nós temos para alguns dos principais pares de moeda no intervalo do ano de 2000 a 2011 e um prazo diário:






Como podemos interpretar esses resultados? Primeiro de tudo, há distorções nos diagramas. Ou seja, nem todos os valores de preços são igualmente susceptíveis a formar picos/fundos. Em segundo lugar, esses valores não coincidem exatamente com os valores "redondos" - que é o que foi basicamente esperado. Se isso pode ou não ser utilizado para o comércio é difícil de se dizer. Isso requer uma pesquisa mais séria. Talvez resultados mais interessantes, do ponto de vista prático, podem ser obtidos no mercado de ações.

Pelo menos, este é mais um instrumento para a análise da história e não o pior entre sua espécie.