Pourquoi mon EA donne-t-il toujours un profit négatif lors du back-testing ?

 

J'ai imité et écrit un même EA avec l'exemple ici https://www.mql5.com/en/articles/1510 sauf les conditions pour l'achat et la vente.

Condition pour ouvrir une position d'achat : RSI inférieur à 5 ET prix de la demande supérieur à la moyenne mobile de 200 jours, sortie lorsque le prix de la demande est supérieur à la moyenne mobile de 5 jours.

Condition pour ouvrir une position de vente : RSI est supérieur à 95 ET le prix de l'offre est inférieur à la moyenne mobile de 200 jours, sortir lorsque le prix de l'offre est inférieur à la moyenne mobile de 5 jours.g

Lorsque je fais des back tests, j'obtiens toujours un profit négatif, ce que je ne sais pas pourquoi. La meilleure partie est que parfois il me donne l'erreur 134 qui signifie que je n'ai pas assez d'argent.

C'est un paramètre requis pour l'indicateur iRSI() mais je ne savais pas quoi écrire alors je lui ai simplement assigné 0.

Voici le code

//+------------------------------------------------------------------+
//|                                              My RSI strategy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#include <stderror.mqh> 
#include <stdlib.mqh>  
//All Variables here

extern double UpperBound    =  90;      //set upper bound value for RSI
extern double LowerBound    =  5;      //set lower bound value for RSI
extern double VarPeriod     =  2;      //number of periods
extern double BuyVolume     = 0.1;       //set buying volume(lots)
extern double SellVolume    = 0.1;       //set selling volume(lots)
extern double StopLoss      = 25;       //Set the stop loss level
extern double TakeProfit    = 25;       //Set the take profit level
extern double TrailingStop = 30;


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   Alert ("The minimum stoploss and take profit is " + MarketInfo(Symbol(),MODE_STOPLEVEL));
   double CurrentRSI;                  //Finds out the RSI for now
   double MA200;                       //200 day Moving Average           
   double MA5;                         //5 day Moving Average
   double CurrentAsk;                  //Finds out the Ask price now
   double CurrentBid;                  //Finds out the Bid price now
  
   
   CurrentAsk = MarketInfo(Symbol(), MODE_ASK);
   CurrentBid = MarketInfo(Symbol(), MODE_BID);
   MA200 = iMA(NULL, 0, 200, 8,MODE_SMA,PRICE_CLOSE, 0);
   MA5 = iMA(NULL, 0, 5, 8,MODE_SMA,PRICE_CLOSE, 0);
   CurrentRSI = iRSI (NULL, 0, VarPeriod,PRICE_CLOSE ,0);
   
   Alert("Bid is " + CurrentBid);
   Alert("Ask is " + CurrentAsk);
   Alert("200 Day Moving Average is " + MA200); 
   Alert("5 Day Moving Average is " + MA5); 
   Alert("RSI Index is " + CurrentRSI);
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   
   double CurrentRSI;                  //Finds out the RSI for now
   double MA200;                       //200 day Moving Average           
   double MA5;                         //5 day Moving Average
   double CurrentAsk;                  //Finds out the Ask price now
   double CurrentBid;                  //Finds out the Bid price now
   int Ticket;
   int cnt;
   int Ticket2;
   int Total;
   
   CurrentAsk = MarketInfo(Symbol(), MODE_ASK);
   CurrentBid = MarketInfo(Symbol(), MODE_BID);
   MA200 = iMA(NULL, 0, 200, 8,MODE_SMA,PRICE_CLOSE, 0);
   MA5 = iMA(NULL, 0, 5, 8,MODE_SMA,PRICE_CLOSE, 0);
   CurrentRSI = iRSI (NULL, 0, VarPeriod,PRICE_CLOSE ,0);
   
   
    if(Bars<100)
     {
      Print("bars less than 100");
      return(0);  
     }
   
   if(AccountFreeMargin()<(1000*BuyVolume))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
   
    if (CurrentRSI < LowerBound && MarketInfo(Symbol(), MODE_ASK) > MA200 ) {    //Condition to execute buy entry
  
        Ticket = OrderSend(Symbol(), OP_BUY, BuyVolume, Ask, 3, Bid - ( StopLoss * Point ), Ask + ( TakeProfit * Point ), "Buy.", 111,0,Yellow)   ;       //execute buy order
   
    if(Ticket>0)
           {
            if(OrderSelect(Ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("BUY order opened : ",OrderOpenPrice());
           }
         if (Ticket < 0) {
         Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
   }
   return(0);
  }
  
 
  if (CurrentRSI > UpperBound && MarketInfo(Symbol(), MODE_BID) > MA200) {     //Condition to execute sell entry
  
       Ticket2 = OrderSend(Symbol(), OP_SELL, SellVolume, Bid, 3, Ask + ( StopLoss * Point ), Bid - ( TakeProfit * Point ), "Sell.",000, 0, Yellow)  ;     //execute sell order
       if(Ticket2>0)
           {
            if(OrderSelect(Ticket2,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("SELL order opened : ",OrderOpenPrice());
           }
         if (Ticket2<0) {
          Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
        }
       return(0);
   
   } 
   
   Total=OrdersTotal();
    for(cnt=0;cnt<Total;cnt++)
  {
   OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())  // check for symbol and check for opened position 
     {
if(OrderType()==OP_BUY)   // long position is opened
{
   
   if (CurrentAsk > MA5){      //condition to close long position
    OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close long position
   return(0); // exit
   
   if(TrailingStop>0)  
              {                 
               if(Bid-OrderOpenPrice()>Point*TrailingStop)
                 {
                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
                     return(0);
                    }
                 }
              }
   
   }
   }
   
   if(OrderType()==OP_SELL)   // long position is opened
{
   if(CurrentBid < MA5){       //condition to close short position
   OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close short position
   return(0); // exit
   }
   
  if(TrailingStop>0)  
              {                 
               if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
                 {
                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
                     return(0);
                    }
                 }
              }
   }
   }
   }
   
    
   
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

Paramètre RSI réglé sur 0, aucun résultat comme . . . Rien

RSI 0

Au moins 2

rsi 2

 

Tous les EA et toutes les stratégies ne sont pas rentables.

En utilisant le Strategytester, faites-le aussi avec le mode visuel activé et placez sur le graphique les indicateurs que vous utilisez avec les mêmes paramètres que ceux que vous avez définis dans l'EA.

   MA200 = iMA(NULL, 0, 200, 8,MODE_SMA,PRICE_CLOSE, 0);
   MA5 = iMA(NULL, 0, 5, 8,MODE_SMA,PRICE_CLOSE, 0);
   CurrentRSI = iRSI (NULL, 0, VarPeriod,PRICE_CLOSE ,0);

A chaque tick vous calculez les valeurs ci-dessus et elles peuvent changer à chaque tick car vous avez choisi "....,PRICE_CLOSE, 0) ;".

Les valeurs que vous voyez sur le graphique quand le test est fait ne sont pas les valeurs que vous aviez quand un trade s'ouvre...

   if(AccountFreeMargin()<(1000*BuyVolume))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
   
    if (CurrentRSI < LowerBound && MarketInfo(Symbol(), MODE_ASK) > MA200 ) {    //Condition to execute buy entry
  
        Ticket = OrderSend(Symbol(), OP_BUY, BuyVolume, Ask, 3, Bid - ( StopLoss * Point ), Ask + ( TakeProfit * Point ), "Buy.", 111,0,Yellow)   ;       //execute buy order
   
    if(Ticket>0)
           {
            if(OrderSelect(Ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("BUY order opened : ",OrderOpenPrice());
           }
         if (Ticket < 0) {
         Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
   }
   return(0);
  }
  

Lorsque les conditions sont réunies pour ouvrir un achat, et que le testeur ouvre un achat, il n'y a pas de vérification si vous en avez déjà ouvert un avec la même condition.

Après l'ouverture d'un achat, le tick suivant vous pouvez à nouveau avoir les conditions pour ouvrir une transaction.

Cette ouverture de trades peut fonctionner dans StrategyTester mais en temps réel sur un compte démo ou réel,

Vous pouvez obtenir des erreurs que vous ne voyez pas dans le testeur. Par exemple, le choix de "3" Slippage est trop faible pour le trading sur un compte à "5 chiffres".

L'envoi de l'OrderSend avec une valeur pour OrderStopLoss() et OrdertakeProfit() > 0 échouera pour les comptes ECN

   Total=OrdersTotal();
    for(cnt=0;cnt<Total;cnt++)
  {
   OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())  // check for symbol and check for opened position 
     {
Dans l'OrderSend et dans cette boucle de vérification des transactions, il me manque l'utilisation de votre OrderMagicNumber().

et je vois que la boucle compte vers le haut au lieu de compter vers le bas, alors que vous voulez aussi qu'elle ferme les positions si nécessaire.

L'OrderModify peut se produire à chaque point, ce qui peut conduire à des erreurs de la part du courtier, comme un tradecontext trop occupé.

 
FXEWEN:

Paramètre RSI réglé sur 0, aucun résultat comme . . . Rien

Au moins 2

J'ai réglé la période iRSI à 2....

 
cyxstudio:


C'est un paramètre requis pour l'indicateur iRSI() mais je ne savais pas quoi écrire alors je lui ai simplement attribué 0.


Je ne sais pas d'où vous tenez cette information mais c'est incorrect....

iRSI() double iRSI(string symbol,int timeframe,int period,int applied_price,int shift)

peut-être vouliez-vous dire iMA()? shift est le numéro de la barre du temps pour lequel vous voulez la MA, ma_shift vous permet de déplacer la valeur de la MA par rapport au numéro de la barre, donc si vous lui donnez un shift de 5 et un ma_shift de -2, il vous donnera la MA de la barre 7, vous devriez expérimenter un peu avec ceci pour vérifier que je suis correct, en principe je le suis.


 
deVries:


En utilisant le Strategytester, faites-le aussi avec le mode visuel activé et placez sur le graphique les indicateurs que vous utilisez avec les mêmes paramètres que vous avez définis dans l'EA.

A chaque tick vous calculez les valeurs ci-dessus et elles peuvent changer à chaque tick parce que vous avez choisi "....,PRICE_CLOSE, 0) ;".


que dois-je choisir pour la valeur de décalage" ....,PRICE_CLOSE, 0) ;" alors ?

 
cyxstudio:

Que dois-je choisir pour la valeur de décalage" ....,PRICE_CLOSE,0) ;" alors ?

Utilisez la barre 0 si vous voulez, mais elle sera "repeinte" même si vous utilisez PRICE_CLOSE, Close[0](prix de clôture de la barre 0) == Bid. Lorsque la barre 0 se ferme finalement, ce n'est plus la barre 0 mais la barre 1.
 
deVries:

Tous les EA et toutes les stratégies ne sont pas rentables.

En utilisant le Strategytester, faites-le aussi avec le mode visuel activé et placez sur le graphique les indicateurs que vous utilisez avec les mêmes paramètres que vous avez définis dans l'EA.

A chaque tick vous calculez les valeurs ci-dessus et elles peuvent changer à chaque tick car vous avez choisi "....,PRICE_CLOSE, 0) ;".

Les valeurs que vous voyez sur le graphique quand le test est fait ne sont pas les valeurs que vous aviez quand une transaction s'ouvre...

Lorsque les conditions sont réunies pour ouvrir un achat, et que le testeur ouvre un achat, il n'y a pas de vérification si vous en avez déjà ouvert un avec la même condition.

Après l'ouverture d'un achat, le tick suivant vous pouvez à nouveau avoir les conditions pour ouvrir une transaction.

Cette ouverture de transaction peut fonctionner dans StrategyTester mais en temps réel sur un compte démo ou réel,

Vous pouvez obtenir des erreurs que vous ne voyez pas dans le testeur. Par exemple, le choix de "3" Slippage est trop faible pour le trading sur un compte à "5 chiffres".

L'envoi de l'OrderSend avec une valeur pour OrderStopLoss() et OrdertakeProfit() > 0 échouera pour les comptes ECN

Dans l'OrderSend et dans cette boucle de vérification des transactions, il me manque l'utilisation de votre OrderMagicNumber().

et je vois que la boucle compte vers le haut au lieu de compter vers le bas alors que vous voulez aussi fermer des positions si nécessaire.

L'OrderModify peut se produire avec chaque point, ce qui peut entraîner des erreurs de la part du courtier, comme un tradecontext trop occupé.

J'ai tout refait, j'ai corrigé la boucle, le slippage, j'ai fixé les valeurs de la moyenne mobile et du RSI, je me suis assuré que toutes les positions ouvertes sont fermées avant de commencer une nouvelle position. Mais quand je le backtest, rien ne se passe, aucun achat/vente n'a été exécuté... quel est le problème ?

//+------------------------------------------------------------------+
//|                                                My Strategy 4.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

extern double StopLoss = 40;
extern double TakeProfit = 40;
extern double Lots = 0.1;
extern double Slippage = 10;
extern double RSINow;
extern double MA200;
extern double MA5;
extern bool A1 = false;
extern bool A2 = false;
extern int Ticket;
extern int Ticket2;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+ 
int init()
  {
//----
   Alert("Minimum Stop Level is " + MarketInfo(Symbol(), MODE_STOPLEVEL)); //find out minimum stop loss
   
   RSINow = iRSI(NULL, 1440, 2, PRICE_CLOSE, 0);			//calculates the RSI value for 2 days
   MA200 = iMA(NULL, 1440, 200, 0, MODE_SMA, PRICE_CLOSE,0);		//calculates the moving average for 200 days
   MA5 = iMA(NULL, 1440, 5, 0, MODE_SMA, PRICE_CLOSE,0);     		//calculates the moving average for 5 days
   Alert(RSINow);
   Alert(MA200);
   Alert(MA5);
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----

   
   
   //check if a long position is possible, A is false means no buy trade is open , execute buy when RSI drops below 5 and when Ask price rises above 200 day moving average
   if (A1 == false && RSINow < 5 && Ask > MA200) {
   
   Ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Bid - ( StopLoss * Point ), Ask + ( TakeProfit * Point ));
   
   if(Ticket>0) {
            if(OrderSelect(Ticket,SELECT_BY_TICKET,MODE_TRADES)) {
               Print("BUY order opened : ",OrderOpenPrice());
               A1 = true;
           }
         if (Ticket < 0) {
         Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
   }
   }
   } 
   
   
   
     //check if a short position is possible, A2 is false means no sell trade is open , execute sell when RSI rises above 95 and when Bid price drops below 200 day moving average

   if (A2 == false && RSINow > 95 && Bid < MA200) {
   
   Ticket2 = OrderSend(Symbol(), OP_BUY, Lots, Bid, Slippage, Ask + ( StopLoss * Point ), Bid - ( TakeProfit * Point ));
   if(Ticket2>0) {
            if(OrderSelect(Ticket2,SELECT_BY_TICKET,MODE_TRADES)) {
               Print("SELL order opened : ",OrderOpenPrice());
               A2 = true;
           }
         if (Ticket2 < 0) {
         Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
         }
   }
   
   } 
   
   
   //check if buy position can be closed, once Ask price rises above 5 day moving average, its time to close the position.
   
   if ((A1 == true) && (Ask > MA5)) {
   OrderClose(Ticket, Lots, Bid, Slippage, Violet);
   A1 = false;
   return(0);
   }
   
   
   
   
   //check if sell position can be closed, if Bid price drops below 5 day moving average, close sell position.
   
   if ((A2 == true) && (Bid < MA5)) {
   OrderClose(Ticket2, Lots, Bid, Slippage, Violet);
   A2 = false;
   return(0);
   }
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
cyxstudio:

J'ai tout refait, j'ai corrigé la boucle, le slippage, j'ai fixé les valeurs de la moyenne mobile et du RSI, je me suis assuré que toutes les positions ouvertes sont fermées avant de commencer une nouvelle position. Mais quand je le backtest, rien ne se passe, aucun achat/vente n'a été exécuté... quel est le problème ?


Non, la boucle n'est pas corrigée, elle est supprimée et le problème est plus important.

. vous utilisez A1 et A2 qui obtiennent la valeur vraie au moment de l'ouverture de la transaction

Mais que se passera-t-il si l'alimentation de votre ordinateur tombe en panne et que vous devez redémarrer votre ordinateur et metatrader.

Vous devez vérifier à ce moment-là si des transactions sont ouvertes par votre EA.

Comment allez-vous faire cela ? ???

Pour rendre cela plus facile, utilisez un OrderMagicNumber spécifique pour ouvrir et vérifier vos transactions.

.

La moyenne mobile n'est pas déplacée maintenant, certaines barres dans le futur sont correctes.

mais vous ne la calculez que dans la section init() cela ne sera exécuté qu'au démarrage de votre Expert Advisor.

Il me manque dans Start() .... Pourquoi l'avoir enlevé ? ??

.

 

J'ai réécrit votre code et essayé un test, voir aussi les paramètres.

Ce n'est pas avec les meilleures données de backtest mais si vous le faites correctement, cela peut être rentable.

Rapport du testeur de stratégie
RSI_strategy_cyxstudio
AlpariUK-Demo - Micro+Classic (Build 451)

SymboleEURUSD (Euro vs Dollar US)
PériodeJournalière (D1) 2010.10.01 00:00 - 2013.01.29 00:00 (2010.10.01 - 2013.01.30)
ModèleChaque tick (la méthode la plus précise basée sur tous les délais les plus courts disponibles)
ParamètresRSIPeriod=3 ; UpperBound=90 ; LowerBound=5 ; MASlowPeriod=200 ; MAFastPeriod=5 ; Lots=0.1 ; StopLoss=60 ; TakeProfit=120 ; TrailingStop=40 ; MagicNumber=54333 ; CommentEA="Stratégie RSI" ; Slippage.Pips=3 ;
Barres dans le test1603Ticks modélisés40187739Qualité de la modélisationn.d.
Erreurs de cartes non concordantes2062601
Dépôt initial3000.00
Bénéfice net total967.18Bénéfice brut2226.34Perte brute-1259.16
Facteur de profit1.77Gain attendu13.62
Pertes absolues107.10Pertes maximales327.47 (7.99%)Tirage relatif7.99% (327.47)
Total des transactions71Positions courtes (% gagné)66 (69.70%)Positions longues (% gagné)5 (80.00%)
Transactions à profit (% du total)50 (70.42%)Transactions perdantes (% du total)21 (29.58%)
Le plus grandtransaction à profit120.07transaction perdante-60.00
Moyenneprofit commercial44.53transaction à perte-59.96
Maximumvictoires consécutives (profit en argent)8 (424.26)Pertes consécutives (perte d'argent)3 (-179.93)
Maximalgains consécutifs (nombre de victoires)424.26 (8)Perte consécutive (nombre de pertes)-179.93 (3)
Moyennegains consécutifs4pertes consécutives2

 
deVries:

J'ai réécrit votre code et essayé un test, voir aussi les paramètres.

Pas avec les meilleures données de backtest mais si vous le faites correctement, il peut être rentable.


Total des transactions71Positions courtes (% gagnées)66 (69.70%)Positions longues (% gagné)5 (80.00%)





Cela me fait penser qu'il y a quelque chose qui ne va pas.