Issues with running a loop in a partial close function in MQL5 EA

To add comments, please log in or register
Stanislav Ivanov
2326
Stanislav Ivanov  

Hello,

I have a problem with a function for partial order close, with a loop in it. Outside the loop i set a variable closed_volume =0, so the idea is to store the amount of closed lots , so that it may equal the previously set lot size for close - vlm .But what happens is when i run the loop once, the information is stored, but the second one comes the closed_volume is reset to 0. I tried everything, break ,return (not together)but what happens is that it just returns to the top of the function and resets the value. Id really use some help with it ! I printed out everything.

 

Test
void myOrderClose(ENUM_POSITION_TYPE type, double vlm) //
  {
  double closed_volume=0 ,ord_volume,vlm_diff;

  ulong tick;
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return;
   if (type > 1)
     {
      myAlert("error", "Invalid type in myOrderClose");
      return;
     } 
    trade.SetTypeFillingBySymbol(_Symbol);
    trade.SetDeviationInPoints(MaxSlippage_); 
   if(closed_volume<vlm){ 
   //----------------------
   for(int i = PositionsTotal()-1;i>=0;i--)
    {
     if(!position1.SelectByIndex(i))
      continue;
     if(position1.Symbol()==_Symbol && position1.Magic()==MagicNumber && position1.PositionType()==type)
      {
       Print("CLV 2 : ",closed_volume);       
       if(closed_volume==vlm)
       {Print("closed volume ",closed_volume);return; }   
           
       ord_volume=position1.Volume();
        if((closed_volume+ord_volume)<vlm)
        {
         tick = position1.Ticket();
         bool close = trade.PositionClosePartial(tick,ord_volume);
         if(!close)
          {Print("Error closing position #",tick," ",GetLastError());}
         else 
          {Print("Position #",tick," closed !");closed_volume+=ord_volume;} 
        }
      if((closed_volume+ord_volume)==vlm)
        {
         tick = position1.Ticket();
         bool close = trade.PositionClosePartial(tick,ord_volume);
         if(!close)
          {Print("Error closing position #",tick," ",GetLastError());}
         else 
          {Print("Position #",tick," closed !");closed_volume+=ord_volume;Print("CLV ",closed_volume);} 
        }
     if(closed_volume<vlm && closed_volume+ord_volume>vlm)
        {
         vlm_diff=vlm-closed_volume;
         tick = position1.Ticket();
         bool close = trade.PositionClosePartial(tick,vlm_diff);
         if(!close)
          {Print("Error closing position #",tick," ",GetLastError());}
         else 
          {Print("Position #",tick," closed !");closed_volume+=vlm_diff;} 
        }
       } 
      } 
    }
  }

for example see the picture - after one turn in the loop, the second resets !

Stanislav Ivanov
2326
Stanislav Ivanov  
   if(Cross(1, getBid() > Signal_Value + Long_TP2_pips * myPoint) //Price crosses above fixed value + fixed value
   && LastLongTradePrice() <= Signal_Value + Long_TP2_pips * myPoint //Last Open Trade Price (Long) <= fixed value + fixed value
   )
     {   
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && MQLInfoInteger(MQL_TRADE_ALLOWED))
       { 
        if(OpenTradeSize()>(total_size*(partialclose_percent2/100)))
         {
          close_volume=total_size*(partialclose_percent2/100);
         }
        else {close_volume=OpenTradeSize();}   
        myOrderClose(POSITION_TYPE_BUY, NormalizeLots(close_volume));
       }
      else //not autotrading => only send alert
         myAlert("order", "");
     }

This is how i utilize the code, a sample function. I tested further, and it seems that the order close function actually does its job good, but the  resetting(more volume being closed this way ) is actually happening by calling the function more that once, immediately after its fulfilled its called again and again. This is the troublemaker, but i can not find the reason.

Marco vd Heijden
Moderator
8418
Marco vd Heijden  
void myOrderClose(ENUM_POSITION_TYPE type, double vlm) //
  {
  double closed_volume=0;

You set it to zero every time you call the function.

If you want it to remember the value you have to declare it outside of the function, and reset it's value by external means.

double closed_volume=0;

void myOrderClose(ENUM_POSITION_TYPE type, double vlm) //
  {
Stanislav Ivanov
2326
Stanislav Ivanov  
Marco vd Heijden:

You set it to zero every time you call the function.

If you want it to remember the value you have to declare it outside of the function, and reset it's value by external means.

thanks for the suggestion,i  already did it, but it seems not working, because the close function is called multiple times from outside. 

Marco vd Heijden
Moderator
8418
Marco vd Heijden  

Try to use a different approach.

You can modify the examples from the documentation.

//+------------------------------------------------------------------+
//| Closing all symbol positions                                     
//+------------------------------------------------------------------+
void CloseAllSymbol(string symbol)
  {
//--- declare and initialize the trade request and result of trade request
   MqlTradeRequest request;
   MqlTradeResult  result;
   int total=PositionsTotal(); // number of open positions   
//--- iterate over all open positions
   for(int i=total-1; i>=0; i--)
     {
      //--- parameters of the order
      ulong  position_ticket=PositionGetTicket(i);                                      // ticket of the position
      string position_symbol=PositionGetString(POSITION_SYMBOL);                        // symbol 
      int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS);              // number of decimal places
      ulong  magic=PositionGetInteger(POSITION_MAGIC);                                  // MagicNumber of the position
      double volume=PositionGetDouble(POSITION_VOLUME);                                 // volume of the position
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);    // type of the position
      //--- output information about the position
      if(debug)
        {
         PrintFormat("#%I64u %s  %s  %.2f  %s [%I64d]",
                     position_ticket,
                     position_symbol,
                     EnumToString(type),
                     volume,
                     DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                     magic);
        }
      //--- if the MagicNumber matches
      if(magic==EXPERT_MAGIC)
        {
         if(symbol==position_symbol)
           {
            //--- zeroing the request and result values
            ZeroMemory(request);
            ZeroMemory(result);
            //--- setting the operation parameters
            request.action   =TRADE_ACTION_DEAL;        // type of trade operation
            request.position =position_ticket;          // ticket of the position
            request.symbol   =position_symbol;          // symbol 
            request.volume   =volume;                   // volume of the position
            request.deviation=5;                        // allowed deviation from the price
            request.magic    =EXPERT_MAGIC;             // MagicNumber of the position
            //--- set the price and order type depending on the position type
            if(type==POSITION_TYPE_BUY)
              {
               request.price=SymbolInfoDouble(position_symbol,SYMBOL_BID);
               request.type =ORDER_TYPE_SELL;
              }
            else
              {
               request.price=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
               request.type =ORDER_TYPE_BUY;
              }
            //--- output information about the closure
            if(debug){PrintFormat("Close #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));}
            //--- send the request
            if(!OrderSend(request,result))
            if(debug){PrintFormat("OrderSend error %d",GetLastError());}  // if unable to send the request, output the error code
            //--- information about the operation   
            if(debug){PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);}
            //---
           }
        }
     }
  }
//+------------------------------------------------------------------+

Closing all for a symbol.

You can easily add a parameter for the magic number, or a position type, volume and etc, anything you need really.

And you still have to add:

bool check=OrderCheck(request,checkresult);

To check before sending out the order.

Stanislav Ivanov
2326
Stanislav Ivanov  

i just finished it, the problem was in the calling function, so it was not in the close algorithm. 

Thanks for your help

To add comments, please log in or register