MT4 Restart makes EA repeat recent tasks again?

 

Hey,

So, if MT4 is restarted, the EA will repeat the most recent available action. In my case, if price is >= exit prices, it will close out the desired lots again, when in fact this has already been done (as I use OrderClose() function).

How can I get the EA to remember that OrderClose() has already been completed once, so if MT4 restarts, it won't think it needs to do it again!

I'm hoping this is fairly straight forward... :s!

 

If you rely on a variable that is lost when MT4 is closed down, use a Global variable of the client terminal instead

https://docs.mql4.com/globals

 

Thanks GumRai.

Can you answer me this; I use a static datetime "partclosedonce" to stop OrderClose() function from continuously closing when Bid >= 1st target. This may be a stupid question, but if I put the static datetime "partclosedonce" within the global area of the MQL4 code, will this store the most previous value, even after an MT4 restart?

This is part of the code I am talking about (See below to understand more clearly what I am talking about):

//+--------------------------------------------------------------------------------------------------+
//| Close OP_BUY Half lots @ 1:1 Function                                                            |
//+--------------------------------------------------------------------------------------------------+
void CloseHalfOrder()
{   
   static datetime partclosedonce; //<< -- If I put this in the global area^, will it remember on the MT4 reboot?
   static datetime partclosedtwice;
   static datetime partclosedthird;
   
   static datetime EMA_MinLot;
   static datetime Second_Tar_MinLot;
   static datetime First_Tar_MinLot;
   
   double minLot = MarketInfo(Symbol(),MODE_MINLOT);   
   double lotStep=MarketInfo(Symbol(),MODE_LOTSTEP);
   
   double EMA_Bar = iClose(NULL, PERIOD_H1, 1);
   double EMA_MA = iMA(Symbol(),60,21,0,1,0,0);
   
   int PositionIndex;    
   int TotalNumberOfOrders;  
   TotalNumberOfOrders = OrdersTotal();   
   
for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --) 
    {
     bool CurrentOrder = OrderSelect(PositionIndex,SELECT_BY_POS,MODE_TRADES);
      if(  ! CurrentOrder ) continue;  
       if(OrderMagicNumber()==MagicNumber)
        if(OrderSymbol() == Symbol())
        { 
         if( CurrentOrder == True)  
            {
               double half_1st = MathFloor(OrderLots()/First_Target/lotStep)*lotStep;
               double half_2nd = MathFloor(OrderLots()/EMA_Target/lotStep)*lotStep;
               double Target_2 = MathFloor(OrderLots()/Second_Target/lotStep)*lotStep;
               FirstTarget_Buy = OrderOpenPrice()+(( OrderTakeProfit()-OrderOpenPrice()) / RewardRatio );  
               TwoRatio_Buy = OrderOpenPrice()+(( OrderTakeProfit()-OrderOpenPrice())/ ( RewardRatio / 2 )); 
            }
            
                            
          
          //<<-- First Target Order Close function -->>\\  
          if( partclosedonce != OrderOpenTime() && OrderType()==OP_BUY && Bid - FirstTarget_Buy > - Point ) 
              {
              
              if( minLot - half_1st > Point / 2. && OrderLots() - (minLot*2) > - Point ) 
                  {
                   bool FirstTarget_MinLotClose = OrderClose( OrderTicket(), minLot, Bid, 5, CLR_NONE );
                   if( FirstTarget_MinLotClose == True )partclosedonce = OrderOpenTime(); //<< -- This stop the OrderClose() being called again.
                     Alert("First Target - Min lot was closed out: ", Symbol());
                  }
               
               if( half_1st - minLot > - Point )
                  {
                  bool Close_Half_Order_Buy=OrderClose(OrderTicket(),half_1st,Bid,5,Blue);
                  if(Close_Half_Order_Buy!=TRUE)Print("Close_Half_Order_Buy Last Error = ",GetLastError(), " On: ", OrderSymbol());
                  if(Close_Half_Order_Buy==True)Print("BUY First Target Closed: ", OrderLots(), " On: ", OrderSymbol());
                  if(Close_Half_Order_Buy==True)partclosedonce = OrderOpenTime(); //<< -- This stop the OrderClose() being called again.
                     Alert("First Target Hit At: ", FirstTarget_Buy," on: ", Symbol()); 
                  }   
              }

......
 
DomGilberto: within the global area of the MQL4 code, will this store the most previous value, even after an MT4 restart?
  1. Of course not. He didn't say any such thing. He said to use a global variable, not globally declared variable.
  2. You have to code your EAs to recover. GV is one way. Files another. Looking at history and finding a closed order that was opened the same time as the current one is a third. What I do is either use two separate orders (one for each target.) Or, I move the SL to BE or above and then close. (If it's already above, the close has already occured.
 
DomGilberto:

Thanks GumRai.

Can you answer me this; I use a static datetime "partclosedonce" to stop OrderClose() function from continuously closing when Bid >= 1st target. This may be a stupid question, but if I put the static datetime "partclosedonce" within the global area of the MQL4 code, will this store the most previous value, even after an MT4 restart?



The documentation re global variables can be a bit confusing, that's why I included the link and used the phrase "Global variable of the client terminal" (GV).

A GV can only be used to store doubles. I don't know if there would likely be any issues with storing a datetime value as a double or not, I've never tried it. Maybe RaptorUK or WHRoeder know?

If you do try to use GVs, it is important to remember that they can be accessed by other EAs and scripts. So if you have the same EA running on multiple charts, it's important that the EA creates GV with a name unique to that instance of the EA. You can get over that by naming the GV with the magic number

GlobalVariableSet("partclosedonce"+MagicNumber, 0)

Of course there may be times that you Want other EAs to access the GV, but not in this case, I think.

You have to Get the GV to compare, but as I said, I am not sure of issues, if any with comparing a double with a datetime

if( GlobalVariableGet("partclosedonce"+MagicNumber) != OrderOpenTime() )
 

I never had a problem storing datetimes in doubles. Comparing datetime == double always seems to work too.

 

Thanks for all your responses :)

Could one of you be kind enough to tell me if I am going wrong here(see code):

( Check the lines where I have written an arrow and notes )

// << Global Area >> \\

static datetime partclosedonce;
static datetime partclosedtwice;
static datetime partclosedthird;

////////////////////////////////////////////////////////////////////////////////////////////////////////

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+


//<<-- Selecting the correct and corresponding order (EA on Chart) that has been triggered for working on -- >>\\

int PositionIndex; 
int TotalNumberOfOrders;
TotalNumberOfOrders  = OrdersTotal();

static datetime Sell_Targets_Confirmed;
static datetime Buy_Targets_Confirmed;

double H1_Close = iClose(NULL, PERIOD_H1, 1);
double MA_sixty = iMA(NULL,60,60,0,1,0,1);

double MinLots = MarketInfo( Symbol(), MODE_MINLOT );

for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --) 
  {  
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;
    if( OrderMagicNumber() == MagicNumber   
      && OrderSymbol() == Symbol() )                 
         {
            
               GlobalVariableSet("partclosedonce", 0); //<< -- This will correspond now to the correct order and magic number etc?
               GlobalVariableSet("partclosetwice", 0);
               GlobalVariableSet("partclosethird", 0); 


....


//+--------------------------------------------------------------------------------------------------+
//| Close OP_SELL Half lots @ 1:1 Function                                                            |
//+--------------------------------------------------------------------------------------------------+
void CloseHalfOrder1()
{   
     
   double minLot=MarketInfo(Symbol(),MODE_MINLOT);
   double lotStep=MarketInfo(Symbol(),MODE_LOTSTEP);
   
   double EMA_Bar = iClose(NULL, PERIOD_H1, 1);
   double EMA_MA = iMA(Symbol(),60,21,0,1,0,0);
   
   int PositionIndex;    
   int TotalNumberOfOrders;   
   TotalNumberOfOrders = OrdersTotal();   

for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --)  
   {
   bool CurrentOrder = OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES);
   if(  ! CurrentOrder ) continue;   
      if( OrderMagicNumber() == MagicNumber )   
         if( OrderSymbol() == Symbol())          
          {  
           if( CurrentOrder == True )
            {
              double half_1st=MathFloor(OrderLots()/First_Target/lotStep)*lotStep;
              double half_2nd=MathFloor(OrderLots()/EMA_Target/lotStep)*lotStep;
              double Target_2 =MathFloor(OrderLots()/Second_Target/lotStep)*lotStep;
              double Points_To_Deduct = (( OrderOpenPrice()-OrderTakeProfit()) / RewardRatio );
              FirstTarget_Sell = OrderOpenPrice()-Points_To_Deduct;
              double Points_To_Deduct2 = (( OrderOpenPrice()-OrderTakeProfit()) / ( RewardRatio / 2 ));
              TwoRatio_Sell_Target = OrderOpenPrice()-Points_To_Deduct2;
            } 
           
           
           
           //<<-- First Target Order Close function -->>\\ 
           if( OrderOpenTime() != partclosedonce && OrderType()==OP_SELL && FirstTarget_Sell - Ask > - Point && 
               GlobalVariableGet("partclosedonce") != OrderOpenTime() ) // << -- If this was true before an MT4 crash, then on a restart it will be false, right?
               {
               
               if(  minLot - half_1st > Point / 2. && OrderLots() - (minLot*2) > - Point ) 
                  {
                   bool FirstTarget_MinLotClose = OrderClose( OrderTicket(), minLot, Ask, 5, CLR_NONE );
                   if( FirstTarget_MinLotClose == True )partclosedonce = OrderOpenTime();
                     Alert("First Target - Min lot was closed out: ", Symbol());
                  }
               
               
               if( half_1st - minLot > - Point ) // Correct Exit
                  {  
                  bool Close_Half_Order_Sell=OrderClose(OrderTicket(),half_1st,Ask,5,Blue);
                  if(Close_Half_Order_Sell!=TRUE)Print("Close_Half_Order_Sell Last Error = ",GetLastError(), " On: ", OrderSymbol());
                  if(Close_Half_Order_Sell==True)Print("SELL First Target Closed: ", OrderLots(), " On: ", OrderSymbol());
                  if(Close_Half_Order_Sell==True)partclosedonce = OrderOpenTime();
                    Alert("First Target Hit At: ", FirstTarget_Sell," on: ", Symbol());
                  }   
               }

........
 

Ok scrap that top one - I know that was a waste of a post, as it doesn't make any sense. I realise now that I need to get and set the GlobalVariables like this:

*thing is, I'm being a little slow today, but how can I compare these GlobalVariableGet (time) against the current OrderOpenTime() to make sure that it doesnt OrderClose() it again? Man my brain is not working today - I swear its a simple if statement "!="....

 //+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  { 

  // Get Global Variable 
   GV = GlobalVariableGet("GlobalV"); 
   if(GV < 1) Print(" Can not Get a Global Variable !"); 
   else Print(" Successfully Got a Global Variable !"); 
     
   return(0);
  }


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+

int start()
 {
   
   // Set Global Variable 
   Set_GV = GlobalVariableSet("GlobalV",TimeCurrent()); 
   if( Set_GV < 1 ) Print(" Can not Set a Global Variable ! "); 

   // last reboot time 
   string last_reboot_time = " last reboot time : " + TimeToStr(GV, TIME_DATE | TIME_MINUTES); 

   // current time 
   double Get_GV = GlobalVariableGet("GlobalV"); 
   string CurrentTime = " GlobalV : " + DoubleToStr(Get_GV,0)+" ("+TimeToStr(Get_GV, TIME_DATE | TIME_MINUTES)+")"; 
   
...

  
 
WHRoeder:
  1. Of course not. He didn't say any such thing. He said to use a global variable, not globally declared variable.
  2. You have to code your EAs to recover. GV is one way. Files another. Looking at history and finding a closed order that was opened the same time as the current one is a third. What I do is either use two separate orders (one for each target.) Or, I move the SL to BE or above and then close. (If it's already above, the close has already occured.


Would this be logical?
  //<<-- First Target Order Close function -->>\\ 
   if( OrderOpenTime() != partclosedonce && OrderType()==OP_SELL && FirstTarget_Sell - Ask > - Point && 
       GlobalVariableGet("partclosedonce") != OrderOpenTime() ) 
       {
               
       if(  minLot - half_1st > Point / 2. && OrderLots() - (minLot*2) > - Point ) 
          {
          bool FirstTarget_MinLotClose = OrderClose( OrderTicket(), minLot, Ask, 5, CLR_NONE );
          if( FirstTarget_MinLotClose == True )partclosedonce = OrderOpenTime();
          if( FirstTarget_MinLotClose == True )GlobalVariableSet("partclosedonce", partclosedonce); //<< partclosedonce is a datetime when it should be a double para. ?
             Alert("First Target - Min lot was closed out: ", Symbol());
          }
               
 
Anyone able to throw me a line for stupid old me - I'm not understanding how to utilize GlobalVariableSet for comparison purposes when using OrderClose()...
 

I do it by OrderModify() add 1 pip to the broker SL before it is part closed. That way there is no need for recovery etc, the Order itself contains the information about how many times it was part closed already. (SL - OpenPrice) - (Original SL - OpenPrice) = nPartCloses.

Reason: