How to close BUY and SELL position?

 

Sounds stupid, but I have problem to close positions. Since MQL5 does not offer any function to close position, all you can do is to open opposite one. The same thing you will find in provided sample Trade\Trade.mql.

If I start from beginning.

I have EA that trades every day once or twice. It opens orders with 1 lot and it can close full position at once or just partially and keep other part open. Each order have TakeProfit and StopLoss.

So, if I have 1 lot BUY position and I want to close 85% then I will open an opposite order - SELL with 0.85 lots.

I'm using MQL Trade\Trade.mqh and I defined my own object:

CTrade cEATrade;

I open order:

cEATrade.PositionOpen(BUY, 1 lot);

And I close just part of it:

cEATrade.PositionClose(SELL, 0.85 lot);

 

Other 0.25 will be closed by StopLoss or by EA later.

When I test my EA, everything works fine and I can't me more satisfied by output. Now I want to do some testing that would be more close to real life situation -  "Execution: Random Delay". Now, when prices can have unexpected changes, my EA stops working as well - it tries to close part of the order but instead it opens new - opposite - order. Why? Because, sometimes order can be closed by StopLoss in the same time when I try to close partially. Now my close command - PositionOpen(opositOrder) - is triggering MetaTrader to open SELL order with 0.85 lots. Since close order does not have StopLoss and TakeProfit then it always stays open till MetaTester finish testing of EA and forcing to close.

 

I have tried to implement many verifications but non of them has helped (just improved). Maybe I have understood it wrong, if not - better MetaQuotes help us with this because every well optimised EA will open and close orders partially. Everyone should have this problem.

I would like to see ClosePosition() function in MQL5.

Here is how I did but still fails:

 CheckOpenOrder()

 

CloseOrder() 

 

Close() 

 

Please help! How can I close orders? 

Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Trade Orders in DOM
  • www.mql5.com
Standard Constants, Enumerations and Structures / Trade Constants / Trade Orders in DOM - Documentation on MQL5
 

I have similar problems. And i am very long for the old good "OrderClose" of MQL 4 :) 

 

I have attached sample of the code so everyone could try it.

It is a test application that opens BUY orders all the time, as soon as there are no open orders. When order is very close to SL ot TP then we close it:

if(NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)+((PositionGetDouble(POSITION_TP)-PositionGetDouble(POSITION_PRICE_OPEN))*closing_part),_Digits)==PositionGetDouble(POSITION_PRICE_CURRENT))
              {
               //Limit reached, close half
               ClosePosition(closing_part);
              }

 I'm closing by opening oposite order:

MqlTick tick;
   SymbolInfoTick(_Symbol,tick);
   if(cTrade.PositionOpen(_Symbol,ORDER_TYPE_SELL,lots,tick.bid,0,0,"Closing half"))
     {
      //Order closed sucessfully
     }
   else
     {
      Print("Failed to open order! Error:",cTrade.CheckResultRetcodeDescription());
     }

 New orders are opened with constant size and static SL and TP:

void OpenPosition()
  {
   MqlTick tick;
   SymbolInfoTick(_Symbol,tick);
   double sl = tick.ask-100.0*_Point;
   double tp = tick.ask+100.0*_Point;
//There is no open positions, let's open one
   if(cTrade.PositionOpen(_Symbol,ORDER_TYPE_BUY,1.0,tick.ask,sl,tp,"Open"))
     {
      //Order sucessfully opened.
     }
   else
     {
      Print("Failed to open order! Error:",cTrade.CheckResultRetcodeDescription());
     }
  }

 When I test it with "Execution: Normal" then it looks like this:

Normal

but with "Execution: Random Delay" 

Random

 It's because now we have SELL order opened that doesn't have TP and SL, so, it is never closed.

Capture 

 Do I need to implement verification it there isn't opposite order created when I try to close my position? Need better solution!

 

Files:
 
It's very clear here that SL or TP order was executed before mine. MetaQuotes, could you implement that SL and TP orders overwrites SELL and BUY orders? So, my order would be declined. Or some similar solution...
 

If anyone needs, I have managed to get workaround!

First we modify our position close function. In successful case it needs to check if no opposite orders are created:

void ClosePosition(double lots)
  {
   if(PositionGetDouble(POSITION_VOLUME)<lots)
     {
      //Not enough volume
      return;
     }
   Log("Closing position...");
   MqlTick tick;
   SymbolInfoTick(_Symbol,tick);
   if(cTrade.PositionOpen(_Symbol,ORDER_TYPE_SELL,lots,tick.bid,0,0,"Closing half"))
     {
      //Order closed sucessfully
      Log("Position closed sucessfully!");
      VerifyIfNoOposit(POSITION_TYPE_SELL);
     }
   else
     {
      Log(StringFormat("Failed to open order! Error: %s",cTrade.ResultRetcodeDescription()));
     }
  }

 As you can see I'm calling VerifyIfNoOposit(). It looks like this:

void VerifyIfNoOposit(ENUM_POSITION_TYPE positionType)
  {
//Wait till all orders are closed, because some of them can open new positions
   Log("Verifying if there are no oposit orders...");
   WaitTillAllOrdersAreClosed();
   Log("Orders are all closed.");
   if(PositionSelect(_Symbol))
     {
      //Some position found
      if(PositionGetInteger(POSITION_TYPE)==positionType)
        {
         //Oposit order found!
         Log("/!\\ Oposit order found!");
         ENUM_ORDER_TYPE ordType;
         double price=0;
         MqlTick tick;
         SymbolInfoTick(_Symbol,tick);

         switch(positionType)
           {
            case  POSITION_TYPE_BUY:
               ordType=ORDER_TYPE_SELL;
               price=tick.bid;
               break;
            default:
               ordType=ORDER_TYPE_BUY;
               price=tick.ask;
               break;
           }

         Log("Making correction...");
         while(!cTrade.PositionOpen(_Symbol,ordType,PositionGetDouble(POSITION_VOLUME),price,0,0,"Correction"))
           {
            Log(StringFormat("Failed to do correction! Error: %s",cTrade.ResultRetcodeDescription()));
            //Wait a litle bit
            Sleep(200);
            //Update price value
            SymbolInfoTick(_Symbol,tick);
            if(ordType==ORDER_TYPE_SELL)
               price=tick.bid;
            else
               price=tick.ask;
           }

         Log("Oposit order closed sucessfully.");

        }
     }
   else
     {
      Log("No positions found.");
     }
  }

 As you can see, before it checks positions, it waits till all orders are closed: 

void WaitTillAllOrdersAreClosed()
  {
   bool wait;
   do
     {
      wait=false;
      for(int i=0;i<OrdersTotal();i++)
        {
         if(OrderSelect(OrderGetTicket(i)))
           {
            if(OrderGetInteger(ORDER_STATE)==ORDER_STATE_PLACED || OrderGetInteger(ORDER_STATE)==ORDER_STATE_STARTED)
              {
               Log("Working order found.");
               Sleep(200);//Wait a litle bit
               wait=true;
              }
           }
        }
     }
   while(wait);
  }

 Here I needed to implement special debug trace that would store everything in file (as I noticed, it displays really small part in original log file in StrategyTester.

Now my output looks like this:

Opening order...

Position opened sucessfully!

Opening order...

Position opened sucessfully!

Closing position...

Position closed sucessfully!

Verifying if there are no oposit orders...

Orders are all closed.

/!\ Opposite order found!

Making correction...

Failed to do correction! Error: requote (1.35744/1.35756)

Failed to do correction! Error: requote (1.35750/1.35762)

Failed to do correction! Error: requote (1.35754/1.35766)

Failed to do correction! Error: requote (1.35756/1.35768)

Failed to do correction! Error: requote (1.35763/1.35775)

Failed to do correction! Error: requote (1.35772/1.35784)

Failed to do correction! Error: requote (1.35770/1.35782)

Failed to do correction! Error: requote (1.35768/1.35780)

Failed to do correction! Error: requote (1.35771/1.35783)

Failed to do correction! Error: requote (1.35763/1.35775)

Failed to do correction! Error: requote (1.35758/1.35770)

Failed to do correction! Error: requote (1.35752/1.35764)

Failed to do correction! Error: requote (1.35747/1.35759)

Failed to do correction! Error: requote (1.35750/1.35762)

Failed to do correction! Error: requote (1.35758/1.35775)

Failed to do correction! Error: requote (1.35753/1.35770)

Failed to do correction! Error: requote (1.35738/1.35755)

Failed to do correction! Error: requote (1.35743/1.35760)

Opposite order closed sucessfully.

Opening order...

Failed to open order! Error: requote (1.35748/1.35762)

Opening order...

Failed to open order! Error: requote (1.35748/1.35762)

Opening order...

Failed to open order! Error: requote (1.35726/1.35739)

Opening order...

Failed to open order! Error: requote (1.35718/1.35730)

Opening order...

Failed to open order! Error: requote (1.35697/1.35708)

Opening order...

Failed to open order! Error: requote (1.35706/1.35718)

Opening order...

Position opened successfully! 

 So, here you have! All this just to open and close simple BUY and SELL orders. I'm scared to look deeper in multiple order types and currencies.

Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Trade Orders in DOM
  • www.mql5.com
Standard Constants, Enumerations and Structures / Trade Constants / Trade Orders in DOM - Documentation on MQL5
Files:
 

Hello,

I know this post is old but I'm new to mql5 and I'm facing the same problem you mention. I try to close an open position but instead it keeps opening new ones in opposite direction. Have you found a solution in this mean time?


Best regards

 
vinyoliver:

Hello,

I know this post is old but I'm new to mql5 and I'm facing the same problem you mention. I try to close an open position but instead it keeps opening new ones in opposite direction. Have you found a solution in this mean time?


Best regards

Me too, I have the same problem.

Actually I opened a similar post some days ago, but suggestions provided did not solve my problem.

What I exactly need is to manage opened positions giving me the possibility to change stop loss or take profit values or completely close positions.


How to do that?


Thanks