English Русский 中文 Español Deutsch 日本語
Indicador Rope por Erik Naymanf

Indicador Rope por Erik Naymanf

MetaTrader 5Exemplos | 8 abril 2016, 17:05
2 721 0
Alexander Puzikov
Alexander Puzikov

Conteúdo


Introdução

Este artigo e o indicador foi inspirado no livro de Erik L. Nayman - The Small Encyclopedia of Trader (A Pequena Enciclopédia do Trader) — K . VIRA-R Alfa Capital, 1999. —236 p. Abrange os conceitos básicos da análise técnica e fundamental dos mercados financeiros, onde um método é escolhido, o indicador "Rope". Para descrevê-lo brevemente, observe que o indicador baseia-se na relação entre a mudança da velocidade de preço durante o período selecionado pela quantidade destas mudanças.

Em seu livro, o autor dá uma visão geral de análise, fornecendo tabelas e gráficos, usados para escrever este artigo. Ele executa a análise de mercado baseada na interação entre as tendências de alta e baixa, usando a velocidade de mudança do preço, número de transações e massa das mudanças como objetos de análise. A velocidade é medida por uma série de operações e a massa é calculada como a diferença entre duas cotações adjacentes (corrente e anterior). O último preço conhecido é considerado no livro como uma cotação (maiores informações são fornecidas no primeiro capítulo, usando o exemplo de cálculo).

O objetivo da análise do mercado é calcular a força e a determinação da direção da tendência, onde as tendências de alta e de baixa afetam simultaneamente o mercado. Encontrando o valor desta força, pode ser usado para avaliar a posição mais forte em andamento. O autor identifica esta ação como um cabo-de-guerra entre duas forças opostas, como mostrado no livro através do valor "rope", calculado usando uma força total das tendências de alta e de baixa:


Ele também descreve duas abordagens para análise do mercado e cálculos com base em métodos estáticos e dinâmicos. O cálculo do valor "rope" no livro envolve os seguintes passos:

1. Avaliação e cálculo de forças de alta e baixa, encontrando a direção.

Fórmulas para força de alta (como no livro):

BuF = SPCi, onde:

  • BuF — força de alta;
  • SPCi — soma das variações positivas ao longo do período de tempo analisado.

Fórmulas para força de baixa (como no livro):

BeF = SNCi, onde:

  • BeF — força de baixa;
  • SNCi — soma das variações negativas ao longo do período de tempo analisado.

Os valores BuF e BeF são comparados uns aos outros, onde o maior valor indica que tem uma posição dominante no mercado.

Ao comparar os valores de força sobre duas barras adjacentes do período gráfico analisado, obtemos a avaliação dinâmica. Veja abaixo a análise na fonte:

BuF > BeF and (BuF1 - BuFО) > (BeF1 - BeFО) = crescimento global da força de alta (valor da força corrente está marcada com índice 1, valor anterior - com o índice 0).

BuF > BeF and (BuF1 - BuFО) < (BeF1 - BeFО) = declínio global da força de alta.

BuF < BeF and (BuF1 - BuFО) > (BeF1 - BeFО) = crescimento global da força de baixa.

BuF < BeF and (BuF1 - BuFО) < (BeF1 - BeFО) = declínio global da força de baixa.

Em adição ao valor da força estática, as mudanças da dinâmica desse valor sobre os pontos calculados adjacentes são vistos separadamente.

2. Avaliar, calcular e comparar o "vigor" (número de mudanças) para as tendências de alta e baixa. Cálculo do vigor para as tendências de alta e baixa na fonte:

BuV = NPCi, onde:

  • BuV — vigor de alta;
  • NPCi — número das variações positivas ao longo do período de tempo analisado.

BeV = NNCi, onde:

  • BeV — vigor de baixa;
  • NNCi — número dase variações negativas ao longo do período de tempo analisado.

Ao comparar o valor calculado do vigor com um valor adjacente anterior, temos a avaliação dinâmica. As dinâmicas são avaliadas através da comparação de um valor estático com um valor dinâmico, igualmente no exemplo de comparação da análise anterior.

3. Avaliar, calcular e comparar a avaliação das "habilidades" (skills) para as tendências de alta e baixa. Mostrada na fonte como:

Habilidades de tendências de alta e baixa quanto a suas políticas de mercado são reveladas nas seguintes fórmulas:

BuS = SPC1/NPC1;

BeS = SNC1 / NNC1.

Isto mostra como o valor estático é calculado, o cálculo dinâmico baseia-se no exemplo da primeira etapa.

4. Avaliação final das tendências de alta e baixa. Depois de calcular todos os valores das três etapas anteriores e comparando seus dados, podemos fazer uma conclusão sobre a direção e caráter da tendência. A avaliação final foi feita com base na comparação de todos os três parâmetros e está sendo apresentada de acordo com o livro:

Se BuF > BeF, BuV > BeV e BuS > BeS (sujeitos as relações dinâmicas mencionadas acima), então as tendências de alta estão muito mais vigorosas do que as tendências de baixa, logo consideramos apenas as ordens de compra.

 Um valor dinâmico de "dois pontos adjacentes calculados na linha rope" deve ser adicionado aos dados estáticos para uma avaliação dinâmica do mercado.

Em termos de etapas de análise, os três principais valores calculados para criar um indicador podem ser distinguidos como:

  • força — soma das variações durante o período de tempo analisado;
  • vigor - quantidade das variações ao longo do período de tempo analisado;
  • habilidade (skill) = força / vigor.

O autor marcou a parte dinâmica como a mais sensível e vigorosa de todas. Apenas um método estático de cálculos foi escolhido para este artigo. Assim, comparando as três partes calculadas: "força", "vigor" e "habilidade" (skill), o autor faz uma conclusão sobre a força e a direção da tendência, calcula os dados estáticos, dinâmicos e introduz vários métodos para a sua utilização. Agora vamos dar uma olhada mais detalhada sobre o desenvolvimento do indicador "Rope", usando o método de Erik L. Nayman.


Capítulo 1. Princípios do desenvolvimento e cálculos do indicador "Rope", com exemplos do código

Um método tipo linear e histograma foi escolhido para escrever o indicador. O método tipo linear soma os valores calculados das tendências de alta e baixa. O método tipo histograma apresenta cálculos para as tendências de alta e baixa separadamente.

Veremos o código do indicador com comentários inseridos em cada etapa. Começaremos com uma declaração das variáveis e características para exibir o indicador usando as atribuições #property. A descrição das características da cor do indicador é colocada convenientemente para análise dos dados no código abaixo.

//+------------------------------------------------------------------+
//|                                             RopebyEricNaiman.mq5 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property description "RopebyEricNaiman by Im_hungry (https://login.mql5.com/en/users/Im_hungry)"
#property description "RopebyEricNaiman - mostra a direção da vontade da ação do mercado e do poder dessa vontade."
#property version   "1.00"
#property strict
//--- incluindo a função de cálculo МА do arquivo MovingAverages.mqh.
#include <MovingAverages.mqh>
//---
#property indicator_separate_window // configura o desenho numa janela separada
#property indicator_buffers 12 // configura 12 buffers do indicador
#property indicator_plots   5 // configura 5 buffers do indicador para ser desenhado pelo próprio indicador
//--- histograma de alta
#property indicator_label1  "BULL"
#property indicator_type1   DRAW_COLOR_HISTOGRAM
// 0 - clrDarkGreen - o índice de cor "apenas comprar"(only buy), ordem de compra com categoria alta de confirmação
// 1 - clrMediumSeaGreen - o índice de cor "ordem de compra permitida" (buy order allowed), ordem de compra com categoria média de confirmação
// 2 - clrLightGreen - o índice de cor "ordem de compra permitida" (buy order allowed), ordem de compra com categoria baixa de confirmação
// 3 - clrGray - índice de cor "ordem de compra proibida" (buy order prohibited)
#property indicator_color1  clrDarkGreen,clrMediumSeaGreen,clrLightGreen,clrGray
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- histograma de baixa
#property indicator_label2  "BEAR"
#property indicator_type2   DRAW_COLOR_HISTOGRAM
// 0 - clrDarkRed - o índice de cor "apenas vender"(only vender), ordem de venda com categoria alta de confirmação
// 1 - clrIndianRed - o índice de cor "ordem de compra permitida" (sell order allowed), ordem de venda com a categoria média de confirmação
// 2 - clrLightPink  - o índice de cor "ordem de compra permitida" (sell order allowed), ordem de venda com a categoria baixa de confirmação
// 3 - clrGray - índice de cor "ordem de venda proibida" (sell order prohibited)
#property indicator_color2  clrDarkRed,clrIndianRed,clrLightPink,clrGray
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
//--- linha PRINCIPAL do indicador
#property indicator_label3  "main line"
#property indicator_type3   DRAW_COLOR_LINE
// 0 - clrDarkGreen - o índice de cor "apenas comprar"(only buy), ordem de compra com categoria alta de confirmação
// 1 - clrDarkRed - o índice de cor "ordem de compra permitida" (sell order allowed), ordem de venda com a categoria média de confirmação
// 2 - clrGray - índice de cor "nenhuma confirmação restrita" (no strict confirmation)
#property indicator_color3  clrDarkGreen,clrDarkRed,clrGray
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2
//--- desenho do indicador МА rápida nos dados da linha principal do indicador
#property indicator_label4  "ma fast"
#property indicator_type4   DRAW_LINE
#property indicator_color4  clrAqua
#property indicator_style4  STYLE_SOLID
#property indicator_width4  1
//--- desenho do indicador МА lenta nos dados da linha principal do indicador
#property indicator_label5  "ma slow"
#property indicator_type5   DRAW_LINE
#property indicator_color5  clrYellow
#property indicator_style5  STYLE_SOLID
#property indicator_width5  1

O autor não fornece nenhuma descrição das características das cores nelas mesmas, mas analisa a tendência, quando os três indicadores correspondem totalmente/parcialmente:

  • bull force > bear force — tendência de alta, o sinal inverso indica o predomínio dos ursos.
  • bull vigor > bear vigor — tendência de alta.
  • bull skill > bear skill — tendência de alta.

Ao comparar esses indicadores, podemos avaliar a força da tendência. Quanto mais indicadores estiverem confirmando a tendência, mais forte ela se torna. Uma descrição das cores exibidas no histograma, com base em três valores calculados durante a inicialização das variáveis, foi mostrado acima. Estes valores calculados podem ser comparados em qualquer combinação.

0 — clrDarkGreen, o índice de cor "apenas comprar"(only buy), ordem de compra com categoria alta de confirmação.

1 — clrMediumSeaGreen - o índice de cor "ordem de compra permitida" (buy order allowed), ordem de compra com categoria média de confirmação

2 — clrLightGreen - o índice de cor "ordem de compra permitida" (buy order allowed), ordem de compra com categoria baixa de confirmação

3 — clrGray - índice de cor "ordem de compra proibida" (buy order prohibited)

Uma cor é exibida na linha principal do indicador somente quando correspondem todos os três valores calculados, de acordo com a descrição original do livro:

"Se BuF > BeF, BuV > BeV e BuS > BeS (sujeitos as relações dinâmicas mencionadas acima), então as tendências de alta estão muito mais vigorosas do que as tendências de baixa, logo consideramos apenas as ordens de compra.

Se BuF < BeF, BuV < BeV e BuS < BeS (sujeitos a relações dinâmicas), as tendências de baixa são muito mais vigorosas do que as de alta. Somente as ordens de venda são as preferidas."

Nós vamos declarar as variáveis externas do indicador. Observe que é uma opção exibir uma linha e/ou um histograma com as variáveis de entrada draw_line e draw_histogram para tornar a operação com o indicador mais fácil. Para alcançar cálculos universais, agora você pode selecionar preços para cálculo do indicador usando o parâmetro _price. Configurações do indicador МА também são executadas com uma opção que pode ser desativada.

//--- parâmetros de entrada
input string section_1="___ main settings";
//--- permitem desenhar um histograma das tendências de alta e de baixa
input bool draw_histogram=true;
//--- habilita o desenho de uma linha principal do indicador
input bool draw_line=true;
//--- período do indicador
input int _period=76;
//--- preço utilizado para cálculos
input ENUM_APPLIED_PRICE _price=PRICE_CLOSE;
//--- restrições mais profundas nos cálculos das barras no histórico da barra atual
input int max_bars=0;
//--- breve deslocamento da linha e da МА a partir do histograma para melhor clareza do indicador. Todos os valores da linha principal e da MA são multiplicados pelo line_deviation
input double line_deviation=3.0;
//---
input string section_2="___ MA fast";
//--- permite desenhar a МА rápida
input bool draw_MA_fast=false;
//--- período de cálculo da МА rápida com base no indicador
input int period_MA_fast=25;
//--- método de cálculo da média móvel rápida
input ENUM_MA_METHOD method_MA_fast=MODE_SMA;
//---
input string section_3="___ MA slow";
//--- permite desenhar a МА rápida
input bool draw_MA_slow=false;
//--- período de cálculo da МА lenta com base no indicador
input int period_MA_slow=143;
//--- método de cálculo da média móvel lenta
input ENUM_MA_METHOD method_MA_slow=MODE_SMA;
//---- buffers
...

O livro contém uma série de opções para trabalhar com o valor "rope". A seguir foram selecionadas a partir da variedade:

  • Interseção do indicador com uma linha zero.
  • Negociação somente quando todos os três valores calculados, como força, vigor e habilidade (skill) combinam. Implementado como cores da linha principal.
  • Intersecção do indicador com a МА.
  • Intersecção de duas МАs.

O indicador МА (carregado a partir da biblioteca MovingAverages.mqh) é criado com base nos valores presentes da linha principal do indicador no array de buffer Buffer_calcLINE. Ele foi adicionado para alcançar facilmente o acesso de dados antes de transferi-lo a biblioteca de funções para o cálculo da МА.

Os principais dados para o cálculo e a criação do indicador são inicializados na função OnInit. Anular as variáveis prev_rates_total e _tm_prev é um aspecto importante para fazer cálculos quando ocorrem mudanças no período do gráfico e outras razões para redefinir o indicador. O valor _tm_prev é responsável pelo tempo da última barra calculada, a partir do qual o cálculo começa quando a próxima barra aparece. O parâmetro prev_rates_total mantém o valor anterior - rates_total (pelo tick anterior). Comparando-o com o rates_total corrente (número de barras ou o tamanho do array price[]), podemos ver se os dados foram recalculados, pois nem sempre todas as barras são carregadas, um novo cálculo é feito para evitar casos de falhas de carregamento do histórico, e como resultado, os dados não seriam exibidos corretamente no gráfico.

//+------------------------------------------------------------------+
//| Função de inicialização do indicador personalizado               |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- mensagem log para executar o indicador pela primeira vez
   Print(__FUNCTION__+"\\ Initialization | _period: ",_period);
//--- número de dígitos depois do ponto decimal para o símbolo atual
   _digits=(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS);
//---exibição precisa dos valores do indicador
   IndicatorSetInteger(INDICATOR_DIGITS,_digits);
//--- Definindo o nome do indicador, exibido na janela do indicador
   IndicatorSetString(INDICATOR_SHORTNAME,"RopebyEricNaiman");
//--- INDICATOR_DATA - armazena dados para o desenho
//--- INDICATOR_COLOR_INDEX - índices de cores armazenadas
//--- INDICATOR_CALCULATIONS - armazena dados para cálculos intermediários não destinados ao desenho
   SetIndexBuffer(0,Buffer_main_bull,INDICATOR_DATA); // buffer de dados de histograma de alta
   SetIndexBuffer(1,Buffer_color_bull,INDICATOR_COLOR_INDEX);  // buffer de dados de cores de alta
   SetIndexBuffer(2,Buffer_main_bear,INDICATOR_DATA); // buffer de dados de histograma de baixa
   SetIndexBuffer(3,Buffer_color_bear,INDICATOR_COLOR_INDEX);  // buffer de dados da cor de baixa
   SetIndexBuffer(4,Buffer_mainline,INDICATOR_DATA); // buffer de dados da linha principal do indicador
   SetIndexBuffer(5,Buffer_mainline_color,INDICATOR_COLOR_INDEX); // buffer de dados de cores da linha principal do indicador
   SetIndexBuffer(6,Buffer_MAfast,INDICATOR_DATA); // buffer de dados da МА rápida
   SetIndexBuffer(7,Buffer_MAslow,INDICATOR_DATA); // buffer de dados da МА lenta
   SetIndexBuffer(8,Buffer_calc,INDICATOR_CALCULATIONS); // buffer de dados dos cálculos do preços
   SetIndexBuffer(9,Buffer_calc_bull,INDICATOR_CALCULATIONS); // alta calculada do buffer de dados
   SetIndexBuffer(10,Buffer_calc_bear,INDICATOR_CALCULATIONS); // baixa calculada do buffer de dados
   SetIndexBuffer(11,Buffer_calcLINE,INDICATOR_CALCULATIONS); // cálculo do buffer de dados para МА
//--- tempo nulo da última barra calculada e prev_rates_total (rates_total na chamada anterior // rates_total = tamanho do array price[])
   _tm_prev=0;
   prev_rates_total=0;
//---
   return(INIT_SUCCEEDED);
  }

Outros cálculos na função OnCalculate são feitos para exibir dados no gráfico. Levando-se em conta a parte calculada da tabela do livro na página 147, uma mudança positiva é um resultado positivo da diferença entre dois preços, onde esta mudança é um preço de fechamento da barra (quando se utiliza price=PRICE_CLOSE). Essa diferença pode indicar uma tendência tanto altista (variação positiva) como baixista (variação negativa) no mercado. Será ainda considerada como uma "barra" o preço que consiste da abertura da barra igual ao fechamento de preço da barra anterior e a barra (i) é calculada no fechamento do preço definido pela função:

for(int i=1; i<bars_calc && !IsStopped(); i++)
        {
         ...

Para calcular os três principais indicadores, devemos conduzir o array de preço de acordo com as configurações _price e calcular o valor da variável _period, utilizando o operador for. Ele é necessário para calcular variações de preços positivas nas tendências de alta e variações de preços negativas nas tendências de baixa, e ainda, a quantidade de mudanças ao longo desse período, além de encontrar sua proporção no curso da divisão da soma pela quantidade:

  • if(total_bull>0) Buffer_calc_bull[i]=sum_bull/total_bull; — para touros.
  • if(total_bear>0) Buffer_calc_bear[i]=sum_bear/total_bear; — para ursos.

Veja abaixo um cálculo (ao vivo no gráfico) dos touros, ursos e a linha principal do histograma com _period=5:


Assim, um resultado da soma dos valores de altas e baixas aparece em cada barra, sendo estes valores usados nos cálculos. Isto é implementado e apresenta-se no indicador como uma linha com três cores, exibidas através do buffer de cor do indicador - Buffer_mainline_color[]. Veja abaixo os cálculos na função OnCalculate().

//+------------------------------------------------------------------+
//| Função de iteração do Indicador personalizado                    |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,    // tamanho do array price[]
                const int prev_calculated,// barras processadas na chamada anterior
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   ArraySetAsSeries(time,true);
//--- definindo a indexação do array como nas séries temporais, o menor índice 0 tem o último valor calculado conhecido no histórico
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
   ArraySetAsSeries(Buffer_main_bull,true);
   ArraySetAsSeries(Buffer_color_bull,true);
   ArraySetAsSeries(Buffer_main_bear,true);
   ArraySetAsSeries(Buffer_color_bear,true);
   ArraySetAsSeries(Buffer_mainline,true);
   ArraySetAsSeries(Buffer_mainline_color,true);
   ArraySetAsSeries(Buffer_MAfast,true);
   ArraySetAsSeries(Buffer_MAslow,true);
   ArraySetAsSeries(Buffer_calc,true);
   ArraySetAsSeries(Buffer_calc_bull,true);
   ArraySetAsSeries(Buffer_calc_bear,true);
   ArraySetAsSeries(Buffer_calcLINE,true);
//--- 
   int copy=0;
   bars_calc=0;
//--- cálculo dos dados do indicador
//--- quando prev_calculated = 0, todos os dados são calculados em todos as barras mais uma vez; _tm_prev=0 pode ser igual a zero após uma falha no histórico, por exemplo, quando se desconectar da Internet por um longo período de tempo
   if(prev_calculated==0) _tm_prev=0;
//---Se o tamanho anterior é maior do que o tamanho atual, indica falha e todos os dados devem ser recalculados
   if(prev_rates_total>rates_total) _tm_prev=0;
   if(_tm_prev<time[0]) // cálculo quando uma nova barra aparece
     {
      if(_tm_prev>0) // Se o indicador já foi previamente calculado
        {
         copy=TakeShift_byTime(Symbol(),PERIOD_CURRENT,_tm_prev); // a barra dos símbolos corrente mudando ao longo da última barra calculada
         if(copy<=0) // Se o deslocamento não for encontrado, então os cálculos são desviados e repetidos no próximo tick
           {
            return 0;
           }
         bars_calc=copy+1; // definindo o deslocamento da barra para começar os cálculos da atual barra não fechada do indicador 
         //--- anulando a primeira barra em andamento não fechada, ou seja, seus dados não são calculados
         Buffer_main_bull[0]=0.0;
         Buffer_color_bull[0]=5; // definição de índice de cor no número 5 corresponde a uma cor vazia, portanto a cor não é desenhada
         Buffer_main_bear[0]=0.0;
         Buffer_color_bear[0]=5; // definição de índice de cor no número 5 corresponde a uma cor vazia, portanto a cor não é desenhada
         Buffer_mainline[0]=0.0;
         Buffer_mainline_color[0]=5; // definição de índice de cor no número 5 corresponde a uma cor vazia, portanto a cor não é desenhada
         Buffer_MAfast[0]=0.0;
         Buffer_MAslow[0]=0.0;
         Buffer_calc[0]=0.0;
         Buffer_calc_bull[0]=0.0;
         Buffer_calc_bear[0]=0.0;
         Buffer_calcLINE[0]=0.0;
        }
      else // se o indicador foi configurado pela primeira vez e os valores não são calculados
        {
         bars_calc=Bars(Symbol(),PERIOD_CURRENT)-1; //delocamento das barras para começar os cálculos é definido com a quantidade total de barras -1
         //--- anular todos os dados em todos as barras, para evitar erros de desenho 
         for(int i=0; i<Bars(Symbol(),PERIOD_CURRENT) && !IsStopped(); i++)
           {
            Buffer_main_bull[i]=0.0;
            Buffer_main_bear[i]=0.0;
            Buffer_mainline[i]=0.0;
            Buffer_MAfast[i]=0.0;
            Buffer_MAslow[i]=0.0;
            Buffer_calc[i]=0.0;
            Buffer_calc_bull[i]=0.0;
            Buffer_calc_bear[i]=0.0;
            Buffer_calcLINE[i]=0.0;
           }
        }
      //--- se a quantidade de barras para cálculos do indicador diminui abaixo de zero, então o cálculo deve ser abortado
      if(bars_calc<0) return 0;
      //--- restrição da quantidade de barras para calcular o valor max_bars
      if(bars_calc>max_bars && max_bars!=0) bars_calc=max_bars;
      for(int i=1; i<bars_calc && !IsStopped(); i++)
        {
         //--- cálculo da diferença entre duas barras de acordo com a configuração do _price
         switch(_price)
           {
            case PRICE_CLOSE:
               Buffer_calc[i]=close[i]-close[i+1];
               break;
            case PRICE_OPEN:
               Buffer_calc[i]=open[i]-open[i+1];
               break;
            case PRICE_HIGH:
               Buffer_calc[i]=high[i]-high[i+1];
               break;
            case PRICE_LOW:
               Buffer_calc[i]=low[i]-low[i+1];
               break;
            case PRICE_MEDIAN:
               Buffer_calc[i]=((high[i]+low[i])/2)-((high[i+1]+low[i+1])/2);
               break;
            case PRICE_TYPICAL:
               Buffer_calc[i]=((high[i]+low[i]+close[i])/3)-((high[i+1]+low[i+1]+close[i+1])/3);
               break;
            case PRICE_WEIGHTED:
               Buffer_calc[i]=((high[i]+low[i]+close[i]+close[i])/4)-((high[i+1]+low[i+1]+close[i+1]+close[i+1])/4);
               break;
            default: return 0;
           }
        }
      //--- o funcionamento da iteração das barras sem cálculos até as extremidades finaliza o loop, o comando IsStopped=true para finalizar o programa não aparece (quando se apaga o indicador no gráfico)
      for(int i=1; i<=bars_calc && !IsStopped(); i++)
        {
         //--- dados nulos 
         sum_bull=0.0; // soma da variável de mudanças positivas (para tendências de alta) durante o período de tempo analisado
         total_bull=0; // soma da variável da quantidade de mudanças positivas ao longo do período de tempo analisado
         sum_bear=0.0; // soma da variável de variações negativas (para tendências de baixa) durante o período de tempo analisado
         total_bear=0; // soma da variável das variações negativas ao longo do período de tempo analisado

         Buffer_main_bull[i]=0.0;
         Buffer_color_bull[i]=5;
         Buffer_main_bear[i]=0.0;
         Buffer_color_bear[i]=5;
         Buffer_mainline[i]=0.0;
         Buffer_mainline_color[0]=5;

         Buffer_calc_bull[i]=0.0;
         Buffer_calc_bear[i]=0.0;
         Buffer_calcLINE[i]=0.0;
         //--- parar o cálculo da barra, se ele diminui além dos dados disponíveis de acordo com o período analisado 
         if(i>=(rates_total-_period)) continue;
         //--- dados de iteração ao longo do período analisado (_period) da barra corrente mais profunda no histórico
         for(int i2=i; i2<i+_period; i2++)
           {
            //--- cálculo para tendência de alta
            if(Buffer_calc[i2]>0)
              {
               sum_bull+=Buffer_calc[i2]; // resumindo os preços das barras positivas ("soma de mudanças positivas ao longo do período de tempo analisado")
               total_bull++; // cálculo da quantidade de barras positivas ("quantidade de mudanças positivas ao longo do período de tempo analisado")
              }
            //--- cálculo para tendências de baixa
            if(Buffer_calc[i2]<0)
              {
               sum_bear+=Buffer_calc[i2]; // resumindo os preços das barras negativas ("soma de variações negativas ao longo do período de tempo analisado")
               total_bear++; // cálculo da quantidade de barras negativas ("quantidade de variações negativas ao longo do período de tempo analisado")
              }
           }
         //--- cálculo da "habilidade dos touros" (bulls skill), dividindo o valor da barra em pontos pela quantidade de tais barras
         if(total_bull>0) Buffer_calc_bull[i]=sum_bull/total_bull;
         //--- calculo do "habilidade dos ursos" (bears' skills)
         if(total_bear>0) Buffer_calc_bear[i]=sum_bear/total_bear;
         //--- desenho do histograma com preenchimento das cores por categorias de confirmação do sinal
         if(draw_histogram)
           {
            //--- desenho do histograma de alta, dividindo o valor da barra em pontos pela quantidade de tais barras
            if(total_bull>0) Buffer_main_bull[i]=sum_bull/total_bull;
            //--- desenho do histograma de baixa, dividindo o tamanho da barra em pontos pela quantidade de tais barras
            if(total_bear>0) Buffer_main_bear[i]=sum_bear/total_bear;
            //--- 0 - cor do histograma clrDarkGreen- o índice de cor "apenas comprar", ordem de compra com categoria alta de confirmação
            //--- categoria de confirmação - todos os três indicadores revelam tendência de alta
            //--- vigor de alta > vigor de baixa e força de alta > força de baixa e habilidade de alta > habilidade de baixa
            //--- vigor - quantidade de barras
            //--- força - resumindo o tamanho da barra em pontos
            //--- habilidade (skill) - valor médio calculado de todas as barras somadas ao período indicado de vigor/força 
            if(total_bull>total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) Buffer_color_bull[i]=0;
            else
              {
               //--- 1 - cor do histograma clrMediumSeaGreen - o índice de cor "ordem de compra permitida", ordem de compra com categoria média de confirmação
               //--- categoria de confirmação - com dois indicadores de alta e um indicador de baixa, em qualquer combinação
               if((total_bull>total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) || 
                  (total_bull>total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) || 
                  (total_bull<total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i]))) Buffer_color_bull[i]=1;
               else
                 {
                  //--- 2 - cor do histograma clrLightGreen - o índice de cor "ordem de compra permitida", ordem de compra com categoria baixa de confirmação
                  //--- categoria de confirmação - com um indicador de alta e dois indicadores de baixa, em qualquer combinação 
                  if((total_bull>total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) || 
                     (total_bull<total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) || 
                     (total_bull<total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i]))) Buffer_color_bull[i]=2;
                  else
                    {
                     //--- 3 - cor do histograma clrGray - índice de cor "ordem de compra proibida"
                     //--- categoria de confirmação - quando o indicador de alta está ausente
                     Buffer_color_bull[i]=3;
                    }
                 }
              }
            //--- 0 - cor do histograma clrDarkRed - o índice de cor "apenas vender", ordem de venda com a categoria alta de confirmação
            //--- categoria de confirmação - todos os três indicadores revelam tendência de baixa
            if(total_bull<total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) Buffer_color_bear[i]=0;
            else
              {
               //--- 1 - cor do histograma clrIndianRed - o índice de cor "ordem de venda permitida", ordem de venda com a categoria média de confirmação
               //--- categoria de confirmação - com dois indicadores de alta e um indicador de baixa, em qualquer combinação
               if((total_bull<total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) || 
                  (total_bull<total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i])) || 
                  (total_bull>total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i]))) Buffer_color_bear[i]=1;
               else
                 {
                  //--- 2 - cor do histograma clrLightPink - o índice de cor "ordem de venda permitida", ordem de venda com a categoria baixa de confirmação
                  //--- categoria de confirmação - com um indicador de alta e dois indicadores de baixa, em qualquer combinação
                  if((total_bull<total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) || 
                     (total_bull>total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])>MathAbs(Buffer_main_bear[i])) || 
                     (total_bull>total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_main_bull[i])<MathAbs(Buffer_main_bear[i]))) Buffer_color_bear[i]=2;
                  else
                    {
                     //--- 3 - cores do histograma clrGray - índice de cor "ordem de venda proibida"
                     //--- categoria de confirmação - quando o indicador de baixa está ausente
                     Buffer_color_bear[i]=3;
                    }
                 }
              }
           }
         //--- valor calculado da linha principal, somando-se as habilidades (skills) dos ursos e touros
         Buffer_calcLINE[i]=(Buffer_calc_bull[i]+Buffer_calc_bear[i])*line_deviation;
         //--- desenho de linha com preenchimento de cores por categorias de confirmação de sinal
         // 0 - clrDarkGreen - o índice de cor "apenas comprar"(only buy), ordem de compra com categoria alta de confirmação
         // 1 - clrDarkRed - o índice de cor "ordem de compra permitida" (sell order allowed), ordem de venda com a categoria média de confirmação
         // 2 - clrGray - índice de cor "nenhuma confirmação restrita" (no strict confirmation)
         if(draw_line)
           {
            //--- desenho dos valores da linha principal, somando-se as habilidades (skills) dos ursos e dos touros
            Buffer_mainline[i]=(Buffer_calc_bull[i]+Buffer_calc_bear[i])*line_deviation;
            //--- configurando a linha de cor como indefinida (2 - clrGray)
            Buffer_mainline_color[i]=2;
            //--- definindo a linha de cor da tendência de alta (0 - clr verde escuro), quando todos os três indicadores de tendência de alta combinam (bull>bear)
            if(total_bull>total_bear && MathAbs(sum_bull)>MathAbs(sum_bear) && MathAbs(Buffer_calc_bull[i])>MathAbs(Buffer_calc_bear[i])) Buffer_mainline_color[i]=0;
            //--- definindo a linha da cor da tendência de baixa (1 - cor vermelho escuro), quando todos os três indicadores de tendência de baixa combinam (bear>bull)
            if(total_bull<total_bear && MathAbs(sum_bull)<MathAbs(sum_bear) && MathAbs(Buffer_calc_bull[i])<MathAbs(Buffer_calc_bear[i])) Buffer_mainline_color[i]=1;
           }
        }
      //--- cálculando e desenhando a МA
      if(draw_MA_fast || draw_MA_slow)
        {
         //--- desabilitando a indexação, como nas séries temporais para transferência dentro da biblioteca MovingAverages.mqh (a indexação é alterado para ter uma barra de histórico atual no final do array)
         ArraySetAsSeries(Buffer_calcLINE,false);
         ArraySetAsSeries(Buffer_MAfast,false);
         ArraySetAsSeries(Buffer_MAslow,false);
         //--- iteração de todos as barras não calculadas. Iteration = All bars (rates_total) - deslocamento da barra a partir da última conhecida que foi calculada por _tm_prev (bars_calc)
         for(int i=rates_total-bars_calc; i<rates_total && !IsStopped(); i++)
           {
            //--- restrição dos cálculos estabelecidos nos parâmetros max_bars, cálculo apenas para a quantidade de max_bars como a diferença total de todas as barras (rates_total) menos o valor definido(max_bars)
            if(max_bars>0?(i<(rates_total-max_bars)):false)
              {
               //--- se o índice atual "i" diminui para além do valor permitido, continuamos com o índice permitido
               i=rates_total-max_bars;
               continue;
              }
            //--- anulando o array caso os dados da МА não sejam recebidos
            Buffer_MAfast[i]=0.0;
            Buffer_MAslow[i]=0.0;
            //--- seleção do método de cálculo da МА rápida com base no parâmetro method_MA_fast
            if(draw_MA_fast)
              {
               switch(method_MA_fast)
                 {
                  case MODE_SMA: // Média Simples
                     Buffer_MAfast[i]=SimpleMA(i,period_MA_fast,Buffer_calcLINE); // a obtenção de dados do índice i, SimpleMA, calculado a partir da biblioteca Include\\MovingAverages.mqh, baseado no de buffer de dados Buffer_calcLINE e no período period_MA_fast
                     break;
                  case MODE_EMA: // Média Exponencial
                     Buffer_MAfast[i]=ExponentialMA(i,period_MA_fast,Buffer_MAfast[i-1],Buffer_calcLINE);
                     break;
                  case MODE_SMMA: // Média Suavizada
                     Buffer_MAfast[i]=SmoothedMA(i+period_MA_fast,period_MA_fast,Buffer_MAfast[i-1],Buffer_calcLINE);
                     break;
                  case MODE_LWMA: // Média Ponderada Linear
                     Buffer_MAfast[i]=LinearWeightedMA(i+period_MA_fast,period_MA_fast,Buffer_calcLINE);
                     break;
                  default: return 0;
                 }
              }
            //--- seleção do cálculo do método MA lenta com base no parâmetro method_MA_slow
            if(draw_MA_slow)
              {
               switch(method_MA_slow)
                 {
                  case MODE_SMA: // Média Simples
                     Buffer_MAslow[i]=SimpleMA(i,period_MA_slow,Buffer_calcLINE);
                     break;
                  case MODE_EMA: // Média Exponencial
                     Buffer_MAslow[i]=ExponentialMA(i,period_MA_slow,Buffer_MAslow[i-1],Buffer_calcLINE);
                     break;
                  case MODE_SMMA: // Média Suavizada
                     Buffer_MAslow[i]=SmoothedMA(i,period_MA_slow,Buffer_MAslow[i-1],Buffer_calcLINE);
                     break;
                  case MODE_LWMA: // Média Ponderada Linear
                     Buffer_MAslow[i]=LinearWeightedMA(i,period_MA_slow,Buffer_calcLINE);
                     break;
                  default: return 0;
                 }
              }
           }
         //--- permitindo a indexação como nas séries temporais para desenhar
         ArraySetAsSeries(Buffer_calcLINE,true);
         ArraySetAsSeries(Buffer_MAfast,true);
         ArraySetAsSeries(Buffer_MAslow,true);
         //--- anulando dados da МА para a barra atual, ou seja, não calculados
         Buffer_MAfast[0]=EMPTY_VALUE;
         Buffer_MAslow[0]=EMPTY_VALUE;
         Buffer_calcLINE[0]=EMPTY_VALUE;
        }
      //--- memorizar o tempo  da última barra calculada
      _tm_prev=time[0];
     }
//--- valor de retorno do prev_calculated para a próxima chamada
   prev_rates_total=rates_total;
   return(rates_total);
  }

Valores da linha principal foram aumentados (valor da linha principal * linha desvio) até diminuir além do histograma para uma visualização conveniente ao exibir linhas e o histograma. A restrição da quantidade de barras calculadas (max_bars) foi adicionada para acelerar os cálculos em pequenos períodos, por exemplo no М1. O último bloco do código TakeShift_byTime é usado para obter o desvio da barra no tempo, com uma finalidade de encontrar a quantidade de barras necessária para os cálculos no bars_calc.


Capítulo 2. Aplicação prática do indicador "Rope" e criar o Expert Advisor

Neste capítulo concentraremos na criação do Expert Advisor EARopebyEricNaiman com base no indicador "Rope" (nome do código fonte do indicador — RopebyEricNaiman). O indicador pode ser utilizado como uma estratégia separada, com base no exemplo do Expert Advisor EARopebyEricNaiman, onde um filtro permite encontrar a direção da tendência. O autor considera várias abordagens para a utilização dos dados calculados pelo indicador neste livro. Foram selecionados os seguintes no Expert Advisor:

  • Intersecção da linha principal com 0 (linha principal cruza o zero). Acima da itersecção - comprar, abaixo da itersecção - vender.

  • Abertura, quando a principal cor da linha é alterada do cinza para verde (comprar) ou de cinza para vermelho (vender).

  • Abertura no principal cruzamento de linha com a МА rápida (linha principal cruza a MAfast). A linha principal cruzando a MA acima - ordem de compra; abaixo - ordem de venda.

  • Abrindo quando duas МАs se cruzarem. O MA rápida cruza o МА lenta acima - compra; abaixo - venda.

Além das configurações principais, o Expert Advisor possibilita a oportunidade para configurar separadamente 4 tipos de fechamentos correspondentes aos sinais de abertura, mas na direção oposta em comparação com um tipo da posição aberta:

//---  configurações para fechar a posição
input string section_5="___ Close settings";
//--- fechando na principal linha de intersecção com zero / fechando uma posição COMPRAR no cruzamento abaixo
input bool close1=true; // Close main line cross zero
//--- fechando quando a cor é alterada para a cor oposta da posição aberta / fechando uma posição COMPRAR quando mudar para vermelho
input bool close2=false; // Close main line color
//--- fechando na principal linha de intersecção com a linha МА / fechando uma posição COMPRAR  no cruzamento da linha principal abaixo da МА
input bool close3=false; // Fecha no cruzamento da linha principal com a MАfast
//---  fechando na intersecção de duas МАs / fechando uma posição COMPRAR no cruzamento da МА rápida com o МА lenta abaixo
input bool close4=true; // Fechar no cruzamento das duas MA 

Assim, a abertura é baseada num dos métodos selecionados na variável trade_mode, o fechamento é executado pelo Stop Loss, ou Take Profit ou por um dos métodos acima mencionados. O código fonte completo do expert e do indicador pode ser baixado e visto nos arquivos anexos ao artigo. Neste artigo nós somente analisamos o cálculo principal da parte dos sinais para as abertura e fechamento das posições.

  • Principais variáveis e o indicador RopebyEricNaiman são inicializados no bloco OnInit().
  • O bloсo OnTick() contém o bloco de gestão para as posições de abertura e fechamento.
  • O bloco de cálculo do sinal Check_Indi_Open() é usado para carregar dados do indicador e procurar um sinal de abertura.
//+------------------------------------------------------------------+
//| Check_Indi_Open                                                  |
//+------------------------------------------------------------------+
int Check_Indi_Open()
  {
   //--- declaração de arrays para a obtenção de dados do indicador
   int copy=0;
   double _arr_ind_1[];
   double mafast[];
   double mainline[];
   double maslow[];
   //--- utilizando a função switch para selecionar o método de abertura com base no parâmetro trade_mode da variável externa
   switch((int)trade_mode)
     {
      case 0:
         //--- linha principal do indicador compara duas últimas barras, exceto a atual
         copy=Copy_indi_Buffer(RbEN_handle,4,1,2,_arr_ind_1,"RbEN");
         if(copy!=2) return 4;
         if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && 
            _arr_ind_1[0]>0 && _arr_ind_1[1]<=0)
           {
            return 0;
           }
         if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && 
            _arr_ind_1[0]<0 && _arr_ind_1[1]>=0)
           {
            return 1;
           }
         break;
      case 1:
         //--- a obtenção do índice de cor do indicador a partir do buffer Nº 5 nas duas últimas barras, exceto a atual
         copy=Copy_indi_Buffer(RbEN_handle,5,1,2,_arr_ind_1,"RbEN");
         if(copy!=2) return 5;
         if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && 
            _arr_ind_1[0]==0 && _arr_ind_1[1]!=0)
           {
            return 0;
           }
         if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && 
            _arr_ind_1[0]==1 && _arr_ind_1[1]!=1)
           {
            return 1;
           }
         break;
      case 2:
         //--- recebimento e comparação da "mafast" (МА sobre linha principal do indicador) e valor da "mainline" (linha principal do indicador) nas últimas duas barras, exceto a atual.
         copy=Copy_indi_Buffer(RbEN_handle,6,1,2,mafast,"RbEN");
         if(copy!=2) return 6;
         copy=Copy_indi_Buffer(RbEN_handle,4,1,2,mainline,"RbEN");
         if(copy!=2) return 7;
         if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && 
            mainline[0]!=EMPTY_VALUE && mainline[1]!=EMPTY_VALUE && 
            mainline[0]>mafast[0] && mainline[1]<=mafast[1])
           {
            return 0;
           }
         if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && 
            mainline[0]!=EMPTY_VALUE && mainline[1]!=EMPTY_VALUE && 
            mainline[0]<mafast[0] && mainline[1]>=mafast[1])
           {
            return 1;
           }
         break;
      case 3:
         //--- recebimento e comparação da "mafast" (МА rápida sobre a linha principal do indicador) e a "maslow" (МА lenta sobre a linha principal do indicador), exceto a atual
         copy=Copy_indi_Buffer(RbEN_handle,6,1,2,mafast,"RbEN");
         if(copy!=2) return 8;
         copy=Copy_indi_Buffer(RbEN_handle,7,1,2,maslow,"RbEN");
         if(copy!=2) return 9;
         if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE &&
            maslow[0]!=EMPTY_VALUE && maslow[1]!=EMPTY_VALUE &&
            maslow[0]<mafast[0] && maslow[1]>=mafast[1])
           {
            return 0;
           }
         if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE &&
            maslow[0]!=EMPTY_VALUE && maslow[1]!=EMPTY_VALUE &&
            maslow[0]>mafast[0] && maslow[1]<=mafast[1])
           {
            return 1;
           }
         break;
      default: return 3;
     }
//---
   return 2;
  }

Existe uma iteração realizada no bloco Check_Indi_Close() de acordo com as configurações de entrada de todos os quatro métodos de fechamento de uma posição aberta:

//+------------------------------------------------------------------+
//| Check_Indi_Close                                                 |
//+------------------------------------------------------------------+
int Check_Indi_Close()
  {
   //--- declaração de arrays para a obtenção de dados do indicador
   int copy=0;
   double _arr_ind_1[];
   double mafast[];
   double mainline[];
   double maslow[];
   _str_close="";
   //--- recepção e comparação com a linha zero da linha principal nas duas últimas barras, exceto a atual
   if(close1)
     {
      copy=Copy_indi_Buffer(RbEN_handle,4,1,2,_arr_ind_1,"RbEN");
      if(copy!=2) return 4;
      _str_close="Close main line cross zero";
      if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && 
         _arr_ind_1[0]>0 && _arr_ind_1[1]<=0)
        {
         return 0;
        }
      if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && 
         _arr_ind_1[0]<0 && _arr_ind_1[1]>=0)
        {
         return 1;
        }
     }
   //--- a obtenção do índice de cor do indicador a partir do buffer Nº 5 nas duas últimas barras, exceto a atual
   if(close2)
     {
      copy=Copy_indi_Buffer(RbEN_handle,5,1,2,_arr_ind_1,"RbEN");
      if(copy!=2) return 5;
      _str_close="Close main line color";
      if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && 
         _arr_ind_1[0]==0 && _arr_ind_1[1]!=0)
        {
         return 0;
        }
      if(_arr_ind_1[0]!=EMPTY_VALUE && _arr_ind_1[1]!=EMPTY_VALUE && 
         _arr_ind_1[0]==1 && _arr_ind_1[1]!=1)
        {
         return 1;
        }
     }
   //--- recebimento e comparação da "mafast" (МА sobre linha principal do indicador) e valor da "mainline" (linha principal do indicador) nas últimas duas barras, exceto a atual.
   if(close3)
     {
      copy=Copy_indi_Buffer(RbEN_handle,6,1,2,mafast,"RbEN");
      if(copy!=2) return 6;
      copy=Copy_indi_Buffer(RbEN_handle,4,1,2,mainline,"RbEN");
      if(copy!=2) return 7;
      _str_close="Close main line cross MAfast";
      if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && 
         mainline[0]!=EMPTY_VALUE && mainline[1]!=EMPTY_VALUE && 
         mainline[0]>mafast[0] && mainline[1]<=mafast[1])
        {
         return 0;
        }
      if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE && 
         mainline[0]!=EMPTY_VALUE && mainline[1]!=EMPTY_VALUE && 
         mainline[0]<mafast[0] && mainline[1]>=mafast[1])
        {
         return 1;
        }
     }
   //--- recebimento e comparação da "mafast" (МА rápida sobre a linha principal do indicador) e a "maslow" (МА lenta sobre a linha principal do indicador), exceto a atual
   if(close4)
     {
      copy=Copy_indi_Buffer(RbEN_handle,6,1,2,mafast,"RbEN");
      if(copy!=2) return 8;
      copy=Copy_indi_Buffer(RbEN_handle,7,1,2,maslow,"RbEN");
      if(copy!=2) return 9;
      _str_close="Close two MA cross";
      if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE &&
         maslow[0]!=EMPTY_VALUE && maslow[1]!=EMPTY_VALUE &&
         maslow[0]<mafast[0] && maslow[1]>=mafast[1])
        {
         return 0;
        }
      if(mafast[0]!=EMPTY_VALUE && mafast[1]!=EMPTY_VALUE &&
         maslow[0]!=EMPTY_VALUE && maslow[1]!=EMPTY_VALUE &&
         maslow[0]>mafast[0] && maslow[1]<=mafast[1])
        {
         return 1;
        }
     }
//---
   return 2;
  }

  • O bloco Copy_indi_Buffer() é criado para receber os dados do indicador usando a função CopyBuffer().
  • O bloco TakeLastOpenTime() é usado para receber o tempo da última posição aberta, com o objetivo de comparação (em OnTick) com o tempo de abertura da barra, a fim de evitar a múltipla abertura da posição sobre uma barra.
  • OpenPosition() — uma função para a abertura de posição.
  • Copy_Time() copia o tempo da barra indicada.
  • CloseAllPosition() fecha toda as posições.

Após criarmos o Expert Advisor, procedemos à otimização dos parâmetros de entrada, descrito no próximo capítulo.


Capítulo 3. Otimização dos parâmetros de entrada do Expert Advisor

Antes de executar o Expert Advisor devemos otimizar os principais parâmetros de entrada. O símbolo EURUSD H1 2005-2015 (algoritmo genético de otimização) foi selecionado como exemplo. A otimização separada é executada para todos os quatro tipos de abertura.

1. trade_mode = linha principal cruzando zero (linha principal intersecção com 0: cruzamento acima - comprar; cruzando abaixo - vender).

Parâmetros para otimização:

Valor Iníciar Passo Stop Passos
StopLoss 0 50 10000 201
TakeProfit 0 50 10000 201
_period 1 1 200 200
close1 false
true 2
Passes totais


16160400

A otimização e os melhores resultados de teste podem ser vistos no arquivo anexo ao artigo, denominado optimization.zip, na pasta "EURUSD H1 2005-2015\test1 - main line cross zero\".


2. trade_mode = altera a cor da linha principal (abertura, quando a cor da linha principal é alterada do cinza para verde (comprar) ou de cinza para vermelho (vender)).

Parâmetros para otimização:

Valor Iníciar Passo Stop Passos
StopLoss 0 50 10000 201
TakeProfit 0 50 10000 201
_period 1 1 200 200
close2 false
true 2
Passes totais


16160400

A otimização e os melhores resultados de teste podem ser vistos no arquivo anexo, denominado optimization.zip, na pasta "EURUSD H1 2005-2015\test2 - main line color\".


3. trade_mode = a linha principal cruza a MAfast (abertura na intersecção da linha principal com a МА rápida: a linha principal cruza o MA acima - comprar; abaixo - vender).

Parâmetros para otimização:

Valor Iníciar Passo Stop Passos
StopLoss 0 50 10000 201
TakeProfit 0 50 10000 201
_period 1 1 200 200
period_MA_fast 1 1 300 300
close3 false
true 2
Passes totais


4848120000

A otimização e os melhores resultados de teste podem ser vistos no arquivo anexo, denominado optimization.zip, na pasta "EURUSD H1 2005-2015\test3 - main line cross MAfast\".


4. trade_mode = duas MAs se ruzam (abertura na intersecção de duas MAs: ao МА rápida cruza o МА lenta acima - ordem de compra; abaixo - ordem de venda).

Parâmetros para otimização:

Valor Iníciar Passo Stop Passos
StopLoss 0 50 10000 201
TakeProfit 0 50 10000 201
_period 1 1 200 200
period_MA_fast 1 1 300 300
period_MA_slow 1 1 400 400
close4 false
true 2
Passes totais


1939248000000

A otimização e os melhores resultados de teste podem ser vistos no arquivo anexo, denominado optimization.zip, na pasta "EURUSD H1 2005-2015\test4 - two MA cross\".



Conclusão

Os resultados de otimização provam a viabilidade desta estratégia, considerando que o Expert Advisor é construído com base na pura lógica de como o indicador funciona, sem o uso de quaisquer funções adicionais para a gestão do dinheiro. Falando de pura lógica, implica na estratégia do autor em descobrir a tendência, baseada na avaliação estática de vigor das tendências de altas (bulls) e baixas (bears) durante o período de tempo especificado. Usando este indicador, definimos os pontos de entrada no mercado de núcleo, portanto o indicador é aplicável tanto como filtro na sua estratégia como sinal base para a abertura das negociações.

Veja os arquivos anexos para encontrar o código-fonte do indicador e do Expert Advisor, você pode usá-los no seu desenvolvimento pessoal no campo da programação e das negociações. Esta estratégia foi implementada e mostrada em pequenas áreas de uso (sinais básicos para entrada/saída), onde já demonstrou a sua capacidade de trabalho nos estágios iniciais.

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

Arquivos anexados |
optimization.zip (2230.41 KB)
Características dos Experts Advisors Características dos Experts Advisors
O desenvolvimento de expert advisors no sistema de negociação MetaTrader tem uma série de características.
Usando Layouts e Containers para Controles da Interface Gráfica do Usuário (GUI): A Classe CGrid Usando Layouts e Containers para Controles da Interface Gráfica do Usuário (GUI): A Classe CGrid
Este artigo apresenta um método alternativo de criação da Interface Gráfica do Usuário (GUI) com base em layouts e containers, usando um gerenciador de layout - a classe CGrid. A classe CGrid é um comando auxiliar, atua como um container para outros containers e faz o controle usando um layout de grade.
Características do Desenvolvimento de Indicadores Personalizados Características do Desenvolvimento de Indicadores Personalizados
O Desenvolvimento de Indicadores Personalizados no sistema de negociação MetaTrader tem uma série de características.
Avaliação e seleção de variáveis para os modelos de aprendizado da máquina Avaliação e seleção de variáveis para os modelos de aprendizado da máquina
Este artigo foca sobre as especificidades de escolha, o pré-condicionamento e avaliação das variáveis de entrada (preditoras) para uso em modelos de aprendizagem da máquina. Novas abordagens e oportunidades de análises preditoras profundas e suas influências no possível sobre-ajuste (overfitting) dos modelos serão consideradas. O resultado global do uso de modelos, em grande parte, depende do resultado desta etapa. Vamos analisar dois pacotes, oferecendo abordagens novas e originais para a seleção dos preditores.