Explorar as classes de estratégia de negociação da biblioteca padrão - Personalização de estratégias
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).
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)".
Vamos chamar o nosso Expert Advisor gerado no Assistente MQL5 de "MyExpert".
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.
Podemos estabelecer alguns parâmetros, como quisermos, ou manter os parâmetros padrão para o nosso exemplo.
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.
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.
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.
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.
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).
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.
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 | ||
---|---|---|
|
SE Signal_ThresholdClose >= 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 | ||
---|---|---|
|
SE Signal_ThresholdClose >= 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).
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:
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.
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.
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
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso