Problem Closing Single Order

 

Hi,

This is my first post here but hopefully someone can help with an issue I'm having with closing orders in an EA I'm writing.

The basic goal of the EA is to open positions with a time based exit built in so they are closed out again after a predetermined number of bars. Only one position can be opened per each new bar but and several positions can be open at once. I have tried to use a TimeToLive (TTL) variable to track the order in which each trade is opened so the EA knows which one to close first which seems to be working ok. The problem is that sometimes, but only sometimes, the EA will close all/multiple open positions instead of just closing the oldest position.

I've tried various different approaches but still having the same problem.

First I just used a single OrderClose() command to close out each trade but was finding some trades weren't being closed out due to requotes. To try and fix this I introduced a while loop that would end when OrderClose()=True but found this sometimes (but not always) closed more than just the trade I wanted to close.

So I have now resorted to using an if statement with OrderCloseTime() to check whether the selected order has closed, OrderTicket() to try and stop the EA from closing orders beyond the first one chosen and, as a last ditch effort, a counter to limit the number of passes.

Even with all of this the EA still occasionally (again not all the time) closes out more than just the 1 trade as wanted.

The edited code is below.

Any help or suggestions greatly appreciated as I'm stumped!

Thanks, HC

if (Bars>BarsTotal) //Identifies that a new bar has formed
   {
      if(Bars<HLPeriod+1)
      {
         Print("bars less than ", HLPeriod);
         return(0);
      }

         //-------------- Identify New Trade Trigger ---------------------------------+
      
         [CODE REMOVED]
         {
            //Open Short Trade
               
            ticket = OrderSend(Symbol(),OP_SELL,Stake,Bid,2,0,0,"Short",MagicNumber2,0,Red);     //Submits market sell order 
            TradeCount = OrdersTotal(); //Calculates how many open trades there are
            TTL[TradeCount]=TradeLength+1; //Assigns the TTL of the new trade as the trade length

         }
         
         [CODE REMOVED]
         {
            //Open Long Trade
            
            ticket = OrderSend(Symbol(),OP_BUY,Stake,Ask,2,0,0,"Long",MagicNumber1,0,Blue);     //Submits market buy order 
            TradeCount = OrdersTotal(); //Calculates how many open trades there are
            TTL[TradeCount]=TradeLength+1; //Assigns the TTL of the new trade as the trade length
            
         }
         
         //------------- End of New Trade Trigger ----------------------------+
      }
      
      if (OrdersTotal()>0) //Determines whether a trade is currently open
      {
         
         TradeCount=OrdersTotal();
         
         for(x=TradeCount;x>0;x--) //For TradeCount is OrdersTotal to 1 decreasing by 1 on each iteration
         {
      
            TTL[x]=TTL[x]-1; //Decreases the TTL for each trade by 1
            
            if (TTL[x]<=0) //Ready to close trade 
            {
               if (OrderSelect(0, SELECT_BY_POS, MODE_TRADES)==true)
               {
                  if(OrderType()==OP_BUY) ClosingPrice = Bid; //Checks the selected trade is a long position and assigns the bid as closing price
                  if(OrderType()==OP_SELL) ClosingPrice = Ask; //Checks the selected trade is a short position and assigns the ask as closing price
                  
                  ticket = OrderTicket();
                  counter = 1;
                  
                  if(OrderCloseTime()==0 && ticket == OrderTicket()&& counter <3)
                  { 
                     TradeClose=OrderClose(OrderTicket(),OrderLots(),ClosingPrice,3,Violet); //Close out the position at the appropriate (bid or ask) price
                     counter=counter+1;
                     Alert("Order Ticket ",ticket," / ",OrderTicket()," closed");
                  }
               }
            
               //Move all of the Trades one space back in the array
            
               for(y=1;y<=TradeCount;y++)
               {
                  TTL[y]=TTL[y+1];
               }
            }   
         }
      }
      
      BarsTotal = Bars;
   
   }
 
HC2005:

Any help or suggestions greatly appreciated as I'm stumped! 

Couple of general points,  don't use Bars it is not reliable,  use Time instead.

 

This is wrong:

for(x = TradeCount; x > 0; x--)

 the last position in the pool is TradeCount - 1  the first is  0  

 

Hi Raptor,

Thanks for swift response. I have amended the code to use the Time[] function instead of Bar[] function as suggested but still experiencing the same problem.

if (Time[0]>BarTime)
{
....

BarTime=Time[0]
}

The TradeCount variable is being used as an ID for each trade that is open so it is intentionally out of sync with the pool number (e.g. TradeCount 1 = pool number 0 and so on).

During the close procedure the OrderSelect() function selects order 0 from the pool in an attempt to only close the oldest open order but, as explained, this isn't always the case.

 
HC2005:


During the close procedure the OrderSelect() function selects order 0 from the pool in an attempt to only close the oldest open order but, as explained, this isn't always the case.

Sorry for my misunderstanding.

If you want to close the oldest order why not simply loop through all the orders in the pool and keep track of the oldest by OrderOpenTime() then when the loop has finished you will know the oldest and you can close it. 

 

After a lot of tweaking I think (touch wood) I've got it working consistently.

The main change was around adding checks in for all OrderSend(), OrderSelect() and OrderClose() functions. I think sometimes these functions weren't completing properly which then caused the EA to act erratically.

while(NewTrade == false)
{
   Ticket = OrderSend(Symbol(),OP_BUY,Stake,Ask,2,0,0,"Buying Dips Long",MagicNumber1,0,Blue);     //Submits market buy order 
   if (Ticket > 0)
      NewTrade = true;
   else
      NewTrade = false;
}

while(TradeClose == false)
{ 
   if (OrderClose(OrderTicket(),OrderLots(),ClosingPrice,3,Red) == true) //Close out the position at the appropriate (bid or ask) price
   {
      TradeClose = true;
      Alert("Order Ticket ",CloseTicket," / ",OrderTicket()," closed");
   }
   else
      TradeClose = false;
}

etc..
Thanks for your suggestions.
Reason: