English Русский Deutsch 日本語
preview
Desenvolvimento e teste de sistemas de negociação Aroon

Desenvolvimento e teste de sistemas de negociação Aroon

MetaTrader 5Negociação | 27 junho 2024, 13:20
97 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introdução

No campo da negociação e análise técnica, existem muitas ferramentas que podemos usar, mas certamente não usaremos todas elas e escolheremos uma ou uma combinação de ferramentas lucrativas após testá-las e otimizá-las. O objetivo deste artigo é tentar fornecer um método que pode ser útil neste contexto, ou dar uma visão de outra perspectiva ou ideia que você pode aplicar e ver qual sistema de negociação automatizado se adequa a você.

Artigos desse tipo são úteis porque seu estudo não leva muito tempo, mas a maior parte do trabalho você precisará fazer por conta própria para encontrar as configurações ideais do sistema de negociação. Estamos simplesmente tentando apresentar aqui ferramentas de negociação que podem ser usadas individualmente ou em combinação com outras ferramentas, para economizar seu tempo. Aqui também é descrito como programar esses sistemas para testar no Testador de Estratégia. Isso significa que você pode economizar muito tempo automatizando o processo de teste em vez de testá-lo manualmente.

Neste artigo, vamos usar o indicador técnico Aroon, testar mais de uma estratégia baseada em seus conceitos e ver os resultados. Será muito mais valioso aprendermos como podemos codificar o indicador no MQL5 e usá-lo em nosso sistema de negociação baseado em estratégia. Tudo isso acontecerá depois que aprendermos o que é o indicador Aroon e como ele pode ser calculado e usado.

Neste artigo, abordaremos os seguintes tópicos:

Após os tópicos anteriores, aprenderemos muito mais sobre o indicador Aroon, em particular como podemos usá-lo, o que precisamos para construir um sistema de negociação, estratégias de negociação Aroon, construção de sistemas de negociação baseados nessas estratégias e seus testes, além de ver quão úteis eles são na negociação.

O teste deve ser realizado em diferentes aspectos para obter os melhores resultados que se adequem ao seu estilo de negociação ou ao seu sistema de negociação, especialmente se você planeja adicionar qualquer ferramenta ao seu sistema de negociação existente. Não existem estratégias ou sistemas de negociação universais, mas posso contribuir mostrando parte deles, o que ajudará a economizar seu tempo.

Atenção! Todo o conteúdo deste artigo é fornecido "como está", destinado apenas para fins educacionais e não constitui uma recomendação de negociação. O artigo não oferece garantias de resultados. Tudo o que você aplicar na prática com base neste artigo, você faz exclusivamente por sua conta e risco, o autor não garante quaisquer resultados.


Definição do indicador Aroon

Primeiramente, vamos definir o indicador técnico Aroon para entender sua ideia principal.

O Aroon foi criado por Tushar S. Chande em 1995. Os principais objetivos do indicador são detectar mudanças de tendência e medir a força da tendência. O indicador pode fazer isso medindo quanto tempo se passou entre os máximos e quanto tempo se passou entre os mínimos em um determinado período. Uma forte tendência de alta é caracterizada por novos máximos regulares, enquanto uma forte tendência de baixa é caracterizada por novos mínimos regulares. O indicador detecta esses padrões e os sinaliza.

O indicador Aroon consiste em duas linhas: Aroon Up, que mede a força da tendência de alta, e Aroon Down, que mede a força da tendência de baixa. Neste contexto, podemos dizer que quando o Aroon Up está acima do Aroon Down, isso indica um sinal de alta. Quando o Aroon Down está acima do Aroon Up, isso é um sinal de baixa. Os indicadores Aroon também se movem ou oscilam entre níveis de zero a 100.

A seguir, é descrito como calcular o indicador técnico Aroon:

Aroon Up     = 100 * ((n-H)/n)

Aroon Down = 100 * ((n-L)/n)

onde:

  • Aroon Up é expresso em porcentagem do total de períodos n e representa o número de períodos desde o último máximo do período n.
  • Aroon Down é expresso em porcentagem do total de períodos n e representa o número de períodos desde o último mínimo do período n.
  • H é o número de períodos no tempo especificado de n períodos desde o último máximo do período n.
  • L é o número de períodos no tempo especificado de n períodos desde o último mínimo do período n.
  • n é o período.


Estratégias Aroon

Vamos considerar duas estratégias simples para usar o indicador Aroon. Essas estratégias serão implementadas usando MQL5 para teste no testador de estratégias, visualizar os resultados de cada uma e compará-los.

Usaremos duas estratégias principais:

  • Aroon Crossover Strategy (estratégia de cruzamento)
  • Aroon Levels Strategy (estratégia de níveis)

Aroon Crossover Strategy:

Precisamos colocar uma ordem no cruzamento das linhas superior e inferior do indicador Aroon. Assim, precisamos abrir uma ordem de compra quando vemos que o Aroon Up (Upline) cruza a linha Aroon Down (Downline) para cima, e uma ordem de venda se o Aroon Down cruzar a linha Aroon Up para cima.

Upline > Downline ==> compra

Downline > Upline ==> venda

Aroon Levels Strategy:

Abrimos uma ordem se a linha Aroon Down cruzar os níveis 10 e 50 do indicador Aroon. Assim, precisamos colocar uma ordem de compra se a linha Aroon Down estiver abaixo do nível 10, e colocar uma ordem de venda se estiver acima do nível 50 do indicador Aroon.

Downline < 10 ==> compra

Downline > 50 ==> venda


Sistemas de negociação Aroon

Nesta parte, aprenderemos a codificar as estratégias Aroon mencionadas no MQL5 para testá-las no testador e avaliar seus resultados. Primeiramente, precisamos codificar nosso próprio indicador Aroon para poder usá-lo em nossas estratégias de negociação, conforme mostrado abaixo:

Na área global do MQL5, defina as propriedades dos indicadores usando o pré-processador de propriedades.

//properties of the indicator
#property indicator_separate_window // the place of the indicator
#property indicator_buffers 2 // number of buffers
#property indicator_plots 2 // number of plots

//up line
#property indicator_type1  DRAW_LINE      // type of the up values to be drawn is a line
#property indicator_color1 clrGreen       // up line color
#property indicator_style1 STYLE_DASH     // up line style
#property indicator_width1 2              // up line width
#property indicator_label1 "Up"           // up line label

// down line
#property indicator_type2  DRAW_LINE      // type of the down values to be drawn is a line
#property indicator_color2 clrRed         // down line color
#property indicator_style2 STYLE_DASH     // down line style
#property indicator_width2 2              // down line width
#property indicator_label2 "Down"         // down line label

// drawing some levels to be used later 10 and 50
#property indicator_level1 10.0
#property indicator_level2 50.0
#property indicator_levelcolor clrSilver
#property indicator_levelstyle STYLE_DOT

Criação de duas entradas de dados inteiros para o indicador: período e deslocamento horizontal usando a palavra-chave input.

//inputs
input int                      periodInp = 25; // Period
input int                      shiftInp  = 0;  // horizontal shift

Criação de dois arrays duplos para os valores up e down do indicador.

//buffers of the indicator
double                         upBuffer[];
double                         downBuffer[];

No OnInit(), ao usar a função SetIndexBuffer para vincular os buffers do indicador aos arrays duplos, os parâmetros são os seguintes:

  • index - para indicar o índice do buffer, usaremos 0 para upBuffer e 1 para downBuffer.
  • buffer[] - para indicar o array, usaremos os arrays upBuffer e downBuffer.
  • data_type - para indicar o tipo de dados que precisamos armazenar (isso pode ser um dos ENUM_INDEXBUFFER_TYPE), usaremos INDICATOR_DATA tanto para up quanto para down.
   SetIndexBuffer(0, upBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, downBuffer, INDICATOR_DATA);

Definição dos valores da propriedade correspondente e das linhas de indicador correspondentes up e down usando a função PlotIndexSetInteger com a opção de chamada indicando o identificador da propriedade e os parâmetros inclui:

  • plot_index - valor inteiro do índice de estilo de exibição, será 0 para up e 1 para down.
  • prop_id:: - valor inteiro do identificador da propriedade, pode ser um dos ENUM_PLOT_PROPERTY_INTEGER. Usaremos PLOT_SHIFT e PLOT_DRAW_BEGIN para up e down.
  • prop_value - valor inteiro, shiftInp e periodInp para up e down.
   PlotIndexSetInteger(0, PLOT_SHIFT, shiftInp);
   PlotIndexSetInteger(1, PLOT_SHIFT, shiftInp);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, periodInp);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, periodInp);

Definição do flag AS_SERIES para os arrays up e down.

   ArraySetAsSeries(upBuffer, true);
   ArraySetAsSeries(downBuffer, true);

Definição do nome da string e valores inteiros do indicador após declarar a variável string indicatorName e atribuir a função StringFormat para definir o formato do que precisamos ver na janela do indicador.

   string indicatorName = StringFormat("Aroon Indicator (%i,%i) - ", periodInp, shiftInp);
   IndicatorSetString(INDICATOR_SHORTNAME, indicatorName);
   IndicatorSetInteger(INDICATOR_DIGITS, 0);

Retorno de INIT_SUCCEEDED como parte do evento OnInit().

return INIT_SUCCEEDED;

Evento OnCalculate,

int OnCalculate(const int       rates_total,
                const int       prev_calculated,
                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[])

No corpo do evento, calculamos o indicador, retornando 0 se os dados forem insuficientes.

   if(rates_total < periodInp - 1)
      return (0);

Criação de uma variável inteira contadora e cálculo dela como resultado da subtração de rate_total e prev_calculated.

int count = rates_total - prev_calculated;

Se prev_calculated for maior que 0, o que significa que temos novos dados, atualizaremos o contador, adicionando 1.

   if(prev_calculated > 0)
      count++;

Criaremos outra condição para atualizar o valor do contador.

   if(count > (rates_total - periodInp + 1))
      count = (rates_total - periodInp + 1);

Criação de um loop for para calcular e atualizar os valores do indicador up e down após o cálculo dos valores mais altos e mais baixos.

   for(int i = count - 1; i >= 0; i--)
     {
      int highestVal   = iHighest(Symbol(), Period(), MODE_HIGH, periodInp, i);
      int lowestVal    = iLowest(Symbol(), Period(), MODE_LOW, periodInp, i);
      upBuffer[i]   = (periodInp - (highestVal - i)) * 100 / periodInp;
      downBuffer[i] = (periodInp - (lowestVal - i)) * 100 / periodInp;
     }

Retorno de rate_total como parte do evento OnCalculate.

return (rates_total);

Assim, abaixo está o código completo para criar nosso indicador personalizado Aroon em um bloco de código.

//+------------------------------------------------------------------+
//|                                                        Aroon.mq5 |
//+------------------------------------------------------------------+
#property indicator_separate_window // the place of the indicator
#property indicator_buffers 2 // number of buffers
#property indicator_plots 2 // number of plots
#property indicator_type1  DRAW_LINE      // type of the up values to be drawn is a line
#property indicator_color1 clrGreen       // up line color
#property indicator_style1 STYLE_DASH     // up line style
#property indicator_width1 2              // up line width
#property indicator_label1 "Up"           // up line label
#property indicator_type2  DRAW_LINE      // type of the down values to be drawn is a line
#property indicator_color2 clrRed         // down line color
#property indicator_style2 STYLE_DASH     // down line style
#property indicator_width2 2              // down line width
#property indicator_label2 "Down"         // down line label
#property indicator_level1 10.0
#property indicator_level2 50.0
#property indicator_levelcolor clrSilver
#property indicator_levelstyle STYLE_DOT
input int periodInp = 25; // Period
input int shiftInp  = 0;  // horizontal shift
double    upBuffer[];
double    downBuffer[];
int OnInit()
  {
   SetIndexBuffer(0, upBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, downBuffer, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_SHIFT, shiftInp);
   PlotIndexSetInteger(1, PLOT_SHIFT, shiftInp);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, periodInp);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, periodInp);
   ArraySetAsSeries(upBuffer, true);
   ArraySetAsSeries(downBuffer, true);
   string indicatorName = StringFormat("Aroon Indicator (%i,%i) - ", periodInp, shiftInp);
   IndicatorSetString(INDICATOR_SHORTNAME, indicatorName);
   IndicatorSetInteger(INDICATOR_DIGITS, 0);
   return INIT_SUCCEEDED;
  }
int OnCalculate(const int       rates_total,
                const int       prev_calculated,
                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[])
  {
   if(rates_total < periodInp - 1)
      return (0);
   int count = rates_total - prev_calculated;
   if(prev_calculated > 0)
      count++;
   if(count > (rates_total - periodInp + 1))
      count = (rates_total - periodInp + 1);
   for(int i = count - 1; i >= 0; i--)
     {
      int highestVal   = iHighest(Symbol(), Period(), MODE_HIGH, periodInp, i);
      int lowestVal    = iLowest(Symbol(), Period(), MODE_LOW, periodInp, i);
      upBuffer[i]   = (periodInp - (highestVal - i)) * 100 / periodInp;
      downBuffer[i] = (periodInp - (lowestVal - i)) * 100 / periodInp;
     }
   return (rates_total);
  }
//+------------------------------------------------------------------+

Após a compilação do código, veremos como nosso indicador personalizado se parece quando executado no gráfico.

 Aroon ind

O indicador está pronto e podemos criar nossas estratégias de negociação. Começaremos com o cruzamento das linhas Aroon e, em seguida, passaremos para os níveis, mas antes disso, criaremos um programa simples que poderá exibir os valores Aroon up e down. O método a seguir permite fazer isso:

Primeiro, na área global, criaremos dois parâmetros de entrada personalizados Period e Shift, usando a palavra-chave input.

input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift

Declararemos uma variável inteira para Aroon, para depois atribuir a ela o handle do indicador.

int aroon;

No OnInit(), atribuiremos a função iCustom para anexar ou retornar o handle do indicador personalizado Aroon ao EA. Os parâmetros são os seguintes:

  • Symbol - nome do símbolo, usaremos _Symbol para retornar o atual.
  • period - período, usaremos _Period para retornar o atual.
  • name - nome exato do indicador personalizado, indicando seu caminho exato na pasta Indicators.
  • Em seguida, indicaremos a lista de parâmetros de entrada do indicador personalizado. Usaremos apenas os dois parâmetros de entrada criados (Period e Shift).
aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);

Então, retornamos (INIT_SUCCEEDED) quando o EA for inicializado com sucesso.

return(INIT_SUCCEEDED);

No OnDeinit, imprimiremos "EA is removed" (EA removido), usando a palavra-chave Print, quando ocorrer o evento Deinit para desinicializar o programa MQL5 em execução.

void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }

No evento OnTick(), declararemos dois arrays double - upBuffer e downBuffer.

double upBuffer[], downBuffer[];

Obtenção de dados dos buffers do indicador Aroon criado, usando a função CopyBuffer com a opção de chamada pela primeira posição e o número de elementos necessários e parâmetros:

  • indicator_handle - handle do indicador personalizado Aroon.
  • buffer_num - número do buffer do indicador.
  • start_pos - posição inicial.
  • count - número de contadores, começando em start_pos.
  • buffer[] - array de destino.
   CopyBuffer(aroon,0,0,3,upBuffer);
   CopyBuffer(aroon,1,0,3,downBuffer);

Uso do ArraySetAsSeries para definir o flag AS_SERIES no flag especificado, que será verdadeiro para a ordem inversa de indexação dos arrays.

   ArraySetAsSeries(upBuffer,true);
   ArraySetAsSeries(downBuffer,true);

Declaração de duas variáveis duplas upValue e downValue para atribuir os valores atuais do indicador Aroon a partir dos arrays por meio de indexação [0].

   double upValue = upBuffer[0];
   double downValue = downBuffer[0];

Uso da função Comment para exibir o comentário no gráfico com os valores do indicador up e down.

Comment("upValue: ",upValue,"\ndownValue: ",downValue);

Abaixo está o código completo em um bloco:

//+------------------------------------------------------------------+
//|                                                AroonValuesEA.mq5 |
//+------------------------------------------------------------------+
input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift
int aroon;
int OnInit()
  {
   aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
   double upBuffer[], downBuffer[];
   CopyBuffer(aroon,0,0,3,upBuffer);
   CopyBuffer(aroon,1,0,3,downBuffer);
   ArraySetAsSeries(upBuffer,true);
   ArraySetAsSeries(downBuffer,true);
   double upValue = upBuffer[0];
   double downValue = downBuffer[0];
   Comment("upValue: ",upValue,"\ndownValue: ",downValue);
  }
//+------------------------------------------------------------------+

Após a compilação sem erros do código e a execução do EA no gráfico, podemos ver suas saídas, como no exemplo a seguir:

AroonValues

Como vemos no gráfico anterior, os valores up e down são mostrados como comentário. O indicador personalizado é executado no gráfico para garantir que o EA retorne os mesmos valores do indicador (96, 48).

Estratégia de cruzamento:

Agora é hora de implementar as estratégias de negociação mencionadas no código. Começaremos com a estratégia de cruzamento.

Em âmbito global, usaremos o pré-processador #include para incluir funções de negociação no nosso EA para a colocação automática de ordens com base na nossa estratégia.

#include <trade/trade.mqh>

Criaremos cinco variáveis de entrada: period, horizontal shift, lotSize, slLvl e tpLvl, e atribuiremos valores padrão para cada uma.

input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift
input double      lotSize=1;
input double      slLvl=200;
input double      tpLvl=600;

Criaremos as seguintes variáveis:

  • Variável inteira Aroon, que será usada posteriormente para definir o indicador.
  • Variável inteira barstotal usada para limitar a abertura de ordens para cada barra.
  • Objeto de negociação CTrade, que será usado ao colocar ordens.
int aroon;
int barsTotal;
CTrade trade;

No evento OnInit(), definiremos a variável barsTotal declarada usando as funções iBars, que retornam as barras disponíveis do símbolo e período no histórico.

barsTotal=iBars(_Symbol,PERIOD_CURRENT);

Definiremos a variável Aroon usando iCustom para incluir o indicador personalizado Aroon que criamos.

aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);

No evento OnDeinit(), imprimiremos uma notificação de remoção do EA.

Print("EA is removed");

No evento OnTick(), declararemos uma variável inteira bars para armazenar o número de barras para cada tick.

int bars=iBars(_Symbol,PERIOD_CURRENT);

Verificamos se barsTotal e bars são iguais.

if(barsTotal != bars)

Em seguida, atualizamos barsTotal usando os buffers de barras.

barsTotal=bars;

Declaramos dois arrays double up e down, obtemos os dados dos buffers do indicador, definimos o flag AS_SERIES para o array selecionado, declaramos e definimos quatro variáveis duplas para os valores up e down anteriores e atuais.

      double upBuffer[], downBuffer[];
      CopyBuffer(aroon,0,0,3,upBuffer);
      CopyBuffer(aroon,1,0,3,downBuffer);
      ArraySetAsSeries(upBuffer,true);
      ArraySetAsSeries(downBuffer,true);
      double prevUpValue = upBuffer[1];
      double prevDownValue = downBuffer[1];
      double upValue = upBuffer[0];
      double downValue = downBuffer[0];

Depois, definimos as condições para a ordem de compra, que são: prevUpValue é menor que prevDownValue, e ao mesmo tempo upValue é maior que downValue.

if(prevUpValue<prevDownValue && upValue>downValue)

Quando essa condição for satisfeita, declaramos uma variável double ask e seu preço atual ask do símbolo atual, também declaramos e definimos slVal e tpVal, e colocamos posições de compra com o valor de lotSize predefinido pelo usuário no símbolo atual. Ao preço atual ask, o stop-loss será o mesmo que o predefinido para slVal, e o take-profit será o mesmo que para tpVal.

         double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);

Em seguida, definimos as condições para a ordem de venda, que são: prevUpValue é maior que prevDownValue, e ao mesmo tempo upValue é menor que downValue.

if(prevUpValue>prevDownValue && upValue<downValue)
Quando essa condição for satisfeita, declaramos uma variável double bid e seu preço atual bid do símbolo atual, também declaramos e definimos slVal e tpVal, e colocamos posições de venda com o valor de lotSize predefinido pelo usuário no símbolo atual. Ao preço atual bid, o stop-loss será o mesmo que o predefinido para slVal, e o take-profit será o mesmo que para tpVal.
         double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);

Abaixo está o código completo da estratégia de cruzamento Aroon em um bloco:

//+------------------------------------------------------------------+
//|                                             AroonCrossoverEA.mq5 |
//+------------------------------------------------------------------+
#include <trade/trade.mqh>
input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift
input double      lotSize=1;
input double      slLvl=200;
input double      tpLvl=600;
int aroon;
int barsTotal;
CTrade trade;
int OnInit()
  {
   barsTotal=iBars(_Symbol,PERIOD_CURRENT);
   aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
   int bars=iBars(_Symbol,PERIOD_CURRENT);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      double upBuffer[], downBuffer[];
      CopyBuffer(aroon,0,0,3,upBuffer);
      CopyBuffer(aroon,1,0,3,downBuffer);
      ArraySetAsSeries(upBuffer,true);
      ArraySetAsSeries(downBuffer,true);
      double prevUpValue = upBuffer[1];
      double prevDownValue = downBuffer[1];
      double upValue = upBuffer[0];
      double downValue = downBuffer[0];
      if(prevUpValue<prevDownValue && upValue>downValue)
        {
         double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }
      if(prevUpValue>prevDownValue && upValue<downValue)
        {
         double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
        }
     }
  }
//+------------------------------------------------------------------+

Após a compilação bem-sucedida do código, podemos encontrar exemplos de colocação de ordens com base na seguinte estratégia:

Exemplo de ordem de compra:

compra

Como vemos no exemplo anterior, temos uma ordem de compra após o cruzamento das linhas up e down.

Exemplo de ordem de venda:

venda

Como vemos no exemplo anterior, temos uma ordem de venda após a linha down cruzar a linha up.

Estratégia de níveis:

Nesta parte, implementaremos a estratégia de níveis Aroon, que permitirá ao EA abrir uma ordem com base no cruzamento da linha down com os níveis 10 e 50 do próprio indicador Aroon. Abaixo mostramos como podemos implementar essa estratégia no MQL5. O código é bastante semelhante ao que foi implementado para a estratégia de cruzamento, então apresentarei o código completo e destacarei as diferenças.

Abaixo está o código completo para codificar a estratégia de níveis Aroon em um bloco de código:

//+------------------------------------------------------------------+
//|                                                AroonLevelsEA.mq5 |
//+------------------------------------------------------------------+
#include <trade/trade.mqh>
input int         periodInp = 25; // Period
input int         shiftInp  = 0; // Shift
input double      lotSize=1;
input double      slLvl=200;
input double      tpLvl=600;
int aroon;
int barsTotal;
CTrade trade;
int OnInit()
  {
   barsTotal=iBars(_Symbol,PERIOD_CURRENT);
   aroon = iCustom(_Symbol,PERIOD_CURRENT,"Aroon",periodInp,shiftInp);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
   int bars=iBars(_Symbol,PERIOD_CURRENT);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      double upBuffer[], downBuffer[];
      CopyBuffer(aroon,0,0,3,upBuffer);
      CopyBuffer(aroon,1,0,3,downBuffer);
      ArraySetAsSeries(upBuffer,true);
      ArraySetAsSeries(downBuffer,true);
      double prevDownValue = downBuffer[1];
      double downValue = downBuffer[0];
      if(prevDownValue> 10 && downValue<10)
        {
         double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }
      if(prevDownValue < 50 && downValue>50)
        {
         double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
        }
     }
  }

Diferenças no código:

Precisamos apenas definir os valores anteriores e atuais

      double prevDownValue = downBuffer[1];
      double downValue = downBuffer[0];

Condição da estratégia: se prevDownValue for maior que o nível 10 e ao mesmo tempo o valor atual de downValue for menor que o nível 10. Precisamos que o EA coloque uma ordem de compra após definir ask, stop-loss e take-profit.

      if(prevDownValue> 10 && downValue<10)
        {
         double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }

Se prevDownValue for menor que o nível 50 e ao mesmo tempo o valor atual de downValue for maior que o nível 50. Precisamos que o EA coloque uma ordem de venda após definir o bid atual, stop-loss e take-profit.

      if(prevDownValue < 50 && downValue>50)
        {
         double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
        }

Após a compilação deste código sem erros, podemos verificar que o EA pode colocar ordens como nos exemplos seguintes:

Exemplo de ordem de compra:

compra

Exemplo de ordem de venda:

venda


Teste do sistema de negociação Aroon

Nesta parte, testaremos cada estratégia para ver seus resultados. Mais uma vez, enfatizo que você pode precisar de otimizações adicionais para essas estratégias, a fim de obter os melhores resultados e determinar o que funciona melhor para você. 

Focaremos nas seguintes métricas-chave para comparar as estratégias:

  • Lucro líquido (Net Profit) - calculado subtraindo o prejuízo bruto do lucro bruto. Quanto maior o valor, melhor.
  • Rebaixamento relativo do saldo (Balance DD relative) - perda máxima na conta durante a operação. Quanto menor o valor, melhor.
  • Fator de lucro (Profit factor) - relação entre o lucro bruto e o prejuízo bruto. Quanto maior o valor, melhor.
  • Expectativa de ganho (Expected payoff) - lucro ou prejuízo médio por negociação. Quanto maior o valor, melhor.
  • Fator de recuperação (Recovery factor) - determina o quão bem a estratégia testada se recupera de perdas. Quanto maior o valor, melhor.
  • Índice de Sharpe (Sharpe Ratio) - determina o risco e a estabilidade do sistema de negociação testado, comparando o retorno com o retorno sem risco. Quanto maior o valor, melhor.

Também testaremos o mesmo período ao testar ambas as estratégias. O período é de um ano, de 1º de janeiro de 2023 a 31 de dezembro de 2023, testaremos dois timeframes: 15 minutos e uma hora.

Estratégia de cruzamento:

Agora, vamos ver os resultados da estratégia de cruzamento Aroon em dois timeframes - 15 minutos e 1 hora, para ver qual deles é melhor com base nas métricas mencionadas anteriormente.

Teste da estratégia no timeframe de 15 minutos:

Os resultados são apresentados nos gráficos abaixo:

resultados do teste 15m

resultados do teste3 - 15m

resultados do teste2 - 15m

Com base nos resultados anteriores, obtemos os seguintes números:

  • Lucro líquido: 14791
  • Rebaixamento relativo do saldo: 6,78%
  • Fator de lucro: 1,17
  • Expectativa: 24,53
  • Fator de recuperação: 1,91
  • Índice de Sharpe: 2,23

Teste da estratégia no timeframe de uma hora:

Os resultados são apresentados nos gráficos abaixo:

resultados do teste 1h

resultados do teste3 - 1h

resultados do teste2 - 1h

Com base nos resultados anteriores, obtemos os seguintes números:

  • Lucro líquido: 6242,20
  • Rebaixamento relativo do saldo: 1,80%
  • Fator de lucro: 1,39
  • Expectativa: 53,81
  • Fator de recuperação: 2,43
  • Índice de Sharpe: 3,23

Estratégia de níveis:

Aqui, testaremos a estratégia de níveis Aroon em dois timeframes - 15 minutos e 1 hora, para comparar as mesmas métricas para ambos os timeframes.

Teste da estratégia no timeframe de 15 minutos:

Os resultados são apresentados nos gráficos abaixo:

resultados do teste 15m

resultados do teste3 - 15m

resultados do teste2 - 15m

Com base nos resultados anteriores, obtemos os seguintes números:

  • Lucro líquido: 42417,30
  • Rebaixamento relativo do saldo: 12,91%
  • Fator de lucro: 1,21
  • Expectativa: 29,62
  • Fator de recuperação: 2,27
  • Índice de Sharpe: 1,88

Teste da estratégia no timeframe de uma hora:

Os resultados são apresentados nos gráficos abaixo:

resultados do teste 1h

resultados do teste3 - 1h

resultados do teste2 - 1h

Com base nos resultados anteriores, obtemos os seguintes números:

  • Lucro líquido: 16001,10
  • Rebaixamento relativo do saldo: 5,11%
  • Fator de lucro: 1,30
  • Expectativa: 41,89
  • Fator de recuperação: 2,68
  • Índice de Sharpe: 2,61

Na tabela abaixo, todos os resultados são reunidos em um só lugar para melhor comparação:

valores

Com base no exposto, podemos encontrar os melhores valores para a estratégia e o timeframe testados:

  • Lucro líquido: O melhor valor (42417,30 USD) foi obtido usando a estratégia de níveis no teste no timeframe de 15 minutos.
  • Rebaixamento relativo do saldo: O melhor valor (1,80%) foi obtido usando a estratégia de cruzamento no teste no timeframe de uma hora.
  • Fator de lucro: O melhor valor (1,39) foi obtido usando a estratégia de cruzamento no teste no intervalo de uma hora.
  • Expectativa: O melhor valor (53,81) foi obtido usando a estratégia de cruzamento no teste no intervalo de uma hora.
  • Fator de recuperação: O melhor valor (2,68) foi obtido usando a estratégia de níveis no teste no timeframe de uma hora.
  • Índice de Sharpe: O melhor valor (3,23) foi obtido com a estratégia de cruzamento no teste no intervalo de uma hora.

Usando os números anteriores, podemos escolher a estratégia adequada com base em nossos objetivos de negociação e quais valores ajudam a alcançá-los.


Considerações finais

Criar e testar um sistema de negociação é uma tarefa crucial para qualquer trader que leva a negociação a sério. Neste artigo, tentamos fornecer uma visão sobre o indicador Aroon, que pode ser usado em qualquer sistema de negociação, tanto isoladamente quanto em combinação com outras ferramentas. Ele pode ser útil para sua negociação e dar uma ideia de como construir um bom sistema de negociação.

Descrevemos detalhadamente o indicador Aroon, bem como sua aplicação e cálculo. Também abordamos duas estratégias simples que podem ser usadas:

  • Estratégia de cruzamento permite que coloquemos automaticamente uma posição de compra quando a linha Aroon Up está acima da Aroon Down, ou uma posição de venda quando a linha Aroon Down está acima da Aroon Up.
  • Estratégia de níveis permite que coloquemos automaticamente uma posição de compra se a linha Aroon Down estiver abaixo do nível 10 do indicador, ou uma posição de venda se a Aroon Down estiver acima do nível 50.

Implementamos essas estratégias no código, criando um EA para cada uma delas. Depois de criar nosso indicador personalizado Aroon no MQL5 e escrever um programa simples que pode gerar valores Aroon Up e Aroon Down no gráfico, executamos o indicador no gráfico, testamos e determinamos os números importantes com base nos resultados dos testes de cada estratégia em dois timeframes - 15 minutos e 1 hora. Podemos usá-los dependendo de nossos objetivos de negociação e dos resultados de cada estratégia.

Também devemos entender que para encontrar as estratégias mencionadas, pode ser necessário mais otimização e mais esforços para alcançar os melhores resultados. O principal objetivo deste artigo é compartilhar algumas ideias sobre diferentes sistemas de negociação, que podem nos levar a criar sistemas de negociação mais aprimorados.

Espero que o artigo tenha sido útil para você. Se você quiser saber mais sobre a construção de sistemas de negociação com base em diferentes estratégias e indicadores técnicos, pode ler meus artigos anteriores sobre os indicadores técnicos mais populares, acessando a seção "Publicações" do meu perfil. Espero que eles também sejam úteis para você.

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

Arquivos anexados |
Aroon.mq5 (3.04 KB)
AroonValuesEA.mq5 (0.91 KB)
AroonLevelsEA.mq5 (1.63 KB)
Algoritmos de otimização populacionais: algoritmo genético binário (Binary Genetic Algorithm, BGA). Parte I Algoritmos de otimização populacionais: algoritmo genético binário (Binary Genetic Algorithm, BGA). Parte I
Neste artigo, vamos realizar um estudo sobre vários métodos aplicados em algoritmos genéticos binários e outros algoritmos populacionais. Vamos examinar os componentes principais do algoritmo, como seleção, crossover e mutação, bem como seu impacto no processo de otimização. Além disso, vamos explorar as formas de representação de informações e seu impacto nos resultados de otimização.
Criando um Expert Advisor simples multimoeda usando MQL5 (Parte 6): Dois indicadores RSI cruzam suas linhas Criando um Expert Advisor simples multimoeda usando MQL5 (Parte 6): Dois indicadores RSI cruzam suas linhas
Por Expert Advisor multimoeda, nesta seção, entende-se um EA ou robô de trading que utiliza dois indicadores RSI com linhas cruzadas, isto é, um RSI rápido que cruza um RSI lento.
Redes neurais de maneira fácil (Parte 73): AutoBots para previsão de movimentos de preço Redes neurais de maneira fácil (Parte 73): AutoBots para previsão de movimentos de preço
Continuamos a análise dos algoritmos de aprendizado de modelos de previsão de trajetórias. E neste artigo, proponho que você conheça o método chamado “AutoBots”.
Desenvolvendo um EA multimoeda (Parte 1): várias estratégias de trading trabalhando juntas Desenvolvendo um EA multimoeda (Parte 1): várias estratégias de trading trabalhando juntas
Existem várias estratégias de trading. Do ponto de vista da diversificação de riscos e do aumento da estabilidade dos resultados de trading, pode ser útil usar várias estratégias em paralelo. Mas se cada estratégia for implementada como um EA separado, gerenciar o trabalho conjunto delas em uma conta de trading se torna muito mais complicado. Para resolver esse problema, é um boa idea implementar o trabalho de diferentes estratégias de trading em um único EA.