Vérification de la bougie ouverte

 

Bonjour à tous,

Je suis assez nouveau dans le codage en mql4 et j'ai vraiment essayé de faire fonctionner mon premier EA. J'apprécierais sincèrement de l'aide pour ce qui suit. C'est juste un croisement de base, mais au lieu de croiser des moyennes mobiles, c'est juste le prix qui croise une moyenne mobile.

J'ai besoin qu'un ordre soit déclenché à l'ouverture de la bougie si : (le prix d'ouverture de la bougie actuelle est > à la moyenne mobile) et si (la bougie précédente a clôturé en dessous de la moyenne mobile).

Jusqu'à présent, j'ai le code suivant dans la zone principale :


//+------------------------------------------------------------------+

int start()

{

//---

double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,1) ;

double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0) ;

double PreviousFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,1) ;

double CurrentFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,0) ;

double PreviousPriceClose= iClose(NULL, 0, 1) ;

double CurrentCandleOpen= iOpen(NULL,0,0) ;

//----------------------Le calcul principal commence ici


if(PreviousPriceClose<PreviousSlow && (CurrentCandleOpen>(CurrentSlow)))

if(OrdersTotal () == 0)

BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,CurrentCandleOpen, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen) ;

//--------------

return(0) ;

return(0) ;

}

//+------------------------------------------------------------------+

Quoi que je fasse, je n'arrive pas à travailler, et je ne pense pas faire quelque chose de bien ici. Encore une fois, j'apprécierais vraiment votre aide !

 
    

  double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);   

Cette valeur change pendant que la bougie est en cours.

double CurrentCandleOpen= iOpen(NULL,0,0);

Ce n'est pas le cas

BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,CurrentCandleOpen, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);

Il est peu probable que CurrentCandleOpen soit un prix d'entrée valide pour de nombreux ticks.

Si vous devez utiliser cette logique, ne calculez qu'une seule fois lorsqu'une nouvelle barre s'ouvre.

Vérifiez les valeurs de retour si l'OrderSend échoue

 
GumRai:

Cette valeur change pendant que la bougie est en cours.

Ce n'est pas le cas

Il est peu probable que CurrentCandleOpen soit un prix d'entrée valide pour de nombreux ticks.

Si vous devez utiliser cette logique, ne calculez qu'une seule fois lorsqu'une nouvelle barre s'ouvre.

Vérifiez les valeurs de retour si l'OrderSend échoue.


Merci pour cette réponse rapide ! Laissez-moi voir si j'ai bien compris :

  1. Le CurrentSlow ne fonctionnera pas vraiment, car il est toujours en formation. Ok, c'est bon, je peux utiliser la valeur de la moyenne mobile qui s'est formée pour la bougie précédente. Cela ne devrait pas être un problème.
  2. Puisque CurrentCandleOpen n'est pas une valeur mobile... alors je suppose que cette partie du code est correcte ?
  3. Vous avez mentionné de ne calculer qu'une seule fois lorsqu'une nouvelle barre s'ouvre. Pourriez-vous développer ce point ? Je ne sais pas vraiment comment faire.
Merci encore GumRai.

 
   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      //Code to process the signal
     }

   
Le code entre les crochets ne sera exécuté qu'au premier tick d'une nouvelle barre.
 
GumRai:
Le code entre les crochets ne sera exécuté qu'au premier tick d'une nouvelle barre.

Merci pour le code ! J'ai mis à jour ce qui suit comme discuté précédemment :

  1. J'ai changé le slow actuel de la MA en Previous Slow.
  2. Suppression de CurrentCandleOpen avec Ask. Chaque fois que j'utilisais CurrentCandleOpen, au lieu de Ask, cela ne prenait pas de trades. Cependant, lorsque je l'ai remplacé par Ask, il a fonctionné, mais bien sûr, il a effectué des transactions lorsque Ask traverse la MA, et non lors de l'ouverture de la bougie.

Mais après cela, lorsque je l'ai inséré dans votre code comme suit, il ne prend plus aucune transaction. Ai-je inséré ceci correctement ?

int start()
  {
//---
    
  double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,1);     //1 at the end signifies that we want it on candle close
  double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);     //1 at the end signifies that we want it on candle close

  double PreviousFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,1);     //1 at the end signifies that we want it on candle close
  double CurrentFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,0);     //1 at the end signifies that we want it on candle close
   
  double PreviousPriceClose= iClose(NULL, 0, 1);
  double CurrentPriceClose= iOpen(NULL, 0, 0);
  
//----------------------Main calculation starts here

 static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
   if(PreviousPriceClose<PreviousSlow && Ask>PreviousSlow)
      if(OrdersTotal () == 0)
         BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,Ask, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);
   }
//--------------
   return(0);
   return(0);
  }
 

Pourquoi placer les appels iMA en dehors du nouveau code à barres ? Cela signifie qu'ils sont appelés à chaque tick alors qu'ils ne sont pas nécessaires - inefficace.

   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod, SlowMaAppliedTo,1);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if(PreviousPriceClose<PreviousSlow && Bid>PreviousSlow)
         if(OrdersTotal()==0)
            {
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
            if(BuyTicket==-1)
               {
               //Error checking code
               }
     }

N'utilisez pas les Ask pour comparer les valeurs sur un graphique MT4, ils sont basés sur le prix Bid.

Vérifiez les erreurs si l'OrderSend échoue.

Vous n'aurez pas beaucoup de cas où le premier tick d'une nouvelle barre est au-dessus d'une MA alors que le dernier tick de la barre précédente était en dessous.

 

Merci beaucoup GumRai. J'apprécie sincèrement votre aide.

Votre code fonctionne comme un charme. J'essaie toujours d'apprendre les ficelles ici, et j'ai vu l'iMA être mis sur son propre comme ça séparément. Je vais suivre votre méthode à la place.

***Je vais suivre votre méthode à la place.

Je vais retravailler mon code. Votre dernière ligne a mis en évidence la faille entre ce que je voulais et ce que j'ai réellement codé.

Ce que je dois faire en fait est :

  • étape 1 : la bougie se ferme en dessous de la MA,
  • étape 2 : la bougie croise et clôture au-dessus de la MA
  • Etape 3 : entrer la transaction à l'ouverture de la nouvelle bougie.

Dernière question, et je pense l'avoir résolue...

Pour l'étape 1 ci-dessus, l'iMA, le SlowMaShift serait de 2, correct ? Puisque c'est 2 barres derrière ? et le iClose serait : iClose(NULL,0,2) pour cette comparaison correcte ?

 

Il semble que vous ayez l'idée.

Modifiez et postez votre code et moi ou quelqu'un d'autre le commentera.

 
GumRai:

Il semble que vous ayez l'idée.

Modifiez et postez votre code et moi ou quelqu'un d'autre le commentera.

J'ai réussi à le faire fonctionner ! Merci GumRai.
Maintenant je fais la même chose mais en utilisant les règles opposées pour prendre le short. Indépendamment, cela fonctionne bien, mais je ne sais pas comment utiliser la fonction OrderCloseBy pour que si le long est ouvert, et que le short se déclenche, il ferme le long principalement parce que je n'ai aucun indice sur la façon de trouver le ticket d'ordre.... J'ai essayé de contourner la fonction OrderCloseBy en faisant ce qui suit :

int start()
  {
//---
 static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod, SlowMaAppliedTo,1);
      double PreviousSlow2 = iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod, SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      double PreviousPriceClose2=iClose(NULL, 0,2);
      if(PreviousPriceClose2<PreviousSlow2 && PreviousPriceClose>PreviousSlow && Bid>(PreviousSlow+PipsBeforeEntry*Pips))
         if(OrdersTotal()==0)
            {
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
         if(OrdersTotal()==1)
         {
            OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink) && OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
                  }
         if(OrdersTotal()==0)
         {
            OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
            }
     }
//--------------
   return(0);
   return(0);
  }
  return(0);
  }
 
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
         if(OrdersTotal()==1)

ne peut être satisfaite car elle se trouve à l'intérieur du bloc de conditions

         if(OrdersTotal()==0)

   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      double PreviousPriceClose2=iClose(NULL,0,2);
      if(PreviousPriceClose2<PreviousSlow2 && PreviousPriceClose>PreviousSlow && Bid>(PreviousSlow+PipsBeforeEntry*Pips))
        {
         if(OrdersTotal()==0)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
        }
      else
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
        {
         if(OrdersTotal()==1)
           {
            OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink);
            OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
           }
         else
         if(OrdersTotal()==0)
           {
            OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
           }
        }
     }

Je pense que ce qui précède est plus conforme à ce que vous vouliez.

Vous devriez vérifier les codes de retour d'erreur

 
GumRai:

Je pense que ce qui précède correspond plus à ce que vous vouliez faire.

Vous devriez vérifier les codes de retour d'erreur

Merci pour le code... malheureusement, il n'a pas vraiment fonctionné, puisqu'il entre maintenant dans un short plus d'une fois. Voici ce que j'ai essayé de faire à la place - je le décompose séparément - entrée et sortie longues, puis je créerai l'inverse pour l'entrée et la sortie courtes. Ce sera plus facile à gérer pour moi, et un peu plus facile à ajuster. Je travaille sur la partie entrée et sortie longues d'abord. Mais d'une manière ou d'une autre, cela ne ferme pas les transactions lorsque la bougie ferme en dessous de la moyenne mobile pour le short. Une idée de ce que je fais mal ? Il y a une erreur : La valeur de retour de 'OrderClose' doit être vérifiée. J'ai cherché une solution sur Google toute la matinée, mais cela ne semble pas fonctionner.

   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      double PreviousPriceClose2=iClose(NULL,0,2);
      if(PreviousPriceClose2<PreviousSlow2 && PreviousPriceClose>PreviousSlow && Bid>(PreviousSlow+PipsBeforeEntry*Pips))
        {
         if(OrdersTotal()==0)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
        }
      else
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow && Bid<PreviousSlow)
        {
          OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink);
          
        }
     

Mise à jour : J'ai supprimé le code d'erreur mais le ticket de fermeture ne semble toujours pas fonctionner. Tout ce que je veux c'est qu'il ferme l'achat une fois que la bougie traverse et ferme en dessous de la MA.

Raison: