Método da área
Tabela de conteúdos
- Introdução
- 1. Método corrente de avaliação das leituras do indicador RSI
- 2. Método da área
- 3. Indicador RSIAreaIndicator_v1
- 3.1. Criamos um projeto para o indicador
- 3.2. Preenchemos o "cabeçalho" do indicador
- 3.3. Editamos a função OnInit() do indicador
- 3.4. Criamos a função auxiliar do indicador
- 3.5. Criamos o código básico de trabalho para o indicador
- 4. Conselheiro RSIAreaExpert version 1.00
- 4.1. Editamos o "cabeçalho" do conselheiro
- 4.2. Função auxiliar RSIAreaFunc
- 4.3. Código de verificação ao trabalhar com a função CopyBuffer
- 4.4. Mais sobre a edição da função auxiliar
- 4.5. Função OnTick() do conselheiro
- 5. Teste do conselheiro RSIAreaExpert version 1.00 em vários períodos e símbolos
- Conclusão
- Bibliografia
Introdução
Como instalar corretamente os indicadores e conselheiros a partir dos arquivos no final do artigo: é necessário descompactar os arquivos "Indicators.zip" e "Experts.zip" no <diretório de dados>\MQL5\
A descrição do método da área foi publicada pela primeira vez em 2004 [1]. Este método é fascinante devido à sua perspectiva incomum sobre os dados do indicador RSI, pois sugere avaliar a área que o oscilador desenha sobre/sob a linha 50 desde o seu último cruzamento. Considerando as mudanças drásticas dos mercados em 2004 e a existência da linguagem MQL5, chegou a hora de testar a estratégia na linguagem MQL5 e no mercado moderno.
1. Método corrente de avaliação das leituras do indicador RSI
O método usual de negociação de acordo com os sinais do indicador RSI consiste numa avaliação das leituras do indicador para: sobrecompra/sobrevenda, procura da divergência entre as leituras do indicador e o preço, reversão após a o indicador visitar as zonas de sobrecompra/sobrevenda, e failure swing. Assim, para análise técnica do oscilador RSI é aplicado pelo menos quatro sinais, e isso complica o sistema de tomada de decisão.
Além disso, sabemos que o indicador RSI não se pode encontrar na zona de sobrecompra (acima da linha 70)/sobrevenda (abaixo da linha 30) por muito tempo, pois ele sempre volta e cruza a linha média 50:
Fig. 1. O oscilador RSI sempre volta das zonas de sobrecompra/sobrevenda
A Figura 1 mostra que o tempo total que o oscilador passou nas zonas de sobrevenda/sobrecompra é muito insignificante em comparação com o resto do tempo. Também, o RSI cruza a linha média 50, após entrar nas zonas de sobrevenda/sobrecompra. Como oscilador RSI sempre retorna e cruza a linha 50 e a análise técnica das leituras oscilador RSI deve ser simplificada, formou-se a base para desenvolver o método da área.
2. Método da área
O método da área sugere avaliar as leituras do oscilador RSI com base num critério: a área formada pelo oscilador sobre/sob a linha 50. Esse valor será usado para descrever o nível de sobrevenda/sobrecompra:
Fig. 2. O método da área é uma avaliação da área sobre/sob a linha 50
Neste caso, o sinal para abrir uma posição é o tamanho da área sobre/sob a linha 50 desde o seu último cruzamento com o indicador RSI.
- Quando o RSI está sobre a linha 50 por muito tempo, e depois ele supera um determinado valor de área (por exemplo, 300), uma posição SELL será aberta:
Fig. 3. Sinal para abertura da posição SELL, assim que a área se tornou igual a 300
-
Da mesma forma, quando o RSI está abaixo da linha de 50 por um longo tempo, e depois ele supera um determinado valor da área, será aberta uma posição BUY.
O sinal de fechamento é gerado quando o oscilador RSI cruza a linha 50 com a subseqüente formação de um máximo/mínimo local e o seu recuo de 4% da escala.
- Por exemplo, ao estar sobre a linha 50 por um longo tempo, em algum momento temos uma posição SELL aberta. Em seguida, o valor do indicador começa a diminuir e atinge a linha 40, por exemplo, após o qual o valor do indicador começa a aumentar (ou seja, forma-se um mínimo local). Quando o valor do indicador atinge 44, isto será um sinal para fechar a posição:
Fig. 4. Sinal para fechar uma posição SELL após a formação do mínimo local e um recuo de 4%
- Uma lógica semelhante é aplicada quando o indicador está abaixo da linha 50 por um longo tempo. Só então podemos esperar a formação do máximo local.
O indicador RSIAreaIndicator ajudará com a visualização da área sobre/sob a linha 50.
3. Indicador RSIAreaIndicator_v1
O indicador RSIAreaIndicator baseia-se no oscilador RSI. A principal diferença é que o RSIAreaIndicator tem dois buffers. Um buffer tem o estilo de construção DRAW_HISTOGRAM, e o segundo, DRAW_LINE. Os valores dos buffers são obtidos pela fórmula
Aparência do indicador RSIAreaIndicator version 1.00:
Fig. 5. Indicador RSIAreaIndicator _v1
3.1. Criamos um projeto para o indicador
Sugiro colocar os indicadores criados por você numa pasta separada. No meu caso, essa pasta é chamada de "MyInd". Para começar a escrever o indicador, é preciso criar o seu cabeçalho no editor de código MetaEditor usando o assistente MQL5 Wizard. Os passos iniciais para a criação do projeto são descritos neste vídeo:
3.2. Preenchemos o "cabeçalho" do indicador
A próxima etapa envolve a adição de uma descrição para o indicador. Posteriormente, ele sempre aparecerá nas propriedades do indicador na aba "Comum". Todo o código adicionado ao artigo será destacado para uma melhor percepção visual:
#property version "1.00" #property description "The indicator displays area RSI over/under line 50" #property indicator_separate_window
Lembremos que o indicador RSIAreaIndicator tem dois indicadores de buffers. Além destes, precisamos de mais um adicional. Desta forma, haverá um total de três buffers usados no indicador. Vamos começar a editar o código na linha do "cabeçalho" do indicador:
#property indicator_separate_window #property indicator_buffers 3 #property indicator_plots 2 #property indicator_type1 DRAW_HISTOGRAM #property indicator_type2 DRAW_LINE #property indicator_color1 clrGray #property indicator_color2 clrGray //--- input parameters input int ExtRSIPeriod=13;
Agora, é preciso declarar as três matrizes que armazenarão os valores do indicador e do buffer adicional:
//--- input parameters input int ExtRSIPeriod=13; //---- buffers double ExtMapBuffer1[]; double ExtMapBuffer2[]; double ExtMapBuffer3[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function |
Além disso, como o nosso indicador RSIAreaIndicator é calculado com base no indicador RSI padrão e vamos precisar dos valores do indicador, é necessária uma variável para armazenar o identificador do indicador de Força Relativa (Relative Strength Index):
double ExtMapBuffer3[]; //--- variable for storing the handle of the iRSI indicator int handle; //+------------------------------------------------------------------+ //| Custom indicator initialization function |
E, finalmente, três variáveis de serviço devem ser declaradas na linha de "cabeçalho". Na variável name será armazenado o nome do símbolo no qual foi executado o indicador, na variável short_name, o nome corto do indicador, e na variável bars_calculated, a quantidade de barras calculadas no indicador RSI:
int handle; //--- variable for storing string name=Symbol(); //--- name of the indicator on a chart string short_name; //--- we will keep the number of values in the Relative Strength Index indicator int bars_calculated=0; //+------------------------------------------------------------------+ //| Custom indicator initialization function |
A linha de "cabeçalho" do indicador está preenchida, então agora podemos prosseguir com a edição da função de OnInit().
3.3. Editamos a função OnInit() do indicador
Uma vez que estamos escrevendo um indicador, os nossos buffers de indicador devem estar associados as matrizes dinâmicas do tipo double declaradas anteriormente:
int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ExtMapBuffer1,INDICATOR_DATA); SetIndexBuffer(1,ExtMapBuffer2,INDICATOR_DATA); SetIndexBuffer(2,ExtMapBuffer3,INDICATOR_CALCULATIONS); //--- return(INIT_SUCCEEDED);
Depois, imediatamente após a ligação dos buffers com as matrizes, definiremos a indexação dos elementos da matriz, como na série de tempo (há um bom exemplo que vale a pena conferir em ArraySetAsSeries). O elemento mais à direita da matriz terá índice "0":
SetIndexBuffer(1,ExtMapBuffer2,INDICATOR_DATA); SetIndexBuffer(2,ExtMapBuffer3,INDICATOR_CALCULATIONS); ArraySetAsSeries(ExtMapBuffer1,true); ArraySetAsSeries(ExtMapBuffer2,true); ArraySetAsSeries(ExtMapBuffer3,true); //--- return(INIT_SUCCEEDED);
Agora, vamos definir a correção de exibição — o indicador será exibido com 2 casas decimais:
ArraySetAsSeries(ExtMapBuffer3,true); //--- set accuracy IndicatorSetInteger(INDICATOR_DIGITS,2); //--- return(INIT_SUCCEEDED);
Na função OnInit() resta obter o identificador da função RSIndex, preencher a variável short_name e atribuir um nome curto para o nosso indicador:
ArraySetAsSeries(ExtMapBuffer2,true); ArraySetAsSeries(ExtMapBuffer3,true); //--- set accuracy IndicatorSetInteger(INDICATOR_DIGITS,2); handle=iRSI(name,0,ExtRSIPeriod,PRICE_CLOSE); //--- if the handle is not created if(handle==INVALID_HANDLE) { //--- tell about the failure and output the error code PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d", name, EnumToString(PERIOD_CURRENT), GetLastError()); //--- the indicator is stopped early return(INIT_FAILED); } //--- show the symbol/timeframe the RSI Area Indicator is calculated for short_name=StringFormat("RSIArea(%d)",ExtRSIPeriod); IndicatorSetString(INDICATOR_SHORTNAME,short_name); //--- normal initialization of the indicator return(INIT_SUCCEEDED);
Então, temos preenchido a linha de "cabeçalho" da função de OnInit(). Você pode ver o código editado no final do artigo — o indicador é salvo sob o nome "RSIAreaIndicatorStep2.mq5".
3.4. Criamos a função auxiliar do indicador
Para trabalhar com o indicador RSIAreaIndicator, é preciso, em cada entrada à função OnCalculate(), obter os dados do indicador RSI. É igualmente importante assegurar a facilidade de leitura do código e dividir a funcionalidade do programa. Portanto, o código adicional para receber valores RSI e a cópia desse valores num dos buffer RSIAreaIndicator, foram movidos para a função separada FillArrayFromBuffer(). Será colocada depois de OnCalculate(). Os valores são copiados usando a função CopyBuffer.
//--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Filling indicator buffers from the iRSI indicator | //+------------------------------------------------------------------+ bool FillArrayFromBuffer(double &rsi_buffer[], // indicator buffer of Relative Strength Index values int ind_handle, // handle of the iRSI indicator int amount // number of copied values ) { //--- reset error code ResetLastError(); //--- fill a part of the iRSIBuffer array with values from the indicator buffer that has 0 index if(CopyBuffer(ind_handle,0,0,amount,rsi_buffer)<0) { //--- if the copying fails, tell the error code PrintFormat("Failed to copy data from the iRSI indicator, error code %d",GetLastError()); //--- quit with zero result - it means that the indicator is considered as not calculated return(false); } //--- everything is fine return(true); } //+------------------------------------------------------------------+
3.5. Criamos o código básico de trabalho para o indicador
O código básico de operação (ou lógica) do indicador RSIAreaIndicator está localizado na função OnCalculate(). Aqui, é declarada a variável principal values_to_copy. Posteriormente, a variável values_to_copy irá armazenar o número de valores que devem ser copiados a partir do indicador RSI.
const int &spread[]) { //--- number of values copied from the iRSI indicator int values_to_copy; //--- determine the number of values calculated in the indicator int calculated=BarsCalculated(handle); if(calculated<=0) { PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError()); return(0); } //--- return value of prev_calculated for next call return(rates_total); }
Cálculo do valor values_to_copy:
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError()); return(0); } //--- if it is the first start of calculation of the indicator or if the number of values in the iRSI indicator changed //---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history) if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1) { //--- if the iRSIBuffer array is greater than the number of values in the iRSI indicator for symbol/period, then we don't copy everything //--- otherwise, we copy less than the size of indicator buffers if(calculated>rates_total) values_to_copy=rates_total; else values_to_copy=calculated; } else { //--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate() //--- for calculation not more than one bar is added values_to_copy=(rates_total-prev_calculated)+1; } //--- return value of prev_calculated for next call return(rates_total);
Por que o valor values_to_copy é calculado desta forma? No indicador MQL5, os elementos de matrizes (time[], open[], high[], low[], close[], tick_volume[], volume[] e spread[]), passados para a função OnCalculate(), têm indexação desde o início da matriz até o fim. Assim é como fica no gráfico:
Fig. 6. Indexação dos elementos da matriz, quando a matriz não é uma série de tempo
Isso é, na matriz que não é uma série de tempo, o elemento mais à direita terá o índice máximo. Isto deve ser tomado em consideração nos cálculos matemáticos.
Agora, quando o valor values_to_copy é calculado, é possível chamar a função auxiliar функцию FillArrayFromBuffer() e preencher com valores os buffers dos indicadores ExtMapBuffer1[] e ExtMapBuffer2[]:
//--- for calculation not more than one bar is added values_to_copy=(rates_total-prev_calculated)+1; } //--- fill the array with values of the iRSI indicator //--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operation if(!FillArrayFromBuffer(ExtMapBuffer3,handle,values_to_copy)) return(0); //--- for(int i=0;i<values_to_copy;i++) { ExtMapBuffer1[i]=ExtMapBuffer2[i]=ExtMapBuffer3[i]-50.0; } //--- memorize the number of values in the Relative Strength Index indicator bars_calculated=calculated; //--- return value of prev_calculated for next call return(rates_total);
O indicador RSIAreaIndicator version 1.00 está pronto. Ele pode ser baixado no final do arquivo sob o nome "RSIAreaIndicatorv1.mq5". Agora, podemos prosseguir com a escritura do conselheiro RSIAreaEA version 1.00 que irá negociar segundo o método das áreas.
4. Conselheiro RSIAreaExpert version 1.00
Da mesma forma como com indicadores, recomendo mudar o conselheiro criado para uma pasta separada. Por exemplo, a pasta para os meus conselheiros é chamada de "MyExp". Por analogia com o indicador, criamos o projeto do conselheiro RSIAreaExpert_v1. Esclarecimento importante: numa das etapas, é necessário desmarcar todas as caixas de seleção:
Fig. 7. Configurações ao criar o conselheiro
Você pode ver o projeto criado no final do artigo — o conselheiro armazenado sob o nome "RSIAreaExpert_v1_Step1.mq5".
4.1. Editamos o "cabeçalho" do conselheiro
Adicionamos a descrição do conselheiro. Será visto na aba "Comuns" do conselheiro:
#property version "1.00" #property description "EA trades on \"Method areas\"" //+------------------------------------------------------------------+ //| Expert initialization function |
Escrever imediatamente uma descrição pode parecer algo incômodo, mas, eventualmente, essa prática será uma grande ajuda para você.
O conselheiro vai utilizar a biblioteca padrão — classe CTrade para executar as operações de negociação. Para isso, é necessário conectar a classe CTrade e anunciar a variável my_trade:
#property description "EA trades on \"Method areas\"" #include <Trade\Trade.mqh> //--- global variables CTrade my_trade; //+------------------------------------------------------------------+ //| Expert initialization function |
Também adicionaremos três variáveis (para armazenar o identificador do indicador Relative Strength Index, a atual área calculada e uma variável auxiliar):
//--- global variables CTrade my_trade; int handle; // variable for storing the handle of the iRSI indicator double RSIArea; // the calculated area double RSIOpen; // the auxiliary variable //+------------------------------------------------------------------+ //| Expert initialization function |
E a última etapa é a edição da linha do "cabeçalho" do conselheiro, isto é, a adição dos parâmetros de entrada:
double RSIOpen; // the auxiliary variable //--- input parametres input int ExtRSIPeriod=13; // period of RSI input int AreaCondition=300; // area input ENUM_TIMEFRAMES period=PERIOD_M15; //+------------------------------------------------------------------+ //| Expert initialization function |
A variável period introduzida exclusivaente para comodidade ao usar o testador de estratégias, desta forma podemos definir várias gamas de períodos testados:
Fig. 8. A variável period permite testar o conselheiro numa ampla gama de períodos
O "cabeçalho" do conselheiro está preenchido, agora é a vez da função OnInit(). OnInit() terá apenas uma função, isto é, vai receber o identificador do símbolo atual (Symbol()) no período estabelecido (period):
int OnInit() { //--- handle=iRSI(Symbol(),period,ExtRSIPeriod,PRICE_CLOSE); //--- if the handle is not created if(handle==INVALID_HANDLE) { //--- tell about the failure and output the error code PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d", Symbol(), EnumToString(period), GetLastError()); //--- the indicator is stopped early return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); }
Todas estas alterações no processo de edição do conselheiro podem ser vistas no arquivo "RSIAreaExpert_v1_Step2.mq5".
4.2. Função auxiliar RSIAreaFunc
A função para determinar a área RSIAreaFunc() está composta por várias partes funcionais. Nós adicionaremos gradualmente a funcionalidade. Primeiro bloco (explicação após o código):
void OnTick() { //--- } //+------------------------------------------------------------------+ //| Area calculation | //+------------------------------------------------------------------+ double RSIAreaFunc(int &RSIAreaShift,int BeginShift) { int shift,limit; double rsivalue,result; //--- get current RSI limit=Bars(Symbol(),period)-ExtRSIPeriod; if(limit>100) limit=100; double arr_rsi[]; ArrayResize(arr_rsi,limit); ArraySetAsSeries(arr_rsi,true); if(CopyBuffer(handle,0,0,limit,arr_rsi)==-1) { Print("CopyBuffer from iRSI failed, no data"); return(0); } return(result); }
A variável limit é responsável pela quantidade de valore do indicador iRSI, nós vamos copiar para a matriz arr_rsi[] usando CopyBuffer. Restringimos a variável limit usando o valor "100", ou seja, sempre vamos copiar os últimos 100 valores do indicador iRSI. Todas estas alterações no processo de edição do conselheiro podem ser vistas no arquivo "RSIAreaExpert_v1_Step3.mq5".
4.3 Código de verificação ao trabalhar com a função CopyBuffer
Se você não consegue entender como trabalha a função CopyBuffer e quais são os valores contidos na matriz sob o índice "0", é possível escrever um código de verificação simples: na função OnTick() escrevemos a chamada da função auxiliar RSIAreaFunc().
void OnTick() { //--- static int RSIAreaShift=0; RSIAreaFunc(RSIAreaShift,0); } //+------------------------------------------------------------------+ //| Area calculation | //+------------------------------------------------------------------+ double RSIAreaFunc(int &RSIAreaShift,int BeginShift)
No final do primeiro bloco da função RSIAreaFunc() adicionaremos a saída do comentário — os valores dos elementos início e fim da matriz arr_rsi[]:
if(CopyBuffer(handle,0,0,limit,arr_rsi)==-1) { Print("CopyBuffer from iRSI failed, no data"); return(0); } //--- Comment("arr_rsi[",limit-1,"]=",DoubleToString(arr_rsi[limit-1],2), "; arr_rsi[0]=",DoubleToString(arr_rsi[0],2)); return(result); }
Este é um código de verificação, ele é adicionado apenas no arquivo RSIAreaExpert_v1_Step3_check.mq5, e ele não estará no conselheiro principal. Para verificação, executamos o seguinte:
- compilar (se ainda não o tenha feito) o arquivo do conselheiro RSIAreaExpert_v1_Step3_check.mq5;
- abrir um novo gráfico de qualquer instrumento e mudar para o timeframe M15 (pous nos parâmetros de entrada, a variável period=PERIOD_M15 é padrão);
- inserir no gráfico o indicador RSI (menu "Inserir" -> "Indicadores" -> "Osciladores" -> "Índice de Força Relativa" com as seguintes definições: "Período" 13 e "Aplicar a" Close);
- adicionar ao gráfico o conselheiro RSIAreaExpert_v1_Step3_check.mq5.
O gráfico mostrará instantaneamente que o valor do elemento com índice "0", na matriz arr_rsi, corresponde ao valor do indicador RSI na barra mais à direita:
Fig. 9. Testando a função CopyBuffer
4.4. Mais sobre a edição da função auxiliar
Próximo bloco da função RSIAreaFunc():
if(CopyBuffer(handle,0,0,limit,arr_rsi)==-1) { Print("CopyBuffer from iRSI failed, no data"); return(0); } result=arr_rsi[0]-50.0; // values from the bars that has 0 index for(shift=BeginShift+1;shift<limit;shift++) { rsivalue=arr_rsi[shift]-50; if((result>0 && rsivalue<-3) || (result<0 && rsivalue>3)) { RSIAreaShift=shift; break; } result+=rsivalue; } return(result); }
Primeiro, a variável result adota o valor do indicador RSI na barra mais à direita menos 50. Depois, ele é seguido pelo ciclo segundo a matriz arr_rsi, começando com o elemento com índice "1" até o elemento com índice limit-1. Neste ciclo, é verificada a seguinte condição: "houve ou não cruzamento da linha zero". Se houver cruzamento, em seguida, o código da barra (vista da direita para a esquerda) será armazenado na variável RSIAreaShift.
4.5. Função OnTick() do conselheiro
Nós terminamos de editar a função auxiliar RSIAreaFunc(). e continuamos com a função de negociação OnTick(): Vamos adicionar o seguinte código para OnTick():
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- static int RSIAreaShift=0; int shift; double RSICurrent,RSILocalMin,RSILocalMax,value; double arr_rsi[1],rsi; MqlTick last_tick; //--- if(CopyBuffer(handle,0,0,1,arr_rsi)==-1) { Print("CopyBuffer from iRSI failed, no data"); return; } rsi=arr_rsi[0]; //--- if(!SymbolInfoTick(Symbol(),last_tick)) Print("SymbolInfoTick() failed, error = ",GetLastError()); //--- }
Usando a função CopyBuffer, obtemos um valor do indicador RSI na barra mais à direita e, a seguir, ele será atribuído para a variável rsi -. No código, vamos referir esta variável varias vezes. Depois, obtemos os valores atuais desse símbolo e armazenamos esses valores na variável last_tick.
O seguinte bloco do código é processado, desde que haja uma posição aberta nesse instrumento:
if(!SymbolInfoTick(Symbol(),last_tick)) Print("SymbolInfoTick() failed, error = ",GetLastError()); //--- check the conditions for opening a position if(!PositionSelect(Symbol())) { RSIArea=RSIAreaFunc(RSIAreaShift,0); //--- check at the chance to take a long position if(RSIArea<-AreaCondition) { my_trade.Buy(1.0,NULL,last_tick.ask,0.0,0.0,NULL); RSIOpen=rsi; return; } //--- check at the chance to take a short position if(RSIArea>AreaCondition) { my_trade.Sell(1.0,NULL,last_tick.bid,0.0,0.0,NULL); RSIOpen=rsi; return; } RSIAreaShift=0; } //--- } //+------------------------------------------------------------------+ //| Area calculation |
No código, são verificadas as condições para abertura da posição: se a área calculada nesse momento (variável RSIArea) inferior/superior ao parâmetro de entrada (AreaCondition), então, respetivamente, será aberta uma posição Buy/Sell.
Depois, a variável RSICurrent é atribuído o valor da variável rsi (lembre-se que ele mantém o valor do indicador RSI no lado direito da barra) e é verificada a condição de saída a partir da função OnTick():
- se a posição for aberta acima da linha "50" (RSIOpen>50) e nós estivermos nesse momento acima da linha "50" (RSICurrent>50);
- se a posição for aberta abaixo da linha "50" (RSIOpen<50) e nós estarmos nesse momento abaixo da linha "50" (RSICurrent<50):
RSIAreaShift=0; } RSICurrent=rsi; if(RSIOpen>50 && RSICurrent>50) return; if(RSIOpen<50 && RSICurrent<50) return; RSILocalMin = RSICurrent; RSILocalMax = RSICurrent; //--- } //+------------------------------------------------------------------+ //| Area calculation |
O próximo bloco de código encontra mínimos/máximos locais e atribui esses valores para as variáveis RSILocalMin e RSILocalMax:
RSILocalMin = RSICurrent; RSILocalMax = RSICurrent; //--- search local minimum/maximum if(RSIAreaShift>1) { double arr_rsi_1[]; ArrayResize(arr_rsi_1,RSIAreaShift); ArraySetAsSeries(arr_rsi_1,true); if(CopyBuffer(handle,0,0,RSIAreaShift,arr_rsi_1)==-1) { Print("CopyBuffer from iRSI failed, no data"); return; } for(shift=1; shift<RSIAreaShift; shift++) { value=arr_rsi_1[shift]; if(value<RSILocalMin && RSIArea>0) RSILocalMin=value; if(value>RSILocalMax && RSIArea<0) RSILocalMax=value; } } //--- } //+------------------------------------------------------------------+ //| Area calculation |
Finalmente, o último bloco de código:
if(value>RSILocalMax && RSIArea<0) RSILocalMax=value; } } //--- check for rollback if(PositionSelect(Symbol())) { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { //--- check, can it is time already be closing? if(RSILocalMax>=RSICurrent+4 && RSILocalMax>50) my_trade.PositionClose(Symbol(),20); } if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) { //--- check, can it is time already be closing? if(RSILocalMin<=RSICurrent-4 && RSILocalMin<50) my_trade.PositionClose(Symbol(),20); } } //--- return; } //+------------------------------------------------------------------+ //| Area calculation |
Aqui (se você tiver uma posição aberta) é verificada a condição de fechamento da posição pela regra:
O oscilador RSI cruza a linha com 50 com a subseqüente formação de um máximo/mínimo local e o seu recuo de 4% da escala.
Por exemplo, ao estar sobre a linha 50 por um longo tempo, em algum momento temos uma posição SELL aberta. Em seguida, o valor do indicador começa a diminuir e atinge a linha 40, por exemplo, após o qual o valor do indicador começa a aumentar (ou seja, forma-se um mínimo local). O sinal para fechar a posição será o momento em que o valor do indicador atinja a linha 44.
Aqui finaliza a criação do conselheiro RSIAreaExpert_v1 . O arquivo "RSIAreaExpert_v1.mq5" pode ser baixado no final do artigo.
5. Teste do conselheiro RSIAreaExpert version 1.00 em vários períodos e símbolos
Inicialmente, o conselheiro RSIAreaExpert foi testado no período H1 [1] do gráfico, mas desde 2004 os mercados mudaram drasticamente, tornaram-se mais voláteis e, portanto, para avaliar o desempenho do método de áreas, decidiu-se realizar o teste numa grande variedade de períodos: a partir do M10 a H6. Também foi significativamente ampliado a gama de áreas para testes: 100-800. Período de teste, 2015.01.05 — 2016.01.05.
Assi, os resultados do teste do conselheiro RSIAreaExpert version 1 par o símbolo AUDCAD:
Fig. 10. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo AUDCAD. Intervalo das áreas 100-800. Intervalo dos períodos M10-H6
No período H2, vemos uma boa densidade de resultados. É possível até mesmo levar em conta o período H3. Agora olhamos para a figura e estimamos o número de transações por ano no símbolo AUDCAD ao testar o conselheiro RSIAreaExpert version 1:
Fig. 11. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo AUDCAD. Intervalo das áreas 100-800. Intervalo dos períodos M10-H6
Nos períodos H2 e H3, o número de transações por ano flutua à volta de 50. Isto é um pouco, e a margem de erro é alta. Podemos concluir que no símbolo AUDCAD a estratégia do método funciona mal.
Resultados de teste do conselheiro RSIAreaExpert version 1 para o símbolo AUDUSD:
Fig. 12. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo AUDUSD. Intervalo das áreas 100-800. Intervalo dos períodos M10-H6
Se considerarmos a rentabilidade da estratégia no símbolo AUDUSD, podemos considerar a negociação nos períodos H2 e H3. Nestos períodos o parâmetro AreaCondition flutua entre 250 e 400. Para justificar a negociação nos períodos H2 e H3, é necessário ver o número de transações por o ano nestes períodos:
Fig. 13. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo AUDUSD. Intervalo das áreas 100-800. Intervalo dos períodos M10-H6
Como você pode ver, é desastrosamente baixo. Por isso, no AUDUSD, não é recomendado negociar segundo o método da área.
Os resultados do teste do conselheiro RSIAreaExpert version 1 para o símbolo EURUSD:
Fig. 14. Resultados do teste do conselheiro RSIAreaExpert. Intervalo das áreas 100-800. Intervalo dos períodos M10-H6
A figura 4 revela no período M10 uma boa densidade de resultados de lucro para a área de 400 a 550, para o período de M12, de 300 a 400, e para o período de M15, de 300 a 400. Não são considerados os períodos superiores, porque o número dos seus negócios ao longo do ano é muito pequeno (см. fig. 5).
A figura 5 revela o gráfico das dependências da quantidade de negociações e o lucro para o símbolo EURUSD:
Fig. 15. Resultados do teste do conselheiro RSIAreaExpert. Intervalo das áreas 100-800. Intervalo dos períodos M10-H6
Aqui claramente é mostrado que o número de negociações é menor em períodos de altos (de H1 a H6), o que não justifica a aplicação do método das áreas sobre tais períodos. No entanto, o número de negociações nos períodos M10, M12 e M15 é suficiente para confirmar da rentabilidade do método das áreas sobre estes timeframes. Certamente o símbolo EURUSD é apropriado para negociação segundo o método das áreas.
Resultado de teste do conselheiro RSIAreaExpert version 1 para o símbolo GBPUSD:
Fig. 16. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo GBPUSD. Intervalo das áreas 100-800. Intervalo dos períodos M10-H6
No símbolo GBPUSD há uma boa densidade de lucros positivos para o período M20. O parâmetro AreaCondition varia de 300 a 500.
Fig. 17. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo GBPUSD. Intervalo das áreas 100-800. Intervalo dos períodos M10-H6
Para o símbolo GBPUSD e no período M20, a quantidade de transações por ano flutua entre 140 e 250. Certamente não é um registro fantástico, mas, é possível tomar nota dele. Em outras palavras, negociar no símbolo GBPUSD usando o método da área não é adequado para todos
Resultados do teste do conselheiro RSIAreaExpert version 1 para o símbolo USDCAD:
Fig. 18. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo USDCAD. Intervalo das áreas 100-800. Intervalo dos períodos M10-H6
No símbolo USDCAD, gostaria de considerar apenas o período M30, pois tem uma boa densidade de lucro positivo. Além disso, o parâmetro AreaCondition é alterado na faixa entre 280 e 550.
Fig. 19. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo USDCAD. Intervalo das áreas 100-800. Intervalo de períodos M10-H6
Neste par de moedas, no timeframe M30, o número de negociações por ano flutua entre 90 e 200. Isto não é muito, por isso não recomendo o método das áreas para o símbolo USDCAD.
Resultado de teste do conselheiro RSIAreaExpert version 1 para o símbolo USDJPY:
Fig. 20. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo USDJPY. Intervalo das áreas 100-800. Intervalo de períodos M10-H6
No símbolo USDJPY existem dois períodos: M10 e M30. O parâmetro AreaCondition para o período M10 situa-se na gama de 320-650, para o período M30, 550-600.
Fig. 21. Resultados do teste do conselheiro RSIAreaExpert version 1. Símbolo USDJPY. Intervalo das áreas 100-800. Intervalo de períodos M10-H6
Para o símbolo USDJPY, o número de transações por ano segundo o método das áreas para o período M10 na gama de 150-200, para o período M30, 50-150. Assim, vemos que aqui as recomendações de negociação são muito vagas.
Conclusão
Ainda é cedo para copiar uma negociação de acordo com o método da área. Realmente, o sistema tem começado a mostrar perdas em relação ao período H1, nas atuais condições de mercado, no entanto, anteriormente [1] era usado para manter o lucro principal. Negociar com EURUSD, nos períodos M10, M12 e M15, usando o método das áreas, provou ser o mais rentável e eficiente no mercado moderno. Precisamente, foram os testes que mostraram um número suficiente de negociações anuais com este par de moedas.
Bibliografia
- Morozov I. V., Fatkhullin R.R. FOREX: do simples ao complexo. Novos recursos para o terminal de cliente "MetaTrader". - "Teletrade LTD", 2004. - 448 p.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/2249
- 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