Partially close order error

 

Hi,

I’ve created an EA that will do partially close order if certain condition met. 

The first condition would be closing half of the open order, I use it using orderlots()*0.5. For the second condition I use only orderlots() to close all the order. The problem Is that I got an error 131, I thought it’s because using the orderlots() in the second condition (Thinking that the orderlots change into the new lots after closing the first condition).

Now I tried to use orderlots()*0.5 thinking that maybe the orderlots still remain the same even after closing partially. But again the result is the same I got the same error.

anyone can explain to me how can I do partially close order without getting the error 131?

 
Luandre Ezra:

Hi,

I’ve created an EA that will do partially close order if certain condition met. 

The first condition would be closing half of the open order, I use it using orderlots()*0.5. For the second condition I use only orderlots() to close all the order. The problem Is that I got an error 131, I thought it’s because using the orderlots() in the second condition (Thinking that the orderlots change into the new lots after closing the first condition).

Now I tried to use orderlots()*0.5 thinking that maybe the orderlots still remain the same even after closing partially. But again the result is the same I got the same error.

anyone can explain to me how can I do partially close order without getting the error 131?

Hello Ezra .

There are some conditions you should keep in mind and be meticulous about as partially closing orders is the pitfall of many ea's codewise :

  1. You have to make sure the partial lot you are closing is valid
  2. When you partially close an order it changes its ticket , so you have to look for the new ticket that spawned into your account
  3. To get the exact remaining lots of the open portion of the order you select it again and call its lots

Im attaching a code snippet for finding the partial ticket which works with most brokers

/* usage example ,close first , if order closed look for partial
            bool closed=CloseOrder(cp_buy,CPTrades[ix].Ticket,CPTrades[ix].Stops[ttp].LotsToClose,10,100,100);
            if(closed){CPTrades[ix].Ticket=GTL_Capture_Partial(Symbol(),BuyMagic,cp_buy,remainlot,op,CPTrades[ix].Ticket,true);}
*/
//FUNCTION TO FIND THE TICKET OF THE NEW PARTIAL CLOSE ORDER 
  int GTL_Capture_Partial(string symbol,
                          int magic,
                          cp_direction direction,
                          double lots,
                          double op,
                          int from_ticket,
                          bool with_comment)
  {
  int returnio=-1;
  if(IsTesting())
  {
  ENUM_ORDER_TYPE oty=OP_BUY;
  if(direction==cp_sell) oty=OP_SELL;
  int ords=OrdersTotal();
     for(int a=0;a<ords;a++)
     {
     bool choose=OrderSelect(a,SELECT_BY_POS,MODE_TRADES);
     if(choose)
       {
       if(OrderType()==oty)
         {
         if(lots==OrderLots())
           {
           if(op==OrderOpenPrice())
             {
             if(OrderCloseTime()==0&&OrderMagicNumber()==magic)
               {
               return(OrderTicket());
               }
             }
           }
         }
       }
     }
  }
  if(!IsTesting())
  {
  string mats=IntegerToString(from_ticket);
  int mats_len=StringLen(mats);  
  int ords=OrdersTotal();
  for(int a=0;a<ords;a++)
  {
  bool choose=OrderSelect(a,SELECT_BY_POS,MODE_TRADES);
  if(choose&&OrderSymbol()==Symbol()&&OrderMagicNumber()==magic)
  {
  if(with_comment==true)
    {
    if(GetContinuousNumber(OrderComment(),"#")==mats)
      {
      returnio=OrderTicket();
      break;
      }
    }
  //check magic adn creds ends here 
  }
  }
  }
  //not in tester ends here 
  return(returnio);
  }
//FUNCTION TO FIND THE TICKET OF THE NEW PARTIAL CLOSE ORDER ENDS HERE 
  string GetContinuousNumber(string feed,string from_character)
  {
  int size=StringLen(feed);
  int from=StringFind(feed,from_character,0);
  string numero="";
  for(int f=from+1;f<size;f++)
  {
  string charactero=StringSubstr(feed,f,1);
  bool valido=false;
  if(charactero=="0"||charactero=="1"||charactero=="2"||charactero=="3"||charactero=="4"||charactero=="5"||charactero=="6"||charactero=="7"||charactero=="8"||charactero=="9")
  {
  valido=true;
  numero=numero+charactero;
  }
  if(valido==false) break;
  }  
  return(numero);
  }
 
Lorentzos Roussos:

Hello Ezra .

There are some conditions you should keep in mind and be meticulous about as partially closing orders is the pitfall of many ea's codewise :

  1. You have to make sure the partial lot you are closing is valid
  2. When you partially close an order it changes its ticket , so you have to look for the new ticket that spawned into your account
  3. To get the exact remaining lots of the open portion of the order you select it again and call its lots

Im attaching a code snippet for finding the partial ticket which works with most brokers

For the second part I used magic number, so it should do the same trick like you suggest right?

for the third part and assuming of what you just stated that the new ticket after partially close is the remaining lots. But why the EA still give me error 131. Do you know any other reason why it behave like that?

 
Luandre Ezra:I use it using orderlots()*0.5.
  1. You can't just use OrderLots()/2 because that is not a multiple of LotStep, and you can't close or have remaining less than MinLot. See my code.
  2. You also must check if you have already done it, to avoid repeated closing. Alternatives:
    • Move SL to Break Even+1 before the partial close. That way you know that you already did it.
    • Set a flag in persistent storage (files, global variables w/flush)
    • Open two orders initially, and close one (manually or by TP.)
 
William Roeder:
  1. You can't just use OrderLots()/2 because that is not a multiple of LotStep, and you can't close or have remaining less than MinLot. See my code.
  2. You also must check if you have already done it, to avoid repeated closing. Alternatives:
    • Move SL to Break Even+1 before the partial close. That way you know that you already did it.
    • Set a flag in persistent storage (files, global variables w/flush)
    • Open two orders initially, and close one (manually or by TP.)

William is right , i forgot #1 too,the lot step 

Your best option is to select the new order -the remnant- with the new ticket ,read its lots ,close those lots 

Reason: