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

 
deVries:

lorsque vous démarrez votre Metatrader, l'EA doit vérifier si une transaction est ouverte.

Je ne fais que la boucle de décompte pour vérifier les transactions s'il y en a une.

Si je le règle au début sur un et que OrdersTotal() >0 alors je le fais vérifier les transactions if(.......> || .......> ){faire la boucle....

vous êtes sûr de m'avoir donné le code qui vous a donné les résultats montrés ci-dessus ? je l'ai testé sur une période de 1440 (1 jour) et aucune transaction n'a été exécutée. cependant, lorsque je l'ai changé pour 1M, de nombreuses transactions ont été exécutées.
 
cyxstudio:
vous êtes sûr de m'avoir donné le code qui vous a donné les résultats montrés ci-dessus ? je l'ai testé sur la période 1440 (1 JOUR) et aucune transaction n'a été exécutée. cependant quand je l'ai changé pour 1M beaucoup de transactions ont été exécutées.
combien de jours en arrière remontent vos données si vous vérifiez mon test à nouveau vous trouverez la période du test et le timeframe testé sur
 

OK, c'est parti : ...... Je vais essayer d'aider si je peux.

Cette question sur Ma_Shift est une question que j'ai depuis un certain temps et pour laquelle je n'ai jamais pu obtenir une réponse claire.

Si vous remarquez que dans votre code vous utilisez un décalage de 8 sur vos moyennes mobiles.... qu'est-ce que cela signifie ?

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) ;
Comme vous pouvez le voir, ce réglage de décalage n'existe pas sur le RSI... il s'affiche dans sa propre fenêtre... c'est un indice.
Si vous déposez une moyenne mobile sur votre graphique, vous verrez ce qui équivaut au Ma_Shift comme paramètre dans la case Shift.
Remarquez également que l'ordre des paramètres 200,8,sma,close. est le même lorsque vous appelez l'indicateur.
que l'ordre dans lequel ils sont listés dans la boîte... le NULL et le timeframe sont ceux sur lesquels vous déposez la Ma.
ils ne sont donc pas nécessaires ici. ni le réglage du dernier décalage... car cette ma changera constamment sur la bougie actuelle. 
bougie actuelle.... vous comprendrez cela dans un instant.
si vous allez voir les paramètres de l'indicateur iAlligator, vous verrez des paramètres pour le décalage de la mâchoire, le décalage des dents, et le décalage des lèvres... c'est le MaShift de chacune de ces moyennes mobiles.
elles peuvent toutes être décalées sur le graphique vers la gauche ou la droite du nombre de barres que vous voulez.

qui s'affiche comme ceci............

Cela fait une différence de 3 pip dans la valeur de cette bougie de 08:00 comme indiqué ici dans la fenêtre de données.

Ce qui nous amène à la question suivante : à quoi sert le paramètre "Shift" à la fin ?

Eh bien, lorsque vous passez la souris sur votre graphique avec la fenêtre de données ouverte et que vous vous déplacez de bougie en bougie

vous verrez les chiffres changer pour la 5 SMA au fur et à mesure que vous allez de bougie en bougie...

C'est à cela que sert la dernière valeur SHIFT... en gardant à l'esprit que la bougie actuelle qui est dessinée est la bougie zéro...

est la bougie zéro... la dernière bougie terminée est la bougie 1, donc s'il y a 1000 bougies au total sur votre

votre graphique, elles sont numérotées à l'envers de 999 sur le bord gauche de votre graphique à 0 où vous êtes actuellement.

Donc si vous voulez savoir quelle était la valeur de la 5 SMA il y a 5 bougies terminées, vous mettez un 5 à cet endroit.

vous mettez un 5 à ce dernier endroit... bien sûr, au fur et à mesure que le temps passe... la bougie 5 sera remplacée par la bougie suivante.

Maintenant, comme cela a été mentionné ... si vous obtenez toujours la valeur de la bougie 0 ... alors cette valeur change constamment avec le prix.

change avec le prix. Donc, vous pouvez prendre un signal et ensuite l'indicateur se repeint sur vous ... mais si vous êtes

mais si vous demandez toujours l'information de la bougie 1, il est fait et ne changera pas....

J'espère que cela vous aidera...

 
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 ?



la fonction init() ne s'exécute qu'au démarrage et non pas à chaque tick comme la fonction start(). vous devrez remettre les moyennes mobiles dans la fonction start au lieu de la fonction init() pour que cela fonctionne et qu'il y ait toujours de nouveaux chiffres...
 

Retravaillé

Ajouter une fonctionnalité où l'EA vérifiera s'il y a des ordres en attente avant de décider d'ouvrir une nouvelle position. S'il y a un ordre en attente ou ouvert, il ne tentera pas d'en ouvrir d'autres.at

je vois que tout le monde utilise une boucle pour vérifier s'il y a une position ouverte avant d'acheter, je ne vois pas la logique de cela. tant que OrdersTotal est > 0 il y a des ordres ouverts et mon EA ne cherchera pas à ouvrir d'autres positions.

J'ai corrigé la boucle décroissante.

Cette fois-ci, il me donne l'erreur 138 OrderClose qui ne peut être résolue en ajoutant refreshrates()

et je finis toujours par perdre de l'argent alors que je ne devrais pas.

Je ne vois rien d'autre à corriger...

//+------------------------------------------------------------------+
//|                                       RSI_strategy_cyxstudio.mq4 |
//|                                  Copyright 2013, Tjipke de Vries |
//|                                     https://forum.mql4.com/53695/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"


extern int RSIPeriod        =  3;      //number of periods for RSI
extern double UpperBound    =  90;     //set upper bound value for RSI
extern double LowerBound    =  5;      //set lower bound value for RSI
extern int MASlowPeriod     = 200;
extern int MAFastPeriod     = 5;
extern double Lots  = 0.1;
extern double StopLoss      = 60;       //Set the stop loss level
extern double TakeProfit    = 120;       //Set the take profit level
extern double TrailingStop = 40;
//extra settings for OrderSend
extern int        MagicNumber = 54333;
extern string     CommentEA = "RSI strategy";
extern int        Slippage.Pips    = 3;


int    BUYS=1,SELLS=1;
//++++ These are adjusted for 5 digit brokers.
int     pips2points;      // slippage  3 pips    3=points    30=points
double  pips2dbl;         // Stoploss 15 pips    0.015      0.0150
int     Digits.pips;      // DoubleToStr(dbl/pips2dbl, Digits.pips)
//---
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----   
   if(Digits % 2 == 1)  // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262
     {pips2dbl = Point*10; pips2points = 10;   Digits.pips = 1;}
     else {pips2dbl = Point;    pips2points =  1;   Digits.pips = 0;}
     // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl        
//----      

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   int Ticket;
   double SL,TP;
   int Total;
   double MagicNo;
   double Slippage;
   
   double pAsk = MarketInfo(Symbol(), MODE_ASK);
   double pBid = MarketInfo(Symbol(), MODE_BID);
   double MA200 = iMA(NULL, 0, MASlowPeriod, 0,MODE_SMA,PRICE_CLOSE, 0);  //200 day Moving Average   
   double MA5 = iMA(NULL, 0, MAFastPeriod, 0,MODE_SMA,PRICE_CLOSE, 0);      //  5 day Moving Average
   double CurrentRSI = iRSI (NULL, 1440, RSIPeriod,PRICE_CLOSE ,0);
  
   int Ticket2;
   int cnt;
   
   if(Bars<100)
     {
      Print("bars less than 100");
      return(0);  
     }
   
   if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }


  
        
        
        if (OrdersTotal() == 0 ) {
        
        if (CurrentRSI < LowerBound && pAsk > MA200) {    //Condition to execute buy entry
  
        Ticket = OrderSend(Symbol(), OP_BUY, Lots, pAsk, 3, pBid - ( StopLoss * Point ), pAsk + ( 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); 
   }
  
  }
  
  
 
  if (CurrentRSI > UpperBound && pBid < MA200) {     //Condition to execute sell entry
  
       Ticket2 = OrderSend(Symbol(), OP_SELL, Lots, pBid, 3, pAsk + ( StopLoss * Point ), pBid - ( 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); 
        }
      
   
   } 
   }
   
   if (OrdersTotal() > 0 ) {
   
   int PositionIndex;    //  <-- this variable is the index used for the loop

int TotalNumberOfOrders;   //  <-- this variable will hold the number of orders currently in the Trade pool

TotalNumberOfOrders = OrdersTotal();    // <-- we store the number of Orders in the variable

for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --)  //  <-- for loop to loop through all Orders . .   COUNT DOWN TO ZERO !
   {
   RefreshRates();
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?
   
   if (pAsk > MA5){      //condition to close long position
   RefreshRates();
    OrderClose(OrderTicket(),OrderLots(),pBid,3,Violet); // close long position
 
   return(0); // exit
   
   if(TrailingStop>0)  
              {                 
               if(pBid-OrderOpenPrice()>Point*TrailingStop)
                 {
                  if(OrderStopLoss()<pBid-Point*TrailingStop)
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),pBid-Point*TrailingStop,OrderTakeProfit(),0,Green);
                     return(0);
                    }
                 }
              }
   
  }
   
   if(pBid < MA5){       //condition to close short position
   RefreshRates();
   OrderClose(OrderTicket(),OrderLots(),pAsk,3,Violet); // close short position
  
   return(0); // exit
   
   
  if(TrailingStop>0)  
              {                 
               if((OrderOpenPrice()-pAsk)>(Point*TrailingStop))
                 {
                  if((OrderStopLoss()>(pAsk+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),pAsk+Point*TrailingStop,OrderTakeProfit(),0,Red);
                     return(0);
                    }
                 }
              }
   }
   
      if ( ! OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), Slippage ) )               // <-- try to close the order
         Print("Order Close failed, order number: ", OrderTicket(), " Error: ", GetLastError() );  // <-- if the Order Close failed print some helpful information 
      
   } //  end of For loop
   
   
   }
  
   
   
   
   
   
        
        
           return(0);
}
 
cyxstudio:

Retravaillé

Ajouter une fonctionnalité où l'EA vérifiera s'il y a des ordres en attente avant de décider d'ouvrir une nouvelle position. S'il y a un ordre en attente ou ouvert, il ne tentera pas d'en ouvrir d'autres.at

je vois que tout le monde utilise une boucle pour vérifier s'il y a une position ouverte avant d'acheter, je ne vois pas la logique de cela. tant que OrdersTotal est > 0 il y a des ordres ouverts et mon EA ne cherchera pas à ouvrir d'autres positions.

J'ai corrigé la boucle décroissante.

Cette fois-ci, il me donne l'erreur 138 OrderClose qui ne peut être résolue en ajoutant refreshrates()

et je finis toujours par perdre de l'argent alors que je ne devrais pas.

Je ne vois rien d'autre à corriger...

Pourquoi avez-vous placé la logique d'ouverture d'un achat avant de vérifier les transactions que votre EA a ouvertes sur votre compte ? ???.

Que va-t-il se passer maintenant ? ??? avec la programmation que vous avez jusqu'à présent ?

Supposons que vous ayez un compte sur lequel fonctionne votre EA. Vous ouvrez manuellement un trade pour GBPUSD.

Combien de transactions y a-t-il dans OrdersTotal() ?

Votre code.... pour BUY

if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }


  
        
        
        if (OrdersTotal() == 0 ) {
        
        if (CurrentRSI < LowerBound && pAsk > MA200) {    //Condition to execute buy entry
  
        Ticket = OrderSend(Symbol(), OP_BUY, Lots, pAsk, 3, pBid - ( StopLoss * Point ), pAsk + ( 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); 
   }
  

Que fait-il maintenant ? et pour quelle raison ?

 
deVries:

Pourquoi avez-vous placé la logique d'ouverture d'un achat avant de vérifier les transactions que votre EA a ouvertes sur votre compte ? ???.

Que va-t-il se passer maintenant ? ??? avec la programmation que vous avez faite jusqu'à présent ?

Supposons que vous ayez un compte sur lequel fonctionne votre EA. Vous ouvrez manuellement un trade pour GBPUSD.

Combien de transactions y a-t-il dans OrdersTotal() ?

Votre code.... pour BUY

Que fait-il maintenant ? et pour quelle raison ?


acheter uniquement si les conditions d'achat ont été remplies et si aucune position n'a été ouverte.
 
cyxstudio:

acheter seulement si les conditions d'achat ont été remplies et si aucune position n'a été ouverte.

Supposons que vous ayez un compte fonctionnant avec votre EA. Vous ouvrez manuellement un trade pour GBPUSD.

La condition sera-t-elle vraie

 if (OrdersTotal() == 0 )
 
cyxstudio2013.01.31 18:04

Vous pouvez me laisser jeter un coup d'œil à vos codes ?

Je veux savoir pourquoi j'ai échoué et comment le faire correctement.

.

Votre message à moi je peux vous donner le code complet directement.....

Ce ne sera pas gratuit. Pour cela, vous devez utiliser la sectionJobs et payer pour l'obtenir...

Vous l'obtiendrez alors là

.

Une autre façon est de lire vos sujets bien

Nous vous aidons ici à apprendre comment le programmer vous-même. C'est une aide gratuite.

Nous vous montrons vos erreurs et vous aidons dans la direction à résoudre.

Je montre le code que j'ai au moment où vous avez appris une façon de l'écrire ....

Pas besoin de payer et vous pouvez à ce moment-là le comparer avec le code que vous avez fait ici avec l'aide de ce forum.

....

ma dernière question n'a toujours pas reçu de réponse

Supposons que vous ayez un compte fonctionnant avec votre EA. Vous ouvrez manuellement un trade pour GBPUSD.

La condition sera-t-elle vraie ?

 if (OrdersTotal() == 0 )

.

. Dans l'autre sujetOrderClose error 138

vous avez été très bien aidé(RaptorUK et WHRoeder merci pour les explications, je pense que c'est très bien fait).

.

Une autre question que j'ai pour vous est

Pourquoi avez-vous changé le Timeframe dans ce calcul de la moyenne mobile ?

   double MA200 = iMA(NULL, 0, MASlowPeriod, 0,MODE_SMA,PRICE_CLOSE, 0);  //200 day Moving Average   
   double MA5 = iMA(NULL, 0, MAFastPeriod, 0,MODE_SMA,PRICE_CLOSE, 0);      //  5 day Moving Average

Ce n'est pas la même chose que ce que j'ai donné,

Il ne calcule pas la bonne valeur sur l'autre graphique Daily.

.

Donc, prenez le temps d'apprendre et de pratiquer et lisez attentivement l'aide que vous recevez ici sur ce forum.

ou vous payez quelqu'un pour programmer pour vous sur un site comme Jobs.

 
deVries:
cyxstudio2013.01.31 18:04

Vous pouvez me laisser jeter un coup d'œil à vos codes ?

Je veux savoir pourquoi j'ai échoué et comment le faire correctement.

.

Votre message à moi je peux vous donner le code complet directement.....

Ce ne sera pas gratuit. Pour cela, vous devez utiliser la sectionJobs et payer pour l'obtenir...

Vous l'obtiendrez alors là

.

Une autre façon est de lire vos sujets bien

Nous vous aidons ici à apprendre comment le programmer vous-même. C'est une aide gratuite.

Nous vous montrons vos erreurs et vous aidons dans la direction à résoudre.

Je vous montre le code que j'ai au moment où vous avez appris une façon de l'écrire ....

Pas besoin de payer et vous pouvez à ce moment-là le comparer avec le code que vous avez fait ici avec l'aide de ce forum.

....

ma dernière question n'a toujours pas reçu de réponse

Supposons que vous ayez un compte fonctionnant avec votre EA. Vous ouvrez manuellement un trade pour GBPUSD.

La condition sera-t-elle vraie ?

.

. Dans l'autre sujetOrderClose error 138

vous avez été très bien aidé(RaptorUK et WHRoeder merci pour les explications, je pense que c'est très bien fait).

.

Une autre question que j'ai pour vous est

Pourquoi avez-vous changé le Timeframe dans ce calcul de la moyenne mobile ?

Ce n'est pas la même chose que ce que j'ai donné,

Il ne calcule pas la bonne valeur sur l'autre graphique Daily.

.

Donc, prenez le temps d'apprendre et de pratiquer et lisez attentivement l'aide que vous recevez ici sur ce forum.

ou vous payez quelqu'un pour programmer pour vous sur un site comme Jobs.

Est-ce queOrdersTotal() est censé révéler le montant total des ordres en attente et des ordres au marché, qu'ils aient été ouverts par l'EA ou manuellement ?

Je pensais de cette façon. Mon EA vérifie toujours s'il y a des ordres ouverts et s'il y en a, il n'ouvre plus d'ordres et il n'ouvre de nouveaux ordres que lorsqu'il n'y en a plus.

if (OrdersTotal() == 0 )

Je pense que cela fonctionne bien car ma section de résultats me montre la séquence d'ordres 1,1,2,2,3,3,4,4 ce qui signifie qu'un ordre est fermé avant qu'un nouvel ordre soit ouvert.

Les variables de la moyenne mobile et du RSI ont changé pour des raisons de test. Je l'ai expérimenté sur différentes périodes de temps mais je ne l'ai pas modifié quand je l'ai posté ici.

et le plus bizarre de tout, mon code n'exécute QUE les ordres d'achat. il n'a jamais exécuté ne serait-ce qu'un seul... ordre de vente. c'est tout simplement bizarre,

En résumé, les problèmes que je rencontre encore maintenant.

1. il n'exécute que l'achat mais jamais la vente malgré le fait que j'ai codé la vente.

2. je fais toujours des profits négatifs, ce qui, j'en suis sûr, n'est pas le but de cette stratégie.