
Desenvolvimento e teste de sistemas de negociação Aroon
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:
- Definição do indicador Aroon
- Estratégias Aroon
- Sistemas de negociação Aroon
- Teste de sistemas de negociação Aroon
- Considerações finais
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.
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.
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:
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:
Como vemos no exemplo anterior, temos uma ordem de compra após o cruzamento das linhas up e down.
Exemplo de ordem de 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:
Exemplo de ordem de 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:
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:
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:
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:
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:
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





- 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