Exécution de plus d'une EE à la fois - page 3

 
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern bool CheckOncePerBar=true;
extern double FixedLotSize=1;
extern double SystemStopLoss=150;
extern double TakeProfit=0;
extern int Slippage=5;
extern int MagicNumber=3574;

//Global Variables
int BuyTicket=0;
int SellTicket=0;
double InternalStopLoss=0;
double CalcDigits=0;
double CalcPoint=0;
bool MABuyFanning=false;
bool MASellFanning=false;
int SelectedOrder=0;
bool Closed=false;
int ErrorCode=0;
string ErrLog="a";
double BuyStopLoss=0;
double SellStopLoss=0;
bool NewBar=false;
double ThisBarOpen=0;
double SmallMA=0;
double MediumMA=0;
double LargeMA=0;
int Counter=0;



//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
CalcDigits = MarketInfo(Symbol(),MODE_DIGITS);//MODE_DIGITS is count of digits after decimal point
if(CalcDigits==0) CalcPoint=1;//Dow      
if(CalcDigits==1) CalcPoint=0.1;   
if(CalcDigits==2) CalcPoint=0.01;//Gold & Nymex
if(CalcDigits==3) CalcPoint=0.01;//Yen
if(CalcDigits==4) CalcPoint=0.0001;//Not used
if(CalcDigits==5) CalcPoint=0.0001;//Non-Yen forex
InternalStopLoss=SystemStopLoss*CalcPoint;
   
   return(INIT_SUCCEEDED);
  }
//-----------------------------------------------

void OnTick()
{

   if(CheckOncePerBar)
      {
      if(ThisBarOpen!=Open[0])
         {
         ThisBarOpen=Open[0];
         NewBar=true;
         }
      else NewBar=false;
      }
    else NewBar=true;

if(NewBar)
{


//Reset Moving Averages
SmallMA=iMA(NULL,0,8,0,1,0,0);
MediumMA=iMA(NULL,0,10,0,1,0,0);
LargeMA=iMA(NULL,0,50,0,1,0,0);


   if(SmallMA>MediumMA&&MediumMA>LargeMA) MABuyFanning=true;
   else MABuyFanning=false;
      
   if(SmallMA<MediumMA&&MediumMA<LargeMA) MASellFanning=true; 
   else MASellFanning=false;   



if(BuyTicket==0&&MABuyFanning)
 {
      RefreshRates();
      BuyStopLoss= Bid-InternalStopLoss;
   //   while(IsTradeContextBusy()) Sleep(10);
      BuyTicket=OrderSend(Symbol(),OP_BUY,FixedLotSize,Ask,Slippage,BuyStopLoss,0,"Buy Order",MagicNumber,0,Green);
          if(BuyTicket==-1)
            {
            ErrorCode=GetLastError();
            Alert("Symbol: ",Symbol(),"Error in buy routine: ",ErrorCode);
            ErrLog=StringConcatenate("Bid: ",MarketInfo(Symbol(),MODE_BID)," Ask: ",MarketInfo(Symbol(),MODE_ASK)," Lots: ",FixedLotSize," Stop Loss: ",BuyStopLoss);
            Print(ErrLog);
            //Buy ticket revert to 0 so it can try again in case of slow connection/timeout etc.
            BuyTicket=0;
            } 
 }   


if(SellTicket==0&&MASellFanning)
 {
      RefreshRates();
      SellStopLoss=Ask+InternalStopLoss;
    //  while(IsTradeContextBusy()) Sleep(10);
      SellTicket=OrderSend(Symbol(),OP_SELL,FixedLotSize,Bid,Slippage,SellStopLoss,0,"Sell Order",MagicNumber,0,Red);
          if(SellTicket==-1)
            {
            ErrorCode=GetLastError();
            Alert("Symbol: ",Symbol(),"Error in sell routine: ",ErrorCode);
            ErrLog=StringConcatenate("Bid: ",MarketInfo(Symbol(),MODE_BID)," Ask: ",MarketInfo(Symbol(),MODE_ASK)," Lots: ",FixedLotSize," Stop Loss: ",SellStopLoss);
            Print(ErrLog);
            SellTicket=0;
            } 
  }  

//Exits

         if(BuyTicket!=0)
            {
            if(SmallMA<MediumMA)
            {
            for(Counter=0; Counter<=OrdersTotal()-1;Counter++)
               {
               SelectedOrder=OrderSelect(Counter,SELECT_BY_POS);
               if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_BUY)
                  {
                 // while(IsTradeContextBusy()) Sleep(10);
                  Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),Slippage,Red);
                  if(Closed) BuyTicket=0;
                  else Alert("Symbol: ",Symbol()," Ticket: ",BuyTicket," unable to close buy order(s): buy ma convergence close routine");                  
                  }
            Counter--;               
                }
            }
            }

         if(SellTicket!=0)
            {
            if(SmallMA>MediumMA)
            {
            for(Counter=0;Counter<=OrdersTotal()-1;Counter++)
               {
               SelectedOrder = OrderSelect(Counter,SELECT_BY_POS);
               if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_SELL)
                  {
               //   while(IsTradeContextBusy()) Sleep(10);
                  Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_ASK),Slippage,Red);
                  if(Closed) SellTicket=0;
                  else Alert("Symbol: ",Symbol()," Ticket: ",SellTicket," unable to close sell order(s): sell ma convergence close routine");                  
                  }
            Counter--;               
                }
            }
            }
}            
return;   
}
 

Vous avez toujours le compteur...

Voir le commentaire de GumRai https://www.mql5.com/en/forum/151167/page2#954622

 
Pensez-vous que deux barres consécutives puissent avoir exactement le même prix d'ouverture ?
   if(CheckOncePerBar){
      if(ThisBarOpen!=Open[0]){
         ThisBarOpen=Open[0];
         NewBar=true;
         }
      else NewBar=false;
      }
    else NewBar=true;

if(NewBar)
{
   : // doit
Toujours utiliser le temps
static datetime ThisBarTime = 0;
if(ThisBarTime != Time[0] || !CheckOncePerBar)
{
   ThisBarTime = Time[0];
   : // doit
Cela ne gère pas les cycles deinit/init. variable statique externe - MQL4 forum
 

Merci pour vos messages.

J'ai utilisé Open au lieu de Time car une fois que l'Open d'une barre se produit, il est fixé pour toujours et ne changera jamais. Il ne s'agit pas de deux barres consécutives - il s'agit de la même barre et on demande si l'ouverture de la barre actuelle au cours de laquelle le tick vient d'avoir lieu est la même que la valeur d'ouverture stockée dans ThisBarOpen. En outre, j'aurais pensé qu'Open serait plus simple que Time, car il s'agit d'une simple consultation de données, alors que Time doit faire référence à quelque chose d'autre et éventuellement effectuer une sorte de calcul.

Re Counter-- ; je n'ai pas changé cela parce qu'un autre EA ne serait pas capable de fermer un ordre parce que le code vérifie d'abord que le MagicNumber et Symbol() sont les mêmes.

Je comprends bien le point de vue sur une coupure de courant qui effacerait le contenu de BuyTicket mais cela ne s'est pas produit pendant mes tests et mon code fonctionne toujours très lentement. Je ne vois donc pas non plus comment cela pourrait être la cause.

Ma principale question pour le moment est de savoir pourquoi il a fallu autant de temps pour supprimer les EA des fenêtres du terminal qui avaient des positions ouvertes et pas du tout de temps pour les supprimer du terminal qui n'avait pas de positions ouvertes. Une coïncidence peut-être - mais les quatre fenêtres ?

 
La dernière fois j'ai eu le même problème et en fait c'est la façon dont vous codez l'ea. Il est peut-être temps que votre ea soit à nouveau écrite à partir de zéro. v2 par exemple.
 

Je ne sais pas si c'est vraiment pertinent pour votre problème mais vous limitez votre trading à 1 achat, 1 vente par EA alors pourquoi faire tout cela ?

  if(SellTicket!=0)
  {if(SmallMA>MediumMA)
   {for(Counter=0;Counter<=OrdersTotal()-1;Counter++)
    {SelectedOrder = OrderSelect(Counter,SELECT_BY_POS);
     if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_SELL)
     {Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_ASK),Slippage,Red);
      if(Closed) SellTicket=0;
      else Alert("Symbol: ",Symbol()," Ticket: ",SellTicket," unable to close sell order(s): sell ma convergence close routine");                  
     }
    Counter--;               
}}}} 

Vous avez déjà votre numéro de ticket ici :

SellTicket=OrderSend(Symbol(),OP_SELL,FixedLotSize,Bid,Slippage,SellStopLoss,0,"Sell Order",MagicNumber,0,Red);

Si vous en faites un int statique, vous pouvez clôturer votre ordre explicitement par ce numéro de ticket sans avoir à parcourir le pool d'ordres pour le trouver.

Closed=OrderClose(SellTicket,OrderLots(),MarketInfo(Symbol(),MODE_ASK),Slippage,Red);
 
Sneck55:

Merci pour vos messages.


En ce qui concerne Counter-- ; je ne l'ai pas changé parce qu'un autre EA ne pourrait pas fermer un ordre car le code vérifie d'abord que le MagicNumber et Symbol() sont identiques.


Ma principale question pour le moment est de savoir pourquoi il a fallu tant de temps pour supprimer les EA des fenêtres du terminal qui avaient des positions ouvertes et pas du tout de temps pour les supprimer du terminal qui n'avait pas de positions ouvertes. Coïncidence peut-être - mais les quatre fenêtres ?


Comprenez-vous comment fonctionnent les boucles ?

if(BuyTicket!=0)
            {
            if(SmallMA<MediumMA)
            {
            for(Counter=0; Counter<=OrdersTotal()-1;Counter++)
               {
               SelectedOrder=OrderSelect(Counter,SELECT_BY_POS);
               if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_BUY)
                  {
                 // while(IsTradeContextBusy()) Sleep(10);
                  Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),Slippage,Red);
                  if(Closed) BuyTicket=0;
                  else Alert("Symbol: ",Symbol()," Ticket: ",BuyTicket," unable to close buy order(s): buy ma convergence close routine");                  
                  }
            Counter--;               
                }
            }
            }

Disons que vous avez 3 ordres ouverts

Au premier passage, le compteur==0, donc l'ordre avec l'index 0 sera sélectionné.

A la fin de la boucle, vous diminuez le compteur de 1, donc compteur== -1.

Avant que la boucle ne s'exécute à nouveau, le compteur est augmenté de 1 dans le cadre de la fonction for. Donc le compteur ==0

Ainsi, lors de la prochaine exécution de la boucle, le compteur = 0 à nouveau ! et ainsi de suite.

Vous êtes coincé dans une boucle sans fin qui ne fait que vérifier l'indice d'ordre 0.

Le seul moyen pour que cela s'arrête est qu'il n'y ait pas d'ordres ouverts car alors OrdersTotal - 1 sera -1 et 0 n'est pas <= -1.

 
Merci beaucoup GumRaj - vous avez résolu mon problème ! Il fonctionne bien maintenant. C'est la première fois que j'écris du code dans MQL4, c'est donc un processus d'apprentissage pour moi. J'étais confus quant au fonctionnement de la boucle for.
 
Sneck55: GumRaj - vous avez résolu mon problème ! Il fonctionne bien maintenant.
Et comment l'avez-vous résolu ? Si vous ne faites pas de décompte, vous avez toujours un problème (#3) - il suffit de le cacher jusqu'à ce que vous ayez plusieurs ordres ou plusieurs EAs.
 
Il doit décrémenter s'il ferme un ordre pour correspondre à ce qui se passe dans le pool, mais pas s'il ne ferme pas d'ordre. S'il décrémente sans fermer un ordre, il entre dans une boucle sans fin.