Un peu d'aide ?

 

Je suis donc en train d'apprendre mql4 après quelques autres langues, et je viens (du moins je le pensais) de terminer la première version de mon premier EA, un simple trader de moyenne mobile. Je l'ai laissé tourner toute la journée d'hier sans aucun souci, l'entrée et la sortie se faisaient comme prévu, et je pensais qu'il était prêt à fonctionner. Ce matin, j'ai rencontré toutes sortes de problèmes. Tout d'abord, le code, lorsque je l'ai ré-exécuté, ne faisait que vendre, quelle que soit la position, et maintenant, après un peu de bricolage, il achète et vend dans les positions correctes, MAIS lorsqu'il achète, la transaction se ferme au prochain tick. Cela ne se produit pas lorsque je vends alors que je détiens le même format - quelqu'un peut-il m'indiquer la raison ?

(A titre d'information, mon ordinateur était capable d'exécuter le code toute la journée d'hier sans beaucoup plus d'un bourdonnement (CPU en moyenne 12%) aujourd'hui il va comme des cloches d'enfer pour exécuter le code (~60-90%))

Code :

int total;
//+------------------------------------------------------------------+
//| expert init function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                   |
//+------------------------------------------------------------------+
int start()
  {
//----
   int p,q,z,i,L;
   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 
RefreshRates();
//----
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
      {                                                                                                                             //---------- ^ conditions to buy
      p=OrderSend(Symbol(),OP_BUY,0.1,Bid,0,0,0,"",z,0,Red);                                                                        //---------- Buy Order
      OrderSelect(p,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))                             //- whilst the above remains true
            {
            RefreshRates();                                                                                                         //- refresh then do nothing
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);                                                                      //---when above is broken, close
         while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }
//-----         
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
       {                                                                                                                            //---Same steps as above for sell
       q=OrderSend(Symbol(),OP_SELL,0.1,Ask,0,0,0,"",z,0,Blue);
       OrderSelect(q,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))
            {
            RefreshRates();
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);
         while (TimeSeconds(TimeCurrent())!=0)
            {
            Sleep(1000);
         }      
         continue;
      }
if (total!=0)
   {
   L=0;
   for (i=1; i<=OrdersTotal(); i++)                                                       //--- if trades were open which werent initially closed
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- close them if now the position has change
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  L++;
               }
            }
            total=L;
         }
      }
   }
else 
   {
   Sleep(1000);
} 
}
//----
return;
}
//--------------------------------------------------------------+
 

Je ne suis pas allé trop loin dans votre code.

Pourquoi rafraîchir les taux et ensuite dormir pendant 1 seconde, lorsque le marché évolue rapidement, les données ne seront plus à jour !

Vous calculez sur les ticks, pas sur les barres, donc 1 tick peut déclencher un ordre si un MA se déplace au-dessus/au-dessous de l'autre d'une quantité minimale. Si le tick suivant (après le sommeil) s'inverse, les MAs se croisent à nouveau et l'ordre sera fermé.

 

L'idée est de simplement rester dans la boucle pendant que les conditions attendent jusqu'à ce que les conditions de fermeture se produisent (alias le basculement des SMA) - certes pas la meilleure façon de le faire, mais l'une des moins coûteuses en termes de calcul.

Les SMA se déplaçant rapidement au-dessus/en dessous l'un de l'autre est l'un des problèmes du code - mais je ne vois pas pourquoi, quand il y a actuellement 10 - 15 pips entre les deux que je suis en cours d'exécution, conduirait à la fermeture ? les conditions sont certainement tenir pour la boucle while pour rester en contrôle, au lieu de sauter instantanément à la fermeture (mon hypothèse est que la boucle while est ignorée pour l'achat, mais pas la vente - et je ne sais pas pourquoi).

 
j.w.msb:

L'idée est de simplement rester dans la boucle pendant que les conditions attendent jusqu'à ce que les conditions de fermeture se produisent (alias le basculement des SMA) - certes pas la meilleure façon de le faire, mais l'une des moins coûteuses en termes de calcul.

Les SMA se déplaçant rapidement au-dessus et au-dessous les unes des autres est l'un des problèmes du code - mais je ne vois pas pourquoi, quand il y a actuellement 10 - 15 pips entre les deux que je suis en cours d'exécution, conduirait à la fermeture ? les conditions sont certainement tenir pour la boucle while pour rester en contrôle, au lieu de sauter instantanément à la fermeture (mon hypothèse est que la boucle while est ignorée pour l'achat, mais pas la vente - et je ne sais pas pourquoi).


Si vous vérifiez seulement si une MA est au-dessus ou au-dessous de l'autre, je doute que la différence soit généralement de 10 à 15 pips, elle peut être de 0,1 pips et donc le prochain tick peut facilement l'inverser.

Ce n'est que mon opinion, mais lorsque vous travaillez avec des croisements, je crois qu'il est préférable de ne calculer que sur des barres fermées pour éviter trop de signaux opposés.

 

De plus, dans votre init

 int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}

votre else ne s'applique qu'au dernier if, donc si l'EA ne ferme pas un ordre de vente ouvert, le total sera augmenté de 1. Pourquoi voulez-vous cela ?

 
GumRai:


Si vous vérifiez seulement si une MA est au-dessus/au-dessous de l'autre, je doute que la différence soit généralement de 10 à 15 pips, elle peut être de 0,1 pips et donc le prochain tick peut facilement l'inverser.

Ce n'est que mon opinion, mais lorsque l'on travaille avec des croisements, je pense qu'il est préférable de ne calculer que sur des barres fermées pour éviter trop de signaux opposés.


C'était une erreur de calcul de ma part en termes de pips ! ma faute ! Mais le point est qu'il y a certainement un espace de respiration entre les deux afin qu'il n'y ait pas de signal de croisement pour forcer la vente. Remplacer le Sleep(1000) par while (TimeSecond(TimeCurrent)!=59) {Sleep(1000)} assurerait le test du crossover uniquement à la fermeture de la bougie ?


J'ai enlevé l'OrderClose dans la section d'achat et l'ordre est toujours ouvert lors de l'exécution et ensuite fermé sur le prochain pip :s


Ensuite, j'ai changé OP_BUY et OP_SELL et la vente se tient comme prévu lorsque la 6SMA est au-dessus de la 21SMA - j'attends le prochain croisement pour voir ce qui se passe (évidemment, je teste ceci dans l'échelle de temps minute pour le moment).

 

Il y a beaucoup de choses à changer..... une chose sur laquelle travailler.

Quel est le numéro magique des trades que votre EA crée...

pourquoi ne pas en faire une variable d'entrée externe pour que ce soit un numéro unique et qu'il ne ferme pas les transactions des autres EAs

int init()
  {

//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }

ce qui se passe ici...

      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair

         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose( OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(O rderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }

ne comptez pas la vérification des transactions, cela échouera si vous fermez des transactions à l'intérieur de la boucle comme vous le faites maintenant.

Jetez un coup d'oeil ici pour voir pourquoi vous devez travailler et comment le décompte est effectué.

https://www.mql5.com/en/forum/139654

(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)

cette condition peut changer plusieurs fois en quelques instants quand un nouveau tick arrive dans chaque trade que vous payez le spread.

la condition ne change pas toujours une fois ....sur une seule barre

   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 

ce qui fonctionne toujours vous le laissez dormir

et de manière normale, lorsque le tick est terminé et qu'un nouveau tick arrive, start() est appelé à nouveau.

    while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }

de cette façon l'exécution du code seulement quand la seconde est 0 échouera souvent

parce qu'il peut arriver souvent qu'à une seconde il n'y a pas de nouveau tick qui arrive

si le premier tick de la minute arrive à 1 seconde, vous devez attendre la nouvelle minute et espérer que le nouveau tick arrive à la seconde 0 la minute suivante.

Vérifiez la fonction RefreshRates()

Il y a d'autres choses à faire, comme le faire fonctionner aussi bien avec un courtier à 4 ou 5 chiffres.

vérification des codes de retour....

Slippage votre valeur 0 pourquoi est ce nécessaire ? ?? pour l'avoir plus grande

 
deVries:

Il y a beaucoup de choses à changer..... une chose sur laquelle travailler.

Quel est le numéro magique des trades que votre EA crée...

pourquoi ne pas en faire une variable d'entrée externe pour que ce soit un numéro unique et qu'il ne ferme pas les transactions des autres EAs

ce qui se passe ici...

ne comptez pas la vérification des transactions, cela échouera si vous fermez des transactions à l'intérieur de la boucle comme vous le faites maintenant.

Jetez un coup d'oeil ici pour voir pourquoi vous devez travailler et comment le décompte est effectué.

https://www.mql5.com/en/forum/139654

cette condition peut changer plusieurs fois en quelques instants quand un nouveau tick arrive dans chaque trade que vous payez le spread

la condition ne change pas toujours une fois .... sur une seule barre

ce qui fonctionne toujours vous le laissez dormir

et de manière normale, lorsque le tick est terminé et qu'un nouveau tick arrive, start() est appelé à nouveau.

de cette façon l'exécution du code seulement quand la seconde est 0 échouera souvent

parce qu'il peut arriver souvent qu'à une seconde il n'y ait pas de nouveau tick qui arrive

si le premier tick de la minute arrive à 1 seconde, vous devez attendre la nouvelle minute et espérer que le nouveau tick arrive à la seconde 0 la minute suivante.

Vérifiez la fonction RefreshRates()

Il y a d'autres choses à faire, comme le faire fonctionner aussi bien avec un courtier à 4 ou 5 chiffres.

vérification des codes de retour....

Slippage votre valeur 0 pourquoi est ce que c'est nécessaire ? ?? pour l'avoir plus grand

Merci pour votre aide, je fais des changements maintenant et je vais voir comment ça se passe ! Des erreurs stupides aggravées par des erreurs stupides de ma part ! C'est presque un miracle qu'il ait fonctionné en premier lieu !
 

J'ai donc réduit le code pour qu'il s'exécute dans les capacités les plus simples (c'est-à-dire croisement = positions inversées) - il provoque beaucoup d'ordres d'achat/de vente lorsque les deux SMA sont proches, mais cela ne m'inquiète pas (pour l'instant) et il fonctionne bien sur un compte de démonstration. Ce qui me préoccupe maintenant, c'est que si j'exécute mon code sur le testeur de stratégie, il ouvre correctement la première position, mais ne parvient pas à avancer dans le temps, de sorte que les SMA ne se croisent jamais. Qu'est-ce que je fais de mal ? Ma liste d'impression est la suivante

2013.10.22 23:41:26 2013.09.18 00:41 Testeur : l'ordre #1 est clôturé

2013.10.22 23:41:26 2013.09.18 00:41 SMACode3 GBPJPY,M1 : 0

...

2013.10.22 23:40:53 2013.09.18 00:41 SMACode3 GBPJPY,M1 : 0

2013.10.22 23:40:52 2013.09.18 00:41 SMACode3 GBPJPY,M1 : 0

2013.10.22 23:40:51 2013.09.18 00:41 SMACode3 GBPJPY,M1 : 0

2013.10.22 23:56:18 SMACode3 GBPJPY,M1 : chargé correctement

Code :



//+------------------------------------------------------------------+
//|                                                   SMA scripy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
extern int z=1234;
int total;
//----

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()!=0)
      {
      for (i=OrdersTotal()-1; i>=0; i--)                                                     
         {
         if (OrderSelect(i,SELECT_BY_POS))
            {
            if (OrderSymbol()==Symbol())
               {
               if (OrderMagicNumber()==z) 
                  {
                  if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     { 
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     {
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  else 
                     {
                     total++;                                                                 
                  }
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int start()
   {
//----
   int i,L;
   while (AccountBalance()>50)                                                                                     
   {
   RefreshRates();
//-----
double SMA6=iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0);
double SMA21=iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0);
double RSI70=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70;
double RSI30=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30;                                                                                                            
//-----   
if (IsTesting()==true)
{
Sleep(60000);
Print(GetLastError());
}
//----
   if (total==0)
      {
      if ((RSI70)&&(SMA6>SMA21))
         {                                                                                                                       
         OrderSend(Symbol(),OP_BUY,0.1,Ask,0,0,0,"",z,0,Red); 
         total+=1;                                                       
         continue;
      }
      if ((RSI30)&&(SMA6<SMA21))
         {
         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
         total+=1;
         continue;
      }  
   }
//---
if (total!=0)
   {
   L=0;
   for (i=OrdersTotal()-1; i>=0; i--)                                                    
      {
      if (OrderSelect(i,SELECT_BY_POS))
         {
         if (OrderSymbol()==Symbol())
            {
            if (OrderMagicNumber()==z) 
               {
               if ((OrderType()==OP_BUY)&&(SMA6<SMA21))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
                     total+=-1;
                 return;
               }
               if ((OrderType()==OP_SELL)&&(SMA6>SMA21))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                 
                     total+=-1;
                  return;
               }
               else 
                  {
                  L++;                                                                  
               }
            }
            total=L;
         }
      }
   }
}
//----
}
//----
return;
}
//--------------------------------------------------------------+
 
j.w.msb: Ce qui me préoccupe maintenant, c'est que si j'exécute mon code sur le testeur de stratégie, il ouvre correctement la première position, mais ne parvient pas à avancer dans le temps,
  1. int start(){
       while (AccountBalance()>50){
          :
    Bien sûr que non. RTFM. Vous n'obtenez un nouveau tick que lorsque vous revenez du départ.
  2. if (IsTesting()==true){
        Sleep(60000);
        Print(GetLastError());
    }
    RTFM et limites du testeur: vous ne pouvez PAS dormir dans le testeur.
  3.         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
                      OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
    
    Que sont les valeurs de retour des fonctions ? Comment les utiliser ? - Forum MQL4
 
RefreshRates ne modifie aucune valeur dans le testeur, vous êtes donc coincé dans une boucle while car il n'a pas de nouvelles valeurs avec lesquelles travailler.