Stop-loss fixo com base na ação do preço e RSI (stop-loss "inteligente")

vwegba | 22 fevereiro, 2022

Introdução

Este estudo foi motivado pelas minhas tentativas de encontrar o graal na negociação. o stop-loss é a ferramenta mais importante na negociação em termos de gerenciamento de dinheiro. Por sua vez, o gerenciamento de dinheiro é uma maneira de ganhar dinheiro no mercado, mantendo a consistência no longo prazo. Como dito anteriormente, a gerenciamento do dinheiro está intimamente relacionada ao stop-loss e à relação risco/recompensa. Uma proporção de 1:1,5R(risco:recompensa) tende a ter uma taxa de retorno mais alta do que outras, mas uma proporção de 1:>1,9R(risco:recompensa) é mais lucrativa na maioria dos casos, enquanto a lucratividade é mantida por um longo período de tempo (graal). No entanto, este graal também tem um lado negativo. Em uma situação ideal, uma negociação com uma relação de 1:>1,9R(risco:recompensa) permanece lucrativa se de 10 negócios (1 pip cada) 6 deles eram ruins (6 pips) e 4 lucrativos (8 pips) . Permanecemos com um lucro de 2 pips. Na realidade, as coisas geralmente são diferentes. Uma das principais razões é o fenômeno da caça ao stop-loss, quando o preço atinge o stop-loss e depois se move na direção prevista. A caça ao stop-loss é um problema sério na negociação e no gerenciamento do dinheiro. Também tem um efeito psicológico nos traders (principalmente iniciantes). 

Caça aos stop-loss

Fig. 1.1. Caça aos stop-loss

A caça ao stop-loss envolve principalmente trailing-stops fixos ou móveis em um gráfico de velas ou em um de ação de preço. Se não houver stop-loss no gráfico de ação de preço, não haverá tal caça. No entanto, a ausência de stop-loss aumenta drasticamente a probabilidade de perda completa do depósito (a probabilidade é igual a um (1)).


Stop-loss com base no RSI

O oscilador RSI é uma réplica de um gráfico de linha de ação de preço plotado de 0 a 100

thRsi


Fig. 1.2. RSI e gráfico de linhas

Se o RSI e o gráfico de linhas forem muito semelhantes, usar o indicador RSI como um stop-loss "inteligente" pode reduzir o risco de busca de stop-loss.

Alvo:

Meu alvo é testar se o uso de um stop-loss baseado em RSI pode reduzir o efeito da busca de stop loss enquanto conseguimos lucratividade no longo prazo.

Método:

Comparação de duas estratégias: uso de stop loss em um gráfico de ação de preço e um stop-loss baseado no indicador RSI.




Estratégia e código

Stop-loss clássico no gráfico de ação de preço

O primeiro EA será baseado em um stop-loss fixo definido no gráfico de ação de preço. Abaixo estão os requisitos para a estratégia.

Parâmetros

Descrição

Indicador usado

MACD (12,26,9)

Indicador usado

Moving Average (200)

Indicador usado

Moving Average (50)

Indicador usado

ATR (5)

Período gráfico

M1

Compra

Se a Moving Average (50) estiver acima da Moving Average (200), e a linha MACD estiver acima da de sinal, com ambas abaixo de zero

Venda

Se a Moving Average (50) estiver abaixo da Moving Average (200), e a linha MACD estiver abaixo da de sinal, com ambas acima de zero

Dados de saída

Take-profit e stop-loss (1:2R).

O stop-loss de compra é mínimo 20 velas após a entrada menos o valor ATR (5)

O stop-loss de venda é máximo 20 velas após a entrada mais o valor ATR (5)

 


A representação gráfica é mostrada abaixo.

Compre (stop-loss clássico)


Fig. 2.1. Compra

Venda (stop-loss clássico)


Fig. 2.2. Venda

Código

A primeira parte do código é principalmente para declarar variáveis e inserir dados. Todas as variáveis do manipulador do indicador são declaradas aqui.

#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
#include<Trade\Trade.mqh>
CTrade trade;
int MATrend;
int MADirection;
int MACD;
int ATR;
input int afi;// ----------RiskAmount------------
input double risk = 0.02; //% Amount to risk
input int atrValue = 20; // ATR VAlue
input int ai;// ----------Moving Average inputs------------
input int movAvgTrend = 200;// Moving Average Trend
input int movAvgDirection = 50;//moving Average for trend Direction;
input int i;// -----------MACD inputs-----------------------
input int fast = 12;// Macd Fast
input int slow = 26; //Macd Slow
input int signal = 9; //Signal Line

Também são declaradas outras variáveis

double pipValue  = 0.0;// 

double Balance; // For the Current Balance

Variáveis foram atribuídas a cada manipulador na função init()

int OnInit()
  {
//---
      //Moving Averages Indicators''
      MATrend = iMA(_Symbol,_Period,movAvgTrend,0,MODE_SMA,PRICE_CLOSE); //Moving Average 200
      MADirection = iMA(_Symbol,_Period,movAvgDirection,0,MODE_EMA,PRICE_CLOSE); //Moving Average 50
      //MACD
      MACD = iMACD(_Symbol,_Period,fast,slow,signal,PRICE_CLOSE);//MACD 
      //ATR
      ATR = iATR(_Symbol,_Period,atrValue);
      //---
      point=_Point;
      double Digits=_Digits;
      
      if((_Digits==3) || (_Digits==5))
      {
         point*=10;
      }
      return(INIT_SUCCEEDED);
  }


O código da estratégia é mostrado abaixo.

void Strategy() {
   MqlRates priceAction[];
   ArraySetAsSeries(priceAction,true);
   int priceData = CopyRates(_Symbol,_Period,0,200,priceAction); 
   
   double maTrend[]; ArraySetAsSeries(maTrend,true);
   CopyBuffer(MATrend,0,0,200,maTrend); //200 MA
     
   double madirection[]; ArraySetAsSeries(madirection,true);
   CopyBuffer(MADirection,0,0,200,madirection);  //50 MA
   
   double macd[]; ArraySetAsSeries(macd,true);
   CopyBuffer(MACD,0,0,200,macd);  //MACD
   
   double macds[]; ArraySetAsSeries(macds,true);
   CopyBuffer(MACD,1,0,200,macds);  //MACD_Signal Line   
      
   double Bid  = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);  
   
   
   if (madirection[1]>maTrend[1]) {
      //Buy ; Uptrend
     
     
      
      bool macd_bZero = macds[1]<0&&macd[1]<0; //MacD Signal Line is less than Zero
      bool macd_cross = macd[1]>macds[1];// Macd Crosses the signal line
      
      if (macd_bZero && macd_cross) {
         buyTrade = true;
      }
      
      
   } else if (madirection[1]<maTrend[1]) {
      //Sell; DownTrend
      
     
      bool macd_bZero = macds[1]>0&&macd[1]>0;; //MacD Signal Line is less than Zero
      bool macd_cross = macd[1]<macds[1];// Macd Crosses the signal line
      
      if (macd_bZero && macd_cross) {
         sellTrade = true;
      }      
      
    }  
    
   if (buyTrade && sellTrade) {
      buyTrade = false;
      sellTrade = false;
   return;
   }
      
      
   if (buyTrade) {
      buyTrade = false;
      sellTrade = false;
      
      Buy(Ask);
   } else if (sellTrade) {
      buyTrade = false;
      sellTrade = false;
      
      Sell(Bid);   
   }
   
}

Entrada (compra e venda)

void Buy(double Ask) {
   double atr[]; ArraySetAsSeries(atr,true); //This array is use to store all ATR value to the last closed bar
   CopyBuffer(ATR,0,0,200,atr); // This method copy the buffer value of the ATR indicator into the array (200 buffered data)

   theLotsize =  NormalizeDouble((Balance*risk)/((MathAbs(Ask-((stoplossforBuy(20)-atr[1])))*100)*pipValue),2); // This Calculate the lotsize using the % to risk
   trade.Buy(theLotsize,_Symbol,Ask,(stoplossforBuy(20)-atr[1]),Ask+(2*MathAbs(Ask-((stoplossforBuy(20)-atr[1])))),NULL); //Buy Entry with zero stoploss && take profit is twice the distance between the entry and the lowest candle
    

}
void Sell(double Bid) {
   double atr[]; ArraySetAsSeries(atr,true); //This array is use to store all ATR value to the last closed bar
   CopyBuffer(ATR,0,0,200,atr); // This method copy the buffer value of the ATR indicator into the array (200 buffered data)
   theLotsize =  NormalizeDouble((Balance*risk)/((MathAbs(Bid-((stoplossforSell(20)+atr[1])))*100)*pipValue),2); // This Calculate the lotsize using the % to risk
   trade.Sell(theLotsize,_Symbol,Bid,(stoplossforSell(20)+atr[1]),Bid-(2*MathAbs(((stoplossforSell(20)+atr[1]))-Bid)),NULL); //Sell Entry with zero stoploss && take profit is twice the distance between the entry and the highest candle

}

Dos códigos acima, chamamos dois métodos - stoplossforSell(int num) e stoplossforBuy(int num). Esses dois métodos são projetados para determinar as velas máximas e mínimas com o número atribuído após o sinal para entrar na negociação ser acionado. Por exemplo, stoplossforSell(20) retorna a vela mais alta das 20 anteriores antes da entrada.

double stoplossforBuy(int numcandle) {
         int LowestCandle;
         
         //Create array for candle lows
         double low[];
         
         //Sort Candle from current downward
         ArraySetAsSeries(low,true);
         
         //Copy all lows for 100 candle
         CopyLow(_Symbol,_Period,0,numcandle,low);
         
         //Calculate the lowest candle
         LowestCandle = ArrayMinimum(low,0,numcandle);
         
         //Create array of price
         MqlRates PriceInfo[];
         
         ArraySetAsSeries(PriceInfo,true);
         
         //Copy price data to array
         
         int Data = CopyRates(Symbol(),Period(),0,Bars(Symbol(),Period()),PriceInfo);
      
         return PriceInfo[LowestCandle].low;
                  
      
         

}
double stoplossforSell(int numcandle) {
         int HighestCandle;
         double High[];
       
       //Sort array downward from current candle
         ArraySetAsSeries(High,true);
       
       //Fill array with data for 100 candle
         CopyHigh(_Symbol,_Period,0,numcandle,High);
         
         //calculate highest candle
         HighestCandle = ArrayMaximum(High,0,numcandle);
         
         //Create array for price
         MqlRates PriceInformation[];
         ArraySetAsSeries(PriceInformation,true);
         
         
         //Copy price data to array
         int Data = CopyRates(Symbol(),Period(),0,Bars(Symbol(),Period()),PriceInformation);
         
         return PriceInformation[HighestCandle].high;
           
 
 }

O EA verifica se existe atualmente um negócio aberto. Caso contrário, o método de estratégia é chamado.

void OnTick()
  {
//---
   pipValue  = ((((SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE))*point)/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE))));

   Balance = AccountInfoDouble(ACCOUNT_BALANCE);
   
   if (PositionsTotal()==0) {
      Strategy();
   }
  }

Stop-loss com base no indicador RSI


O segundo EA usará um stop-loss fixo no indicador RSI. Abaixo estão os requisitos para a estratégia.

Parâmetros

Descrição

Indicador usado

MACD (12,26,9)

Indicador usado

Moving Average (200)

Indicador usado

Moving Average (50)

Indicador usado

ATR (5)

Período gráfico

M1

Compra

Se a Moving Average (50) estiver acima da Moving Average (200), e a linha MACD estiver acima da de sinal, com ambas abaixo de zero

Venda

Se a Moving Average (50) estiver abaixo da Moving Average (200), e a linha MACD estiver abaixo da de sinal, com ambas acima de zero

Dados de saída

Take-profit

O stop-loss de compra é mínimo 10 valores do RSI após a entrada

O stop-loss de venda é máximo 10 valores do RSI após a entrada

 

Se o RSI cruzar o RSI máximo ou mínimo, o negócio será fechado.

 


Para facilitar a percepção disso, o stop-loss é exibido como uma linha.

Compra (stop-loss com base no RSI)


