English Русский 中文 Español Deutsch 日本語 한국어 Français Italiano Türkçe
Explorar as classes de estratégia de negociação da biblioteca padrão - Personalização de estratégias

Explorar as classes de estratégia de negociação da biblioteca padrão - Personalização de estratégias

MetaTrader 5Sistemas de negociação | 12 março 2014, 13:18
3 009 0
Harvester Trading
Harvester Trading

Introdução

Este artigo é direcionado a novatos/iniciantes que desejam abordar alguma forma de personalização com funcionalidade e sem ter que escrever um EA desde o início.

No MetaTrader 5, temos a possibilidade de negociar como especialistas, mesmo com pouco ou nenhum conhecimento (ou habilidades) de linguagem de programação e codificação de fontes, devido a um recurso do MetaEditor: Assistente MQL5. O Assistente (não explicaremos o seu funcionamento detalhado neste artigo) foi criado para gerar programas completos (arquivos .mq5 e .ex5), algoritmos e código. Ele se beneficia com o uso da biblioteca padrão do MQL5 e classes de estratégia de negociação (que são ótimos recursos).

Explorar as classes de estratégia de negociação da biblioteca padrão: Personalização de estratégias

Há diversas classes de estratégia de negociação na biblioteca padrão. Na realidade, algumas delas já são muito boas e são provenientes de estudos mais ou menos famosos sobre mercados financeiros e análise de lucratividade. Há pelo menos uma estratégia para cada indicador do conjunto padrão de indicadores que acompanha o MetaTrader 5.

Para estabelecer sinais de negociação a partir dessas classes de estratégia de negociação, o Assistente MQL5 utiliza um mecanismo que chama os comportamentos do indicador criados por uma lógica codificada na forma de "padrões de negociação". E cada EA específico gerado chama os indicadores (através das instruções #include) e os seus conjuntos de padrões e decisões de negociação serão então importadas para o núcleo do EA para fins de negociação.


Assistente MQL5

O primeiro passo é criar um Expert Advisor utilizando o Assistente MQL5. Para abrir o Assistente MQL5 no MetaEditor, selecione "Novo" no menu "Arquivo" ou pressione o botão "Novo". Em seguida, selecione a opção "Expert Advisor (gerar)".

Figura 1. Criar novo arquivo (selecione a opção

Vamos chamar o nosso Expert Advisor gerado no Assistente MQL5 de "MyExpert".

Figura 2. Nome e parâmetros do EA gerado no Assistente MQL5

Em seguida, adicionamos dois indicadores/sinais para trabalhar com ele (você pode selecionar quantas condições quiser a partir dos indicadores disponíveis). Em nosso exemplo, adicionaremos dois indicadores famosos: índice de Força Relativa (RSI) e Média Móvel (MA). Adicione o indicador RSI primeiro e, em seguida, o indicador MA.

Figura 3. Selecione RSI primeiro e, em seguida, MA

Podemos estabelecer alguns parâmetros, como quisermos, ou manter os parâmetros padrão para o nosso exemplo.

Figura 4. Parâmetros de sinais

Após clicar em OK e continuar o Assistente, não selecionaremos (por enquanto) qualquer limite móvel na próxima janela. Entretanto, se você quiser, poderá adicionar: isso não afetará o tópico deste artigo. Na próxima janela, selecionaremos 5,0 como porcentagem de negociação e 0,1 lotes, ou quaisquer outro parâmetros que você quiser: novamente, isso não afetará o assunto do nosso artigo.


Análise do código gerado

Após a finalização, você terá o arquivo "MyExpert.mq5". Vamos analisar os principais aspectos do código gerado.

//+------------------------------------------------------------------+
//|                                                     MyExpert.mq5 |
//|                                                        Harvester |
//|                        https://www.mql5.com/pt/users/Harvester |
//+------------------------------------------------------------------+
#property copyright "Harvester"
#property link      "https://www.mql5.com/pt/users/Harvester"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\Signal\SignalRSI.mqh>
#include <Expert\Signal\SignalMA.mqh>
//--- available trailing
#include <Expert\Trailing\TrailingNone.mqh>
//--- available money management
#include <Expert\Money\MoneyFixedLot.mqh>

Primeiramente, observe os arquivos #include adicionados ao código gerado pelo Assistente. Podemos observar:

  • Expert.mqh
  • SignalRSI.mq
  • SignalMA.mqh

Após, a seguinte parte do código:

//--- Creating filter CSignalRSI
   CSignalRSI *filter0=new CSignalRSI;
   if(filter0==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating filter0");
      ExtExpert.Deinit();
      return(-3);
     }
   signal.AddFilter(filter0);

Conforme o título sugere, é o "filtro" que será aplicado às condições de mercado do EA gerado que deverá ser anexado a um gráfico ou testado no Strategy Tester. O filter0 é então o primeiro filtro com um "índice" zero e, para este primeiro filtro, selecionamos RSI em nosso exemplo.

CSignalRSI significa sinal de classe RSI. Essa classe é usada para chamar o indicador RSI e aplicá-lo a algumas condições para criar sinais de compra ou de venda através do uso de padrões lógicos do Assistente. RSI é então o nosso primeiro filtro (filtro número 0).

Na seguinte parte do código há alguns parâmetros de filtro e, em seguida, a seção de limite móvel (optamos por não ter) e, após - a parte do código que trata sobre gerenciamento de dinheiro.

Continuando, temos:

//--- Tuning of all necessary indicators
   if(!ExtExpert.InitIndicators())
     {
      //--- failed
      printf(__FUNCTION__+": error initializing indicators");
      ExtExpert.Deinit();
      return(-10);
     }
//--- ok
   return(0);
  }

Esta seção pertence ao arquivo incluso Expert.mqh. Trata sobre a inicialização dos indicadores requeridos para a operação do EA.

E a última parte do código do EA trata sobre a finalização e outros eventos comuns do Expert Advisor:

//+------------------------------------------------------------------+
//| Deinitialization function of the expert                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ExtExpert.Deinit();
  }
//+------------------------------------------------------------------+
//| "Tick" event handler function                                    |
//+------------------------------------------------------------------+
void OnTick()
  {
   ExtExpert.OnTick();
  }
//+------------------------------------------------------------------+
//| "Trade" event handler function                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
   ExtExpert.OnTrade();
  }
//+------------------------------------------------------------------+
//| "Timer" event handler function                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   ExtExpert.OnTimer();
  }
//+------------------------------------------------------------------+

Na realidade, este EA usa dois indicadores (RSI e MA) para as decisões de negociação através da biblioteca padrão de classes de negociação que utilizam a lógica de "filtros" e "pesos". Você pode encontrar mais informações sobre isso na seção Módulos de sinais de negociação da Referência MQL5. Porém, nosso objetivo é utilizar nossas próprias estratégias de negociação como novos filtros.

Para o primeiro passo (utilizando nossas próprias estratégias de negociação) modificaremos um pouco o nosso MyExpert.mq5. Primeiramente, vamos adicionar outro filtro. Este será o filter2 e o colocaremos imediatamente após a porção do filter1 no código.

//--- Creating filter CSignalCCIxx
   CSignalCCIxx *filter2=new CSignalCCIxx;
   if(filter2==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating filter2");
      ExtExpert.Deinit();
      return(-4);
     }
   signal.AddFilter(filter2);
//--- Set filter parameters
   filter2.PeriodCCIxx(Signal_CCIxx_PeriodCCI);
   filter2.Applied(Signal_CCIxx_Applied);
   filter2.Weight(Signal_CCIxx_Weight);

Vamos voltar aos arquivos #include que são o núcleo dos filtros e tomada de decisão do mercado. O primeiro deles é o arquivo #include . Este arquivo incluso, por sua vez, inclui outros arquivos:

  • #include "ExpertBase.mqh"
  • #include "ExpertTrade.mqh"
  • #include "ExpertSignal.mqh"
  • #include "ExpertMoney.mqh"
  • #include "ExpertTrailing.mqh"

Esses arquivos inclusos são respectivamente o gerenciamento da estrutura principal do EA, da estrutura de negociação, do sinal, do dinheiro e do limite móvel. Não analisaremos esses arquivos detalhadamente ou os modificaremos. Nosso objetivo é focar na adição de nossas próprias estratégias através da utilização dos indicadores existentes no grupo padrão de indicadores do MetaTrader 5 e adicionar o arquivo incluso deles.

No código MyExpert.mq5, nós temos os arquivos #include dos indicadores RSI e MA que usamos neste exemplo como sinais/filtros para a decisão de negociação de mercado. Aqui, vamos adicionar nosso próprio arquivo incluso personalizado. Para isso, utilizaremos uma versão modificada ("melhorada") dos sinais pertencentes ao indicador CCI.

//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\Signal\SignalRSI.mqh>
#include <Expert\Signal\SignalMA.mqh>

#include <Expert\Signal\SignalCCIxx.mqh>   // This is our own 'custom' indicator for custom Signal management of the EA

O arquivo SignalCCIxx.mqh deve ser colocado na pasta \MQL5\Include\Expert\Signal\ e deve corresponder à capacidade de integração do EA gerado pelo Assistente, assim como as outras classes de negociação #include da biblioteca padrão - arquivos de sinal já presentes nesta pasta (SignalRSI.mqh e SignalMA.mqh).

Para este exemplo, copiaremos o arquivo CCI original, criando outro arquivo, chamado CCIxx com o código um pouco modificado e usaremos como arquivo #include. Agora, por questão de simplicidade, apenas usaremos uma versão copiada do indicador CCI da biblioteca padrão.

O que temos que fazer é copiar o arquivo "\MQL5\Include\Expert\Signal\SignalCCI.mqh" para o arquivo "\MQL5\Include\Expert\Signal\SignalCCIxx.mqh". A forma mais fácil de fazer isso é criar uma cópia do arquivo na pasta e renomeá-la.

Vamos observar esse arquivo agora. A integração dessa forma 'personalizada' no arquivo MyExpert.mq5 gerado pelo Assistente já é um trabalho finalizado. Nós adicionamos o código filter2, conforme explicado acima, e agora vamos completar o seguinte. O foco agora não é mais o arquivo MyExpert.mq5, e sim o arquivo Signalxx.mqh, que é o núcleo real do EA devido ao seu sinal filter2 do indicador CCI.


Personalização de estratégia

Voltamos a adicionar os filtros de estratégia "semipersonalizados" que chamaremos de CCIxx, que é a versão modificada do SignalCCI.mqh. Definimos como semipersonalizado porque na verdade não se trata de um sinal personalizado totalmente novo, mas sim de uma versão reestruturada do indicador CCI do conjunto de indicadores padrão que acompanham o MetaTrader 5. Dessa forma, mesmo usuários e programadores inexperientes podem modificar um pouco os padrões e filtros de um EA gerado pelo Assistente MQL5 utilizando o grande número de indicadores existentes. Em outras palavras, você pode criar as suas próprias versões de filtros e padrões para gerar sinais de mercado de compra e venda. Esta ainda é uma excelente base para trabalhar com estratégias.

Vamos observar este exemplo. Ele será útil para aqueles que apenas precisam desse recurso (para adicionar alguns padrões personalizados a indicadores existentes) e para aqueles que desejam participar do Campeonado de negociação automatizada somente utilizando o Assistente para criar EAs totalmente funcionais (e válidos) com algum tipo de personalização rapidamente.

Isso pode ser feito em apenas 1 hora de trabalho - a criação de um EA apto para o Campeonato, totalmente funcional, com limite móvel, gerenciamento de dinheiro e tudo que é necessário para a negociação competitiva. Devemos focar novamente no fato que o EA é gerado pelo Assistente. Dissemos que o EA está apto para o Campeonato e isso na verdade significa que o código gerado é livre de erros, de forma que os participantes não precisam corrigir coisa alguma ou temer falhas ou erros!

O EA simplesmente negociará e será perfeito para isso, pelo menos para aqueles que desejam participar mas não têm experiência em programação e não querem fazer um pedido de EA no serviço Empregos (uma boa alternativa para participar do Campeonato). Há muitos parâmetros de entrada que podem ser definidos para que o seu próprio robô de negociação se aproxime da estratégia que você tem em mente.

Mas, na realidade, você apenas pode usar o conjunto padrão de indicadores com o conjunto padrão de filtros/padrões oferecidos pelo MetaQuotes através do Assistente e da biblioteca padrão de classes de estratégia de negociação. Ele oferece um grande número de combinações e possibilidades de sucesso comercial, visto que os indicadores têm muitos parâmetros (período de tempo, símbolo) e todos os parâmetros dos próprios indicadores, tal como Período, Preço Aplicado, etc. Neste artigo, você aprenderá de forma rápida e fácil a personalizar os indicadores padrão do MetaTrader 5 e a adicionar padrões/filtros a eles.

Vamos continuar com o arquivo SignalCCIxx.mqh para personalizar e modificar o comportamento dele para criarmos nosso próprio modelo de negociação de sinal CCI (CCIxx). Primeiramente, vamos adicionar novas variáveis para o novo código na seção de entrada do arquivo MyExpert.mq5, como no exemplo a seguir (veja o código em destaque):

//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
//--- inputs for expert
input string             Expert_Title         ="MyExpert";  // Document name
ulong                    Expert_MagicNumber   =26287;       // 
bool                     Expert_EveryTick     =false;       // 
//--- inputs for main signal
input int                Signal_ThresholdOpen =40;          // Signal threshold value to open [0...100]
input int                Signal_ThresholdClose=60;          // Signal threshold value to close [0...100]
input double             Signal_PriceLevel    =0.0;         // Price level to execute a deal
input double             Signal_StopLevel     =50.0;        // Stop Loss level (in points)
input double             Signal_TakeLevel     =50.0;        // Take Profit level (in points)
input int                Signal_Expiration    =4;           // Expiration of pending orders (in bars)
input int                Signal_RSI_PeriodRSI =8;           // Relative Strength Index(8,...) Period of calculation
input ENUM_APPLIED_PRICE Signal_RSI_Applied   =PRICE_CLOSE; // Relative Strength Index(8,...) Prices series
input double             Signal_RSI_Weight    =0.7;         // Relative Strength Index(8,...) Weight [0...1.0]
input int                Signal_MA_PeriodMA   =90;          // Moving Average(12,0,...) Period of averaging
input int                Signal_MA_Shift      =0;           // Moving Average(12,0,...) Time shift
input ENUM_MA_METHOD     Signal_MA_Method     =MODE_SMA;    // Moving Average(12,0,...) Method of averaging
input ENUM_APPLIED_PRICE Signal_MA_Applied    =PRICE_CLOSE; // Moving Average(12,0,...) Prices series
input double             Signal_MA_Weight     =0.6;         // Moving Average(12,0,...) Weight [0...1.0]

input int                Signal_CCIxx_PeriodCCI =8;            // Commodity Channel Index(8,...) Period of calculation
input ENUM_APPLIED_PRICE Signal_CCIxx_Applied   =PRICE_CLOSE;  // Commodity Channel Index(8,...) Prices series
input double             Signal_CCIxx_Weight    =0.8;          // Commodity Channel Index(8,...) Weight [0...1.0]

Alteramos os valores das variáveis Signal_RSI_Weight e Signal_MA_Weight de 1,0 para 0,7 e 0,6, respectivamente, e adicionamos as linhas destacadas acima. Para trabalhar corretamente com os parâmetros de entrada para a versão CCIxx modificada do padrão pertencente ao indicador CCI nas classes de estratégia de negociação, na realidade, copiamos essas 3 linhas de código do arquivo SignalCCI.mqh e simplesmente adicionamos o sufixo "xx" após "CCI".

Há muitos elementos interessantes na seção "protegida" da declaração de classe:

class CSignalCCI : public CExpertSignal
  {
protected:
   CiCCI             m_cci;            // object-oscillator
   //--- adjusted parameters
   int               m_periodCCI;      // the "period of calculation" parameter of the oscillator
   ENUM_APPLIED_PRICE m_applied;       // the "prices series" parameter of the oscillator
   //--- "weights" of market models (0-100)
   int               m_pattern_0;      // model 0 "the oscillator has required direction"
   int               m_pattern_1;      // model 1 "reverse behind the level of overbuying/overselling"
   int               m_pattern_2;      // model 2 "divergence of the oscillator and price"
   int               m_pattern_3;      // model 3 "double divergence of the oscillator and price"
   //--- variables
   double            m_extr_osc[10];   // array of values of extremums of the oscillator
   double            m_extr_pr[10];    // array of values of the corresponding extremums of price
   int               m_extr_pos[10];   // array of shifts of extremums (in bars)
   uint              m_extr_map;       // resulting bit-map of ratio of extremums of the oscillator and the price

Observe os tipos int denominados m_pattern. Essas variáveis são progressivamente numeradas de 0 a 3. Cada uma delas é um "padrão" ou, em outras palavras, um modelo de condições de tomada de decisão de mercado que cria condições para para compra ou venda de um instrumento financeiro.

Adicionaremos 2 padrões personalizados: m_pattern_4 e m_pattern_5. Isso é feito simplesmente pela adição de duas linhas de código, duas variáveis do tipo inteiro.

//--- "weights" of market models (0-100)
   int               m_pattern_0;      // model 0 "the oscillator has required direction"
   int               m_pattern_1;      // model 1 "reverse behind the level of overbuying/overselling"
   int               m_pattern_2;      // model 2 "divergence of the oscillator and price"
   int               m_pattern_3;      // model 3 "double divergence of the oscillator and price"

   int               m_pattern_4;      // model 4 "our own first new pattern: values cross the zero"
   int               m_pattern_5;      // model 5 "our own second new pattern: values bounce around the zero"

Se você continuar observando o código, entenderá a lógica de compra e venda e todo o resto. Entretanto, apenas nos concentraremos nas seções de como adicionar os seus próprios padrões, visto que não explicaremos os arquivos inclusos linha a linha (para isso, o leitor poderá abrir os arquivos e estudá-los além de utilizar a Referência MQL5 para facilitar o entendimento).

Também faremos o seguinte: pressione CTRL + H no arquivo CSignalCCIxx.mqh, procure o termo "CCI" e o substitua por "CCIxx". Clique em "Substituir todos" - você deve encontrar e substituir 41 ocorrências. Vamos ao topo do arquivo:

//+------------------------------------------------------------------+
//| Class CSignalCCIxx.                                              |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Commodity Channel Index' oscillator.               |
//| Is derived from the CExpertSignal class.                         |
//+------------------------------------------------------------------+
class CSignalCCIxx : public CExpertSignal
  {
protected:
   CiCCIxx             m_CCIxx;            // object-oscillator

e mudaremos isto:

protected:
   CiCCIxx             m_CCIxx;            // object-oscillator

com esta parte igual ao SignalCCI.mqh original:

protected:
   CiCCI             m_CCIxx;            // object-oscillator

Fazemos isso porque o CiCCI é chamado a partir de outro arquivo incluso e, se alterarmos isso, haverá, obviamente, diversos erros. Agora podemos compilar o arquivo SignalCCIxx.mqh e deve haver 0 erros e 0 alertas. Se houver algum, você provavelmente cometeu algum erro e deve repetir o procedimento.

Agora vamos ao centro da adição de nossos próprios padrões. Apenas como exemplo, adicionamos 2 padrões de comportamento de mercado. No total, teremos 4 novos sinais (padrões), 2 iguais para compra e 2 iguais para venda. Este é o fragmento a ser alterado:

//+------------------------------------------------------------------+
//| Constructor CSignalCCIxx.                                        |
//| INPUT:  no.                                                      |
//| OUTPUT: no.                                                      |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
void CSignalCCIxx::CSignalCCIxx()
  {
//--- initialization of protected data
   m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
//--- setting default values for the oscillator parameters
   m_periodCCIxx  =14;
//--- setting default "weights" of the market models
   m_pattern_0  =90;         // model 0 "the oscillator has required direction"
   m_pattern_1  =60;         // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =100;        // model 2 "divergence of the oscillator and price"
   m_pattern_3  =50;         // model 3 "double divergence of the oscillator and price"
   m_pattern_4  =90;         // model 4 "our own first new pattern: "
   m_pattern_5  =90;         // model 5 "our own second new pattern: 
}

Designamos o valor 90 para m_pattern_4 e m_pattern_5, mas você deve (necessariamente) mudá-los para o seu próprio valor: esses são os pesos que você deseja definir para os seus novos modelos de mercado visto que eles influenciam todo o comportamento de negociação do Expert Advisor.

Ainda como exemplo, vamos adicionar dois novos modelos de mercado. Eles serão muito simples, pois são apenas para fins de educação e não foram testados. Por essa razão, não negocie com eles. O retículo nos ajudará a identificar valores do indicador CCI na figura abaixo para as barras correspondentes.


Primeiro padrão

Cruzando a linha zero de baixo para cima

Esse é o nosso primeiro padrão para: "votação para que o preço suba".

  • A Figura 5 mostra o valor CCI que corresponde à Barra 1 (uma barra anterior à barra atual). O valor é 45,16, ou seja, > 0.
  • A Figura 6 mostra o valor CCI que corresponde à Barra 2 (duas barras anteriores à barra atual). O valor é -53,92, ou seja, < 0.
  • A linha zero (valor 0,00) do indicador CCI foi cruzada de baixo para cima dentro de 2 barras.

Figura 5. Nosso primeiro padrão, aumento de preço - CCI na Barra 1 Figura 6. Nosso primeiro padrão, aumento de preço - CCI na Barra 2


Cruzando a linha zero de cima para baixo

Este é o nosso primeiro padrão para: "votação para que o preço caia".

  • A Figura 7 mostra o valor CCI que corresponde à Barra 1 (uma barra anterior à barra atual). O valor é -28,49, ou seja, < 0.
  • A Figura 8 mostra o valor CCI que corresponde à Barra 2 (duas barras anteriores à barra atual). O valor era 2,41, ou seja, > 0.
  • A linha zero (valor 0,00) do indicador CCI foi cruzada de cima para baixo dentro de 2 barras.

Figura 7. Nosso primeiro padrão, queda de preço - CCI na Barra 1 Figura 8. Nosso primeiro padrão, queda de preço - CCI na Barra 2


Segundo padrão

Cruzando a linha zero de cima para baixo e retornando novamente para cima

Este é o nosso segundo padrão para: "votação para que o preço suba".

  • A Figura 9 mostra o valor CCI que corresponde à Barra 1 (uma barra anterior à barra atual). O valor é 119,06, ou seja, > 0.
  • A Figura 10 mostra o valor CCI que corresponde à Barra 2 (duas barras anteriores à barra atual). O valor é -20,38, ou seja, < 0.
  • A Figura 11 mostra o valor CCI que corresponde à Barra 3 (três barras anteriores à barra atual). O valor era 116,85, ou seja, > 0 novamente.
  • A linha zero (valor 0,00) do indicador CCI foi cruzada de cima para baixo. Em seguida, a linha do indicador CCI retornou para cima, ressurgindo na linha zero dentro de 3 barras.

Figura 9. Nosso segundo padrão, aumento de preço - CCI na Barra 1 Figura 10. Nosso segundo padrão, aumento de preço - CCI na Barra 2 Figura 10. Nosso segundo padrão, aumento de preço - CCI na Barra 3


Cruzando a linha zero de baixo para cima e retornando novamente para baixo

Este é o nosso segundo padrão para: "votação para que o preço caia".

  • A Figura 12 mostra o valor CCI que corresponde à Barra 1 (uma barra anterior à barra atual). O valor é -58,72, ou seja, < 0.
  • A Figura 13 mostra o valor CCI que corresponde à Barra 2 (duas barras anteriores à barra atual). O valor era 57,65, ou seja, > 0.
  • A Figura 14 mostra o valor CCI que corresponde à Barra 3 (três barras anteriores à barra atual). O valor era -85,54, ou seja, < 0 novamente.
  • A linha zero (valor 0,00) do indicador CCI foi cruzada de baixo para cima. Em seguida, a linha do indicador CCI retornou para baixo, ressurgindo na linha zero dentro de 3 barras.

Figura 12. Nosso segundo padrão, queda de preço - CCI na Barra 1 Figura 13. Nosso segundo padrão, queda de preço - CCI na Barra 2 Figura 14. Nosso segundo padrão, queda de preço - CCI na Barra 3


Implementação de padrões

Para implementar essas 4 condições (2 por padrão), temos que modificar esta seção do código da seguinte forma. Na parte inferior, adicionamos as linhas de código destacadas para a condição "comprar" (veja acima nos comentários: "Votação" para que o preço suba).

//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//| INPUT:  no.                                                      |
//| OUTPUT: number of "votes" that price will grow.                  |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
int CSignalCCIxx::LongCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   if(Diff(idx)>0.0)
     {
      //--- the oscillator is directed upwards confirming the possibility of price growth
      if(IS_PATTERN_USAGE(0)) result=m_pattern_0;      // "confirming" signal number 0
      //--- if the model 1 is used, search for a reverse of the oscillator upwards behind the level of overselling
      if(IS_PATTERN_USAGE(1) && Diff(idx+1)<0.0 && CCIxx(idx+1)<-100.0)
         result=m_pattern_1;      // signal number 1
      //--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
      if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
        {
         ExtState(idx);
         //--- if the model 2 is used, search for the "divergence" signal
         if(IS_PATTERN_USAGE(2) && CompareMaps(1,1))      // 00000001b
            result=m_pattern_2;   // signal number 2
         //--- if the model 3 is used, search for the "double divergence" signal
         if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2))   // 00010001b
            return(m_pattern_3);  // signal number 3
        }
      // if the model 4 is used, look for crossing of the zero line
      if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0)
         result=m_pattern_4;      // signal number 4 
      // if the model 5 is used, look for the bouncing around the zero line
      if(IS_PATTERN_USAGE(5) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0 && CCIxx(idx+3)>0.0)
         result=m_pattern_5;      // signal number 5
     }
//--- return the result
   return(result);
  }

Vamos modificar a seção de código correspondente para a condição "vender". Na parte inferior, adicionamos as linhas de código destacadas para a condição "vender" (veja acima nos comentários: "votação" para que o preço caia).

//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//| INPUT:  no.                                                      |
//| OUTPUT: number of "votes" that price will fall.                  |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
int CSignalCCIxx::ShortCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   if(Diff(idx)<0.0)
     {
      //--- the oscillator is directed downwards confirming the possibility of falling of price
      if(IS_PATTERN_USAGE(0)) result=m_pattern_0;      // "confirming" signal number 0
      //--- if the model 1 is used, search for a reverse of the oscillator downwards behind the level of overbuying
      if(IS_PATTERN_USAGE(1) && Diff(idx+1)>0.0 && CCIxx(idx+1)>100.0)
         result=m_pattern_1;      // signal number 1
      //--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
      if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
        {
         ExtState(idx);
         //--- if the model 2 is used, search for the "divergence" signal
         if(IS_PATTERN_USAGE(2) && CompareMaps(1,1))      // 00000001b
            result=m_pattern_2;   // signal number 2
         //--- if the model 3 is used, search for the "double divergence" signal
         if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2))   // 00010001b
            return(m_pattern_3);  // signal number 3
        }
      if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)<0.0 && CCIxx(idx+2)>0.0)
         result=m_pattern_4;      // signal number 4 
      if(IS_PATTERN_USAGE(5) && CCIxx(idx+1)<0.0 && CCIxx(idx+2)>0.0 && CCIxx(idx+3)<0.0)
         result=m_pattern_5;      // signal number 5  
     }
//--- return the result
   return(result);
  }

O (idx+1) ou (idx+2) ... (idx+n) das últimas linhas adicionadas é muito simples, mas é também um ponto muito importante da questão: +1, +2, +3, etc. são apenas o número de barras que precede a barra atual (a atual é na realidade o "candle" absoluto, a barra 0).

Figura 15. Correspondência das Barras (candles) à variável (idx) no código.

Dessa forma, quanto maior o idx+N, maior o número de barras a serem retornadas. Cada barra (idx+n) corresponde ao valor do indicador na mesma posição "vertical" no mesmo período de tempo.

Figura 16. Cada barra (idx) corresponde ao valor CCI relativo

Nesta Figura 16, a barra zero (o primeiro candle mais à direita, correspondente a idx ou (idx+0) no código) tem o valor CCI correspondente inferior a 0,00. Além disso, a segunda (idx+1) e a terceira (idx+2) barras têm valores inferiores à linha 0,00. Não marcamos outras barras com uma seta vertical, mas se você mover o seu mouse sobre a 4ª barra anterior (idx+3), poderá ver que o seu valor CCI correspondente é superior a 0,00.

Para a maioria dos usuários, este é um fato óbvio, mas é melhor que os usuários iniciantes saibam como as barras (candles) gráficas do gráfico de preços, visualização gráfica do indicador CCI e respectivamente a variável (idx) e valor do indicador CCIxx correspondem um ao outro.

Isso é importante para ver os seus indicadores selecionados em um gráfico e tentar "visualizar" (ou descobrir) a correspondência entre barras/candles de preço e o comportamento do indicador selecionado, tentando fazer uma dedução para um estratégia, que você pode facilmente codificar utilizando o índice de barra (idx) e o valor da variável do indicador.

No arquivo SignalCCIxx.mqh, o seguinte código:

CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0

escrito em palavras, significa:

CCI Indicator value (one bar before, named idx+1) is above the zero line of CCI indicator
AND
CCI Indicator value (two bars before, named idx+2) is below the zero line of CCI indicator

Este é o melhor exemplo de como adicionar simplesmente dois padrões personalizados apenas com base no valor do indicador que escolhemos (neste caso - CCI).

A condição "preço subirá" ou "preço cairá" deve ser escrita e adicionada aos Padrões dessa forma e ninguém proibiu a criação de condições mais complexas. Antes do teste final, vamos observar os mecanismos de como as posições são abertas e fechadas.

O mecanismo e a lógica foram explicados muito bem no manual de Referência MQL5 na seção Classes de estratégia de negociação da biblioteca padrão.

Brevemente, temos 2 parâmetros de entrada (duas variáveis inteiras) no arquivo MyExpert.mq5:

//--- inputs for main signal
input int                Signal_ThresholdOpen =40;          // Signal threshold value to open [0...100]
input int                Signal_ThresholdClose=60;          // Signal threshold value to close [0...100]

Esses limites de abertura e fechamento são dois valores que são utilizados para cálculo, caso (de acordo com nossos modelos de negociação) uma negociação longa ou curta for aberta e então fechada. Os limites são um número do tipo inteiro de 0 a 100. O que significam esses parâmetros?

Signal_ThresholdOpen é o valor para abrir uma posição longa ou curta, Signal_ThresholdClose é o valor para fechar uma posição anteriormente aberta. Esses valores são calculados no contexto de um mecanismo simples, porém brilhante, que está integrado à lógica completa dos EAs gerados pelo Assistente.

Cada sinal dos arquivos Signal__.mqh (__ significa o nome do indicador usado, em nosso caso - MA, RSI e CCIxx) consiste em padrões, como vimos anteriormente em detalhes. Vamos observá-los novamente em nosso exemplo. No arquivo SignalMA.mqh temos 4 padrões com seus "pesos" relativos para cada padrão:

//--- setting default "weights" of the market models
   m_pattern_0 =80;          // model 0 "price is on the necessary side from the indicator"
   m_pattern_1 =10;          // model 1 "price crossed the indicator with opposite direction"
   m_pattern_2 =60;          // model 2 "price crossed the indicator with the same direction"
   m_pattern_3 =60;          // model 3 "piercing"

e para o RSI do arquivo SignalRSI.mqh, da mesma forma:

//--- setting default "weights" of the market models
   m_pattern_0  =70;         // model 0 "the oscillator has required direction"
   m_pattern_1  =100;        // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =90;         // model 2 "failed swing"
   m_pattern_3  =80;         // model 3 "divergence of the oscillator and price"
   m_pattern_4  =100;        // model 4 "double divergence of the oscillator and price"
   m_pattern_5  =20;         // model 5 "head/shoulders"

Em "nosso próprio" SignalCCIxx.mqh (que é quase uma cópia integral do SignalCCI.mqh), temos os seguintes valores:

//--- setting default "weights" of the market models
   m_pattern_0  =90;         // model 0 "the oscillator has required direction"
   m_pattern_1  =60;         // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =100;        // model 3 "divergence of the oscillator and price"
   m_pattern_3  =50;         // model 4 "double divergence of the oscillator and price"
   m_pattern_4  =80;         // model 4 "our own first new pattern: "
   m_pattern_5  =90;         // model 5 "our own second new pattern: "

Esses são os padrões 0, 1, 2 e 3 padrão, além de nossos próprios padrões 4 e 5 com os últimos dois valores 80 e 90. Quando anexamos o MyExpert.ex5 ao gráfico ou testamos ele no Strategy Tester, os padrões de todos os sinais que selecionamos (RSI, MA e CCIxx) são continuamente calculados.

Se uma ou mais condições do padrão forem exitosas, o sinal daquele padrão é ativado para o próximo cálculo. Por exemplo, se o pattern_4 do arquivo SignalCCIxx.mqh da condição está ocorrendo:

// if the model 4 is used, look for crossing of the zero line
       if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0)
          result=m_pattern_4;      // signal number 4 

Ele se torna um sinal de negociação potencial. Em outras palavras, se o valor do CCI na barra 1 é > 0,0 e ao mesmo tempo o valor do CCI na barra 2 era < 0,0, como nas Figuras 5 e 6, a condição está ocorrendo e o m_pattern_4 (sinal número 4) é ativado.

O valor do peso que estabelecemos para este sinal da nossa estratégia CCIxx é igual ao valor absoluto 80, mas assumirá o valor -80 em um caso de "votação para que o preço caia" e 80 no caso de "votação para que o preço suba". A "votação para que o preço caia" apenas coloca um sinal negativo no valor original do peso do padrão.

Considera-se que a condição do m_pattern_4 é exitosa, uma negociação é aberta somente se:

  • O sinal número 4 (m_pattern_4) é o único sinal cuja condição é verdadeira (sinal ativado) E ele atingiu o objetivo do Signal_ThresholdOpen (o seu valor multiplicado por um coeficiente atingiu e superou o valor do Signal_ThresholdOpen).

  • O sinal número 4 alcançou o limite do Signal_ThresholdOpen enquanto competia com outros sinais de seu próprio correspondente da estratégia CCIxx (os sinais/padrões "votação para que o preço caia" da estratégia CCIxx) e competia com todos os outros sinais da direção oposta (neste caso, a direção oposta é a direção curta, porque estamos analisando o m_pattern_4 sobre a "votação para que o preço suba") de outros sinais (sinais RSI e MA).

Dessa forma, podemos considerar cada padrão como um competidor em 2 facções: sinais bull (em alta) e sinais bear (em baixa). Quando esses padrões/sinais de mesma direção ("votação para que o preço suba") são exitosos (ativados), eles são somados uns aos outros e o total é comparado ao valor do Signal_ThresholdOpen. Se nenhuma posição foi aberta ou se o total é comparado ao valor Signal_ThresholdClose no caso de uma posição anteriormente oposta (neste exemplo, uma posição curta), o m_pattern_4 do SignalCCIxx.mqh tem o valor:

  • 80, em caso de condição de "crescimento de preço".
  • -80, em caso de condição de "queda de preço".

Vamos supor que TODOS os outros padrões de TODOS os outros sinais (SignalRSI.mqh, SignalMA.mqh e os padrões 0,1,2,3 e 5 do SignalCCIxx.mqh) têm o valor 0. Isso significa que os "competidores de sinal" estão fora do "jogo" e que os únicos competidores são os dois m_pattern_4 - um para comprar e outro para vender. Então temos apenas o m_pattern_4 em funcionamento, porque ele tem um valor diferente de 0, ou seja, 80.

//--- setting default "weights" of the market models
   m_pattern_0 =0;          // model 0 "price is on the necessary side from the indicator"
   m_pattern_1 =0;          // model 1 "price crossed the indicator with opposite direction"
   m_pattern_2 =0;          // model 2 "price crossed the indicator with the same direction"
   m_pattern_3 =0;          // model 3 "piercing"

E para o RSI do arquivo SignalRSI.mqh, da mesma forma:

//--- setting default "weights" of the market models
   m_pattern_0  =0;         // model 0 "the oscillator has required direction"
   m_pattern_1  =0;        // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =0;        // model 2 "failed swing"
   m_pattern_3  =0;        // model 3 "divergence of the oscillator and price"
   m_pattern_4  =0;        // model 4 "double divergence of the oscillator and price"
   m_pattern_5  =0;        // model 5 "head/shoulders"

Em "nosso próprio" SignalCCIxx.mqh (que é quase uma cópia integral do SignalCCI.mqh), temos os seguintes valores:

//--- setting default "weights" of the market models
   m_pattern_0  =0;        // model 0 "the oscillator has required direction"
   m_pattern_1  =0;        // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =0;        // model 3 "divergence of the oscillator and price"
   m_pattern_3  =0;        // model 4 "double divergence of the oscillator and price"
   m_pattern_4  =80;       // model 4 "our own first new pattern: "
   m_pattern_5  =0;        // model 5 "our own second new pattern: "

No início do artigo, adicionamos estas linhas:

input int                Signal_CCIxx_PeriodCCI =8;            // Commodity Channel Index(8,...) Period of calculation
input ENUM_APPLIED_PRICE Signal_CCIxx_Applied   =PRICE_CLOSE;  // Commodity Channel Index(8,...) Prices series
input double             Signal_CCIxx_Weight    =0.8;          // Commodity Channel Index(8,...) Weight [0...1.0]

Focamos na variável Signal_CCIxx_Weight que tem valor de 0,8. O Signal_ThresholdOpen é alcançado (disparado), quando o valor limite é atingido. O valor é calculado dessa forma:

0.8 (Signal_CCIxx_Weight input parameter)
*
80 (m_pattern_4's weight value)
= 64 is the signal strength for the "voting that price will grow"

Ele é "votação para que o preço suba" porque o algoritmo capturou um sinal "de crescimento de preço" (m_pattern_4 do SignalCCIxx) e o valor é 80.

Caso hipoteticamente ele capture "votação para que o preço caia" (m_pattern_4 do SignalCCIxx), o valor é -80. Para um algoritmo de "preço em queda", apenas coloque um sinal de menos no valor do padrão. Suponha que os cálculos do caso de "votação para que o preço caia" sejam como os seguintes:

0.8 (Signal_CCIxx_Weight input parameter)
*
-80 (m_pattern_4's weight value)
= -64 = the negative value is considered for short positions

-64 --> 64 (em valor absoluto) é a força do sinal para "votação para que o preço caia". A força do sinal é sempre expressa em valor absoluto, enquanto que os valores de posição curta são precedidos do sinal de menos, e os valores de posição longa, do sinal de mais.

Vamos voltar ao exemplo da posição longa acima com valor obtido 64 e sinal de força 64. Se não houver sinais (m_pattern_N do Signal__) opostos (com sinal negativo) em competição, o Signal_ThresholdOpen que tem valor 40 é atingido, porque a força do sinal longo é 64, e o nível 40 do Signal_ThresholdOpen é atingido e superado em 24 (40+24=64). Porque o Signal_ThresholdOpen foi atingido, uma posição longa é aberta.

Por exemplo, se configurarmos o valor 0,4 no Signal_CCIxx_Weight, nenhuma posição longa será aberta porque:

0.4 (the Signal_CCIxx_Weight)
*
80(m_pattern_4)
= 32 (strength of "long signal")

e o nível 40 (Signal_ThresholdOpen) não é atingido porque 32 < 40, então nenhuma posição longa é aberta.

O exemplo de valores acima (todos os valores 0, exceto 80 no m_pattern_4 do SignalCCIxx.mqh) é utilizado apenas de forma absurda para que possamos compreender a excelente lógica por trás do Assistente e do sistema de pesos e limites. Na programação normal, você definiria um peso de sua preferência para cada m_pattern_N de cada Signal__. Se você definir o valor 0 para um padrão, isso apenas significa que este padrão não será utilizado.

Se fôssemos mudar outro valor no exemplo acima (com todos os parâmetros definidos em 0, exceto o valor do m_pattern_4 of SignalCCIxx.mqh), vamos supor que o m_pattern_1 of SignalRSI.mqh seja 100, os cálculos mudam de forma que agora teremos 4 competidores:

  • m_pattern_4 (Bull) e m_pattern_4 (Bear) do arquivo SignalCCIxx.mqh, com valores 80 e -80, respectivamente.
  • m_pattern_1 (Bull) e m_pattern_1 (Bear) do arquivo SignalRSI.mqh, com valores 100 e -100, respectivamente.
m_pattern_4 Bullish --> 0.8 * 80 = 64
m_pattern_2 Bullish --> 0.7 * 100 = 70
m_pattern_4 Bearish --> 0.8 * (-80) = -64
m_pattern_2 Bearish --> 0.7 * (-100) = -70

Assim, teremos 4 combinações possíveis:

A) m_pattern_4 Bullish + m_pattern_2 Bullish = {[0.8 * (80)] + [0.7 * (100)]}/2 = [64 + (70)]/2 = 134/2 = 67
B) m_pattern_4 Bullish + m_pattern_2 Bearish = {[0.8 * (80)] + [0.7 * (-100)]}/2 = [64 + (-70)]/2 = -6/2 = -3
C) m_pattern_4 Bearish + m_pattern_2 Bullish = {[0.8 * (-80)] + [0.7 * (100)]}/2 = [(-64) + 70]/2 = 6/2 = 3
D) m_pattern_4 Bearish + m_pattern_2 Bearish = {[0.8 * (-80)] + [0.7 * (-100)]}/2 = [(-64) + (-70)]/2 = -134/2 = -67

Caso A
Valor positivo 67. A posição longa é aberta porque o Signal_ThresholdOpen com valor 40 é atingido e superado. A posição longa é posteriormente fechada quando o Signal_ThresholdClose com valor 60 é atingido e superado pelo valor absoluto do caso D = -67 = |67| (valor absoluto) porque a força do caso D em valor absoluto é 67 > 60 (que é o limite do Signal_ThresholdClose).

Caso B
Valor negativo -3. Nenhuma posição curta é aberta, porque o Signal_ThresholdOpen com valor 40 não é atingido e superado pelo valor absoluto do caso B: -3 tornou-se 3 quando consideramos o seu valor absoluto para calcular a "força do sinal", e 3 < 40 (valor para que um sinal abra uma posição). Não há posições curtas abertas e, obviamente, não há cálculos para o fechamento de posições curtas.

Caso C
Valor positivo 3. Nenhuma posição longa é aberta, porque o Signal_ThresholdOpen com valor 40 não é atingido ou superado pelo valor do caso C, porque 3 < 40 (valor para que um sinal abra uma posição). Não há posições longas abertas e, obviamente, não há cálculos para o fechamento de posições longas.

Caso D
Valor negativo -67. A posição curta é aberta porque o Signal_ThresholdOpen com valor 40 é atingido e superado pela força de sinal que é calculada simplesmente com o valor absoluto de -67, que é 67, e 67 > 40. A posição curta é posteriormente fechada quando o Signal_ThresholdClose com valor 60 é atingido e superado pelo valor do caso A = 67, porque 67 (a força do caso A) > 60 (que é o limite do Signal_ThresholdClose).

Em outras palavras, para abrir posições curtas, primeiramente devemos identificar a direção devido ao valor negativo dos sinais e, em seguida, o valor negativo é transformado no valor absoluto para o cálculo da força de sinal que será comparada ao valor do Signal_ThresholdOpen para ver se o primeiro é maior ou igual ao último.

O fechamento de posições longas é feito de maneira similar: primeiramente, consideramos o valor negativo que fecha uma posição longa (caso contrário, o valor para fechamento de posição curta é positivo) e, em seguida, esse valor é transformado no seu valor absoluto que será comparado ao Signal_ThresholdClose para verificar se o primeiro é maior ou igual ao último.

Para abrir posições longas e fechar posições curtas, os cálculos são realizados com números positivos (não há sinais com sinal negativo), de forma que não há necessidade de considerar os valores absolutos para cálculo. As posições longas abertas são disparadas por um valor positivo de força de sinal e o fechamento de posições curtas também é disparado por um valor positivo de força de sinal.

Primeiramente, considera-se o sinal de mais e o sinal de menos para abrir uma posição longa ou curta, e para fechar uma posição curta ou longa, respectivamente. Em seguida, calculamos os seus valores absolutos para comparação com os valores limite do Signal_ThresholdOpen e do Signal_ThresholdClose, que são sempre calculados com sinal positivo (nenhum sinal negativo para Signal_ThresholdOpen e Signal_ThresholdClose).


Detalhes de posição

Vamos continuar a nos aprofundar nos detalhes de posição:

  • Negociação normal. A posição é aberta e depois fechada. Após isso, a posição não é imediatamente reaberta.
  • Inversão de posição. A posição é aberta, fechada e, em seguida, aberta novamente na direção oposta.

A posição longa é aberta se:

Open_long >= Signal_ThresholdOpen
SE Signal_ThresholdClose <= Signal_ThresholdOpen
Recebemos um sinal para vender, de forma que posição longa será invertida se:
Open_short > Signal_ThresholdClose AND Open_short > Signal_ThresholdOpen
Recebemos um sinal para vender, de forma que posição longa será fechada se:
Open_short > Signal_ThresholdClose AND Open_short < Signal_ThresholdOpen

SE Signal_ThresholdClose >= Signal_ThresholdOpen
Recebemos um sinal para vender, de forma que posição longa será invertida se:
Open_short > Signal_ThresholdClose OR Open_short > Signal_ThresholdOpen
Recebemos um sinal para vender, de forma que posição longa será fechada se:
Open_short > Signal_ThresholdClose OR Open_short < Signal_ThresholdOpen

No caso de Signal_ThresholdClose >= Signal_ThresholdOpen é o operador boleano "OR" porque Signal_ThresholdClose >= Signal_ThresholdOpen, já incorporando o valor do Signal_ThresholdOpen. Assim, a posição será fechada e substituída pelo valor do Signal_ThresholdClose >= Signal_ThresholdOpen. Ela será curta-invertida, de qualquer maneira.


A posição curta é aberta se:

Open_short >= Signal_ThresholdOpen.
Signal_ThresholdClose <= Signal_ThresholdOpen
Recebemos um sinal para comprar, de forma que posição curta será invertida se:
Open_long > Signal_ThresholdClose AND Open_long > Signal_ThresholdOpen
Recebemos um sinal para comprar, de forma que posição curta será fechada se:
Open_long > Signal_ThresholdClose AND Open_long < Signal_ThresholdOpen

SE Signal_ThresholdClose >= Signal_ThresholdOpen
Recebemos um sinal para comprar, de forma que posição curta será invertida se:
Open_long > Signal_ThresholdClose OR Open_long > Signal_ThresholdOpen
Recebemos um sinal para comprar, de forma que posição curta será fechada se:
Open_long > Signal_ThresholdClose OR Open_long < Signal_ThresholdOpen

No caso de Signal_ThresholdClose >= Signal_ThresholdOpen é o operador boleano "OR" porque Signal_ThresholdClose >= Signal_ThresholdOpen, já incorporando o valor do Signal_ThresholdOpen. Assim, a posição será fechada e substituída pelo valor do Signal_ThresholdClose >= Signal_ThresholdOpen. Ela será longa-invertida, de qualquer maneira.

O mecanismo de abertura e fechamento de posições dos EAs gerados pelo Assistente é muito intuitivo e inteligente, visto que é baseado em um sistema de pesos, valores e limites. Com o uso desse mecanismo, as posições serão gerenciadas a partir de uma ótima "metodologia" e não haverá erros de lógica.


Nível de preço e vencimento de sinal

Há outra variável importante:

input double             Signal_PriceLevel    =0.0;         // Price level to execute a deal

Essa variável é muito importante para a compreensão básica do mecanismo dos EAs gerados pelo Assistente e pode ser simplificada da seguinte forma:

  • O Signal_PriceLevel determina se o sinal longo será processado como Buy-Stop (parada de compra) ou Buy-Limit (limite de compra), ou se o sinal curto será processado como Sell-Stop (parada de venda) ou Sell-Limit (limite de venda). Para detalhes sobre ordens de parada e limite, veja a seção de Ajuda do MetaTrader 5 correspondente.

  • Valores negativos definidos para a variável de entrada Signal_PriceLevel sempre significam ordens de parada (comprar ou vender).

  • Valores positivos definidos para a variável de entrada Signal_PriceLevel sempre significam ordens de limite (comprar ou vender).

Figura 17. Ordens de parada ou de limite, dependendo do Sinal_PriceLevel

Por exemplo:

EURUSD - posições longas

Signal_PriceLevel = -70 (menos 70)
de forma que quando o Signal Open for ativado (por exemplo, valor atual = 1.2500),
o EA dará uma ordem de parada de compra que consiste em 1.2500 + 70 = 1.2570
(pior que o preço atual, pelo ponto de vista otimista).


Signal_PriceLevel = 60 (mais 60)
de forma que quando o Signal Open for ativado (por exemplo, valor atual = 1.2500),
o EA dará uma ordem de limite de compra que consiste em 1.2500 - 60 = 1.2440
(melhor que o preço atual, pelo ponto de vista otimista).


EURUSD - posições curtas

Signal_PriceLevel = -70 (menos 70)
de forma que quando o Signal Open for ativado (por exemplo, valor atual = 1.2500),
o EA dará uma ordem de parada de venda que consiste em 1.2500 - 70 = 1.2430
(melhor que o preço atual, pelo ponto de vista pessimista).


Signal_PriceLevel = 60 (mais 60)
de forma que quando o Signal Open for ativado (por exemplo, valor atual = 1.2500),
o EA dará uma ordem de limite de venda que consiste em 1.2500 + 60 = 1.2560
(pior que o preço atual, pelo ponto de vista pessimista).


Finalmente, a variável de entrada

input int                Signal_Expiration    =4;           // Expiration of pending orders (in bars)

determina quantas vezes (expressas em barras) as ordens de parada/limite serão ativadas.


Fluxograma

Para melhor compreensão, você pode observar este fluxograma simplificado que apresenta o mecanismo da dinâmica de funcionamento dos EAs gerados pelo Assistente:

Figura 18. Fluxograma simplificado do funcionamento de ordens e posições


Strategy Tester

Agora vamos voltar ao contexto da nossa estratégia personalizada e compilar o arquivo SignalCCIxx.mqh. Se não houver erros, tudo deve funcionar corretamente. Na verdade, agora nós adicionamos 2 novos padrões de modelos de decisão de negociação de mercado. Cada padrão tem uma condição de compra e de venda, bem como condições de abertura e de fechamento.

Agora vamos compilar o arquivo MyExpert.mq5 e, se tudo estiver certo, haverá 0 erro(s) e 0 alerta(s). Vamos testá-lo no Strategy Tester. Utilizamos alguns parâmetros no Strategy Tester para o símbolo EUR/USD, para um período similar ao do Campeonato de negociação automatizada de 2011.

Figura 19. Alguns parâmetros simples para emular o Campeonato de 2011 com o MyExpert.mq5

Apesar de ele apresentar "bons" resultados e mais do que dobrar o depósito inicial em menos de 3 meses, com uma quantidade de lote fixa, não recomendamos a utilização deste EA para uma negociação real. Na realidade, encorajamos você a adicionar seus próprios padrões/modelos e testá-los, aprimorando eles até que você obtenha os resultados ótimos que deseja.

De qualquer forma, o nosso objetivo aqui é mostrar que a ideia de ampliação das classes de estratégia de negociação existentes funciona.

Figura 20. Resultados de um Campeonato de 2011 fictício com MyExpert.mq5

Você pode criar novos padrões/modelos e compartilhá-los no site MQL5.community. A utilização do Assistente MQL5 e do método simples discutido neste artigo fará com que seja fácil testá-los. Este artigo é apenas um exemplo de como explorar as classes de estratégia de negociação da biblioteca padrão e de como é simples modificar as bibliotecas para criar os seus próprios sistemas de negociação.


Conclusão

Nós adicionamos 2 novos filtros/padrões ao Sinal CCI facilmente. Você pode fazer o mesmo para todos os outros indicadores e construir os seus sinais personalizados. Se você fizer um trabalho bem pensado e bem estruturado, isso pode se tornar um instrumento de negociação muito poderoso.

Esta é uma forma poderosa e conveniente para adicionar suas próprias estratégias apenas focando no núcleo das estratégias e trabalhando com indicadores. Deixe que o Assistente MQL5 faça todo o resto do trabalho no que diz respeito às funções e operações de negociação do EA - isto economiza muito tempo e também assegura que o Expert Advisor não tenha erros.

Você pode escrever suas próprias estratégias facilmente utilizando os Indicadores padrão do MetaTrader 5 e agrupando eles no EA que está pronto para o ATC (Campeonato de Negociação Automatizada).

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

Arquivos anexados |
myexpert.mq5 (8.57 KB)
signalccixx.mqh (21.02 KB)
Estratégia de Carry Trade estatístico Estratégia de Carry Trade estatístico
Um algorítimo de proteção estatística de posições swap positivas abertas de movimentos de preço indesejados. Este artigo apresenta uma variante da estratégia de proteção Carry Trade, que permite que você compense potenciais riscos em relação ao movimento de preços na direção oposta à posição aberta.
Metaquotes ID no terminal móvel Metatrader Metaquotes ID no terminal móvel Metatrader
Aparelhos com Android e iOS oferecem muitos recursos que sequer conhecemos. Um desses recursos são as notificações do tipo push que permitem recebermos mensagens pessoais, independentemente do nosso número de telefone ou operadora de telefonia móvel. O terminal móvel MetaTrader já consegue receber essas mensagens diretamente do robô de negociação. Você apenas precisa saber o ID MetaQuotes do seu aparelho. Mais de 9.000.000 terminais móveis já receberam o ID.
Redes neurais: Da teoria à prática Redes neurais: Da teoria à prática
Atualmente, todo negociador já deve ter ouvido falar sobre redes neurais e sabe como é interessante utilizá-las. A maioria acredita que as pessoas que sabem lidar com redes neurais são algum tipo de super-humano. Neste artigo, tentaremos explicar a arquitetura da rede neural, descrever as suas aplicações e apresentar exemplos de uso prático.
Introdução ao Método de decomposição do modo empírico Introdução ao Método de decomposição do modo empírico
Este artigo serve como familiarização do leitor com o método de decomposição do modo epírico (EMD). é uma parte fundamental da transformação Hilbert-Huang e é destinada a análise de dados a partir de processos não lineares e não estacionários. Este artigo apresenta uma possível implementação do software deste método juntamente com uma breve consideração de suas peculiaridades e fornece simples exemplos de seu uso.