Fig. 2.3. Compra com stop-loss baseado no RSI

O negócio é fechado quando o valor atual do RSI cai abaixo da linha de stop loss na janela do RSI.

Venda (stop-loss com base no RSI)


Fig. 2.4. Venda com stop-loss baseado no RSI

O negócio é fechado quando o valor atual do RSI ultrapassa a linha de stop loss na janela RSI.

Código

A primeira parte do código é principalmente para declarar variáveis e inserir dados. Algumas adições que distinguem este Expert Advisor do anterior estão listadas abaixo.

int RSI;
input int rsi = 5; // RSI VAlue
double lowestrsiValue = 100;
double highestrsiValue = 0.0;

O método onint() também foi complementado

int OnInit()
  {
              //RSI
      RSI = iRSI(_Symbol,_Period,rsi,PRICE_CLOSE);
}


O código de estratégia não mudou. No entanto, a compra e a venda não possuem stop-loss, pois o nível do RSI desempenha tal função. Abaixo está o código de entrada no mercado

void Buy(double Ask) {
   double atr[]; ArraySetAsSeries(atr,true); //This array is use to store all ATR value to the last closed bar
   CopyBuffer(ATR,0,0,200,atr); // This method copy the buffer value of the ATR indicator into the array (200 buffered data)

   theLotsize =  NormalizeDouble((Balance*risk)/((MathAbs(Ask-((stoplossforBuy(20)-atr[1])))*100)*pipValue),2); // This Calculate the lotsize using the % to risk
   
   ObjectCreate(0,"sl",OBJ_HLINE,3,0,lowestRSI(10)); // Since our stoploss is zero we assign a smart stoploss on the rsi by drawing a line on the rsi window
   trade.Buy(theLotsize,_Symbol,Ask,0,Ask+(2*MathAbs(Ask-((stoplossforBuy(20)-atr[1])))),NULL);//Buy Entry with zero stoploss && take profit is twice the distance between the entry and the lowest candle
    Print("SL",lowestRSI(10));
}
void Sell(double Bid) {
   double atr[]; ArraySetAsSeries(atr,true); //This array is use to store all ATR value to the last closed bar
   CopyBuffer(ATR,0,0,200,atr); // This method copy the buffer value of the ATR indicator into the array (200 buffered data)
   
   theLotsize =  NormalizeDouble((Balance*risk)/((MathAbs(Bid-((stoplossforSell(20)+atr[1])))*100)*pipValue),2);  // This Calculate the lotsize using the % to risk
   
   ObjectCreate(0,"sl",OBJ_HLINE,3,0,highestRSI(10)); // Since our stoploss is zero we assign a smart stoploss on the rsi by drawing a line on the rsi window
   trade.Sell(theLotsize,_Symbol,Bid,0,Bid-(2*MathAbs(((stoplossforSell(20)+atr[1]))-Bid)),NULL);//Sell Entry with zero stoploss && take profit is twice the distance between the entry and the highest candle
   Print("SL",highestRSI(10));
}


A última parte do código contém métodos que obtêm os valores máximo e mínimo do RSI. A chamada vem do método de entrada mostrado acima e usa os dados para desenhar uma linha no ponto máximo ou mínimo do RSI.

Nota: a linha desenhada é excluída no método de estratégia se não houver posição aberta.

 double lowestRSI(int count) {     
      double thersi[]; ArraySetAsSeries(thersi,true);
      CopyBuffer(RSI,0,0,200,thersi);
      
      for (int i = 0; i<count;i++) {
      
         if (thersi[i]<lowestrsiValue) {
            lowestrsiValue = thersi[i];
         }
      }
   return lowestrsiValue;
}
//This method get the Highest RSI afer ENtry to set the smart Stoploss
double highestRSI(int count) {

      
      double thersi[]; ArraySetAsSeries(thersi,true);
      CopyBuffer(RSI,0,0,200,thersi);
      
      for (int i = 0; i<count;i++) {
      
         if (thersi[i]>highestrsiValue) {
            highestrsiValue = thersi[i];
         }
      }
   return highestrsiValue;
}

####

Os Expert Advisors estão prontos e compilados. É hora de testá-los.


Teste e resultado

Teste da busca de stop-loss

Esta seção apresentará os testes e os resultados obtidos da simulação. A primeira coisa a fazer é determinar se o Expert Advisor com stop-loss baseado no RSI (RSI STOP-LOSS) é capaz de reduzir o efeito de busca de stop-loss durante a negociação e comparar seus resultados com o desempenho do Expert Advisor com stop-loss clássico (CLASSIC STOP-LOSS).

Os testes são realizados no período M1.

RSI STOP-LOSS

Expert Advisor: MACD_Smart_Stoploss
Símbolo: Volatility 10 Index
Período: M1 (2021.07.01 - 2021.07.15)
Parâmetros de entrada: afi=0
risk=0.05
atrValue=20
rsi=14
ai=0
movAvgTrend=200
movAvgDirection=50
i=0
fast=12
slow=26
signal=9
Corretora: Deriv Limited
Moeda: USD
Depósito inicial: 500.00
Alavancagem: 1:500



CLASSIC STOP-LOSS

Expert Advisor: MACD_Cross_Stoploss
Símbolo: Volatility 10 Index
Período: M1 (2021.07.01 - 2021.07.15)
Parâmetros de entrada: afi=0
risk=0.05
atrValue=5
ai=0
movAvgTrend=200
movAvgDirection=50
i=0
fast=12
slow=26
signal=9

risk reward=1:2
Corretora: Deriv Limited
Moeda: USD
Depósito inicial: 500.00
Alavancagem: 1:50


Resultados

Abaixo é mostrada uma representação gráfica dos negócios feitos por ambos os Expert Advisors. No total, três segmentos de negociação foram considerados para cada Expert Advisor.

RSI stoploss 1


Fig. 3.1. Segmento 1 (RSI STOP-LOSS)

Stop-loss com base na ação do preço


Fig. 3.1a. Segmento 1 (CLASSIC STOP-LOSS)

Rsi stoploss 2

Fig. 3.2. Segmento 2 (RSI STOP-LOSS)

Stop-loss com base na ação do preço

Fig. 3.2a. Segmento 2 (CLASSIC STOP-LOSS)

Rsi Stoploss 3
Fig. 3.3. Segmento 3 (RSI STOP-LOSS)

Stop-loss com base na ação do preço

Fig. 3.3a. Segmento 3 (CLASSIC STOP-LOSS)


A comparação mostrou que o Expert Advisor RSI STOP-LOSS fez um trabalho melhor ao reduzir o efeito da busca de stop-loss do que o Expert Advisor com stop-loss clássico no gráfico de ação de preço.


Teste de rentabilidade

Agora é hora de abordar a questão mais importante - definir a lucratividade. Como o Expert Advisor RSI STOP-LOSS fez um trabalho melhor ao caçar stop-loss, ele deve ser lucrativo e ter uma taxa de ganho mais alta porque aciona menos stop-loss em comparação com um stop-loss clássico. Para confirmar isso, precisamos realizar um teste.

Para ambos os testes, os dados especificados acima serão usados. Ambos os Expert Advisors serão testados com base em um histórico de mais de 100 negócios no período M1. Os resultados são mostrados abaixo.


RSI STOP-LOSS

Resultados
Tamanho do histórico: 100%
Barras: 20160 Ticks: 603385 Símbolos: 1
Lucro líquido: 327.71 Rebaixamento absoluto do saldo: 288.96 Rebaixamento absoluto de dinheiro: 367.85
Lucro total: 3 525.74 Rebaixamento máximo do saldo: 483.90 (69.63%) Rebaixamento máximo do dinheiro: 523.24 (71.95%)
Perda total: -3 198.03 Rebaixamento relativo do saldo: 69.63% (483.90) Rebaixamento relativo do capital líquido: 73.65% (369.45)
Lucratividade: 1.10 Retorno esperado: 1.76 Nível de margem: 317.21%
Fator de recuperação: 0.63 Índice de Sharpe: 0.08 Cálculo Z: 1.68 (90.70%)
AHPR: 1.0070 (0.70%) LR Correlation: 0.51 Resultado do OnTester: 0
GHPR: 1.0027 (0.27%) LR Standard Error: 134.83
Negócios no total: 186 Negócios curtos (% de ganhos): 94 (42.55%) Negócios longos (% de ganhos): 92 (38.04%)
Transações no total: 372 Transações lucrativas (% de todas): 75 (40.32%) Transações perdedoras (% de todas): 111 (59.68%)
Maior negócio lucrativo: 85.26 Maior negócio perdedor: -264.99
Negócio lucrativo médio: 47.01 Negócio perdedor médio: -28.81
Número máximo de ganhos contínuos (lucro): 5 (350.60) Número máximo de perdas contínuas (perdas): 6 (-255.81)
Lucro contínuo máximo (número de ganhos): 350.60 (5) Perda contínua máxima (número de perdas): -413.34 (5)
Ganho contínuo médio: 2 Perda contínua média: 2

rsistlEcurve

Fig. 3.4. Curva de capital líquido para RSI Stop loss

CLASSIC STOP-LOSS


Resultados
Tamanho do histórico: 100%
Barras: 20160 Ticks: 603385 Símbolos: 1
Lucro líquido: 3 672.06 Rebaixamento absoluto do saldo: 215.45 Rebaixamento absoluto de dinheiro: 217.30
Lucro total: 10 635.21 Rebaixamento máximo do saldo: 829.54 (19.27%) Rebaixamento máximo do dinheiro: 1 159.20 (25.59%)
Perda total: -6 963.15 Rebaixamento relativo do saldo: 48.76% (270.82) Rebaixamento relativo do capital líquido: 51.81% (303.90)
Lucratividade: 1.53 Retorno esperado: 15.97 Nível de margem: 274.21%
Fator de recuperação: 3.17 Índice de Sharpe: 0.16 Cálculo Z: -0.14 (11.13%)
AHPR: 1.0120 (1.20%) LR Correlation: 0.80 Resultado do OnTester: 0
GHPR: 1.0093 (0.93%) LR Standard Error: 545.00
Negócios no total: 230 Negócios curtos (% de ganhos): 107 (44.86%) Negócios longos (% de ganhos): 123 (38.21%)
Transações no total: 460 Transações lucrativas (% de todas): 95 (41.30%) Transações perdedoras (% de todas): 135 (58.70%)
Maior negócio lucrativo: 392.11 Maior negócio perdedor: -219.95
Negócio lucrativo médio: 111.95 Negócio perdedor médio: -51.58
Número máximo de ganhos contínuos (lucro): 6 (1 134.53) Número máximo de perdas contínuas (perdas): 9 (-211.43)
Lucro contínuo máximo (número de ganhos): 1 134.53 (6) Perda contínua máxima (número de perdas): -809.21 (4)
Ganho contínuo médio: 2 Perda contínua média: 2


classicalcure

Fig. 3.5. Curva de capital líquido para Classic Stop loss


Resultados

Embora ambos os EAs tenham sido lucrativos no final do período de negociação, o primeiro EA (RSI Stop-Loss) teve menos perdas, algumas das quais bastante grandes.

Perdas do RSI stoploss na curva de capital líquido

Fig. 3.6. Perdas na curva de capital líquido

Essas perdas podem afetar a lucratividade geral do EA, bem como o gerenciamento adequado do dinheiro. Por outro lado, um Expert Advisor baseado em um stop loss clássico sofreu mais perdas, mas ao mesmo tempo ganhou mais dinheiro no final do período de negociação.


Conclusão

O gerenciamento do dinheiro é verdadeiramente o graal da negociação. O experimento mostrou que uma gestão totalmente implementada trouxe mais lucro com maiores perdas devido a negócios mais consistentes. No entanto, a dependência do stop-loss em relação ao RSI não dá a mesma consistência para o EA RSI STOP-LOSS porque a quantidade de risco varia.

Recomendações

Uma maneira de reduzir as perdas ao usar o EA RSI STOP-LOSS pode ser o hedge. Ele permite que você torne a quantidade de risco mais constante e aumente os lucros a longo prazo.


Obrigado pela atenção!