Ordersend related problem of unwanted duplicate order?

 

Hi there,

I am battling with a part of my EA related to Ordersend...

Sometimes my EA opens a second order milliseconds after the first one.

The part of my EA that deals with the opening of a long order is below...

if(ticketlong==-1) // If I'm not already long...
{//
MyNumOfLots=NumOfLots(EquityPerLot); // Calculates No. of lots based on Equity
ticketlong=OrderSend(Symbol(),OP_BUY,MyNumOfLots,Ask,slippage*Point,0,0,"My buy order",MagicLong,0,Green); // Open order...
if(ticketlong>-1) // If order was opened...
{//
if(OrderSelect(ticketlong,SELECT_BY_TICKET,MODE_TRADES))
Alert(Symbol(),": LONG opened:",OrderOpenPrice(),", Ticket:",ticketlong);
longclosed=false; // Zero variables...
}//
else // Order didnt open... why? & try fix...
Error_Long=ErrorBlock(GetLastError()); // My custom error call funtion

later in my EA I handle closing a long order as follows...

if(longclosed==false) // If I'm still long...
{//
longclosed=OrderClose(ticketlong,MyNumOfLots,Bid,slippage*Point,Red); // Close the order...
if (longclosed==true) // If order was closed...
{//
Alert(Symbol(),": LONG closed, ticket No:",ticketlong);
ticketlong=-1; // Zero variables...
}//
else // Order didnt open... why? & try fix...
Error_close=ErrorBlock(GetLastError());
}//

I only want to be able to open 1 long order at once, i shouldnt be able to go long if i already am...

It works most of the time, but from time to time i get a trade that shouldnt be there.

any ideas?

Regards,

Mike

 
You can do one more check before opening any trades. Check if any trades with the same magic number already exist. Only if no trades exist you run the code you posted.
 
robofx.org:
You can do one more check before opening any trades. Check if any trades with the same magic number already exist. Only if no trades exist you run the code you posted.

Hi there,

thanks for the suggestion... have inserted the below and will run on demo and see if problem is fixed...

if(ticketlong==-1) // If I'm not already long...
{//
if (OrderMagicNumber()!= MagicLong) // double checked if I'm not already long...
{//
MyNumOfLots=NumOfLots(EquityPerLot); // Calculates No. of lots based on Equity
ticketlong=OrderSend(Symbol(),OP_BUY,MyNumOfLots,Ask,slippage*Point,0,0,"My buy order",MagicLong,0,Green); // Open order...
if(ticketlong>-1) // If order was opened...
{//
if(OrderSelect(ticketlong,SELECT_BY_TICKET,MODE_TRADES))
Alert(Symbol(),": LONG opened:",OrderOpenPrice(),", Ticket:",ticketlong);
longclosed=false; // Zero variables...
Error_Long=0; // Zero variables...
}//

else // Order didnt open... why? & try fix...
Error_Long=ErrorBlock(GetLastError());
}//
}//

regards, Mike

 

OrderMagicNumber requires you to select an order, so I' not sure that code is going to work for you.

You could just count the long and short orders in the pool and trade accordingly...

   int   longcount,shortcount,type,magic;

   longcount=0;
   shortcount=0;
   for(int i=OrdersTotal()-1; i>=0; i--)                                                
      {
      if (OrderSelect(i,SELECT_BY_POS)==true)                           
         {                                                                  
         type=OrderType();                                              
         
         if (OrderSymbol()!=Symbol()||type>1 || OrderMagicNumber()!=magic) // filters out pending orders and orders from other EA's
            {
            continue;
            }                           
         if (type==0)
            {
            longcount++;
            }
         if (type==1)
            {
            shortcount++;
            }   
         }
      }

Oh, and please use the src button for code...

hth

V

 
Agreed, and if you're going to be writing more than one EA, I'll recommend turning that code into a User Defined Function and put it in the Include folder. Please search for User Defined Function or Include if you need more understanding.
 
Viffer:

"please use the src button for code..."





thanks for input, please explain "src button" in dont understand abrievation

 
miketinn:


thanks for input, please explain "src button" in dont understand abrievation

It makes code much easier to read if you input it with the src button

V

 
Viffer:

OrderMagicNumber requires you to select an order, so I' not sure that code is going to work for you.

You could just count the long and short orders in the pool and trade accordingly...

Oh, and please use the src button for code...

hth

V





   longcount=0;
   shortcount=0;
   for(int i=OrdersTotal()-1; i>=0; i--)                                                 
      {
       if (OrderSelect(i,SELECT_BY_POS)==true)                           
         {                                                                
          type=OrderType();    // Short = 1, Long = 0, 
          if (OrderSymbol()!=Symbol()||type>1 || OrderMagicNumber()!=magic) // filters out pending orders and orders from other EA's
          // if Symbol of selected order != Symbol of chart OR type > 1? OR magic numbers dont match
            {
             continue;
            }                       
         if (type==0)
            {
             longcount++;
            }
         if (type==1)
            {
             shortcount++;
            }
         }
      }
     
    MovingAve=iMA(NULL,0,PeriodMA,0,0,0,0);   //Calculate the MA Value...

//------------------------------------------------- LONG LOOP ---------------------------------------------------

    if (Bid>MovingAve&&longcount==0)     // If Price is above Moving average & I'm not already long...
         {
          if(longcount==0&&ticketlong==-1)      // If I'm not already long... (i assign -1 to "ticketlong" after i close a long order)
            {
             MyNumOfLots=NumOfLots(EquityPerLot);      // Calculates No. of lots based on Equity
             ticketlong=OrderSend(Symbol(),OP_BUY,MyNumOfLots,Ask,slippage*Point,0,0,"My buy order",magic,0,Green); // Open order...
             if(ticketlong>-1)   // If order was opened...           
               {
                if(OrderSelect(ticketlong,SELECT_BY_TICKET,MODE_TRADES)) 
                Alert(Symbol(),": LONG opened:",OrderOpenPrice(),", Ticket:",ticketlong);       
               }            
             else    // Order didnt open... why? & try fix...
             Error_Long=ErrorBlock(GetLastError());
            }
         } 

hi V,

i have adjusted my code as above and the count function at the top works great, my EA wont go long on same symbol if im already long...

however, an "alien 2nd order" still seems to slip its way in somehow...

i suspect its in the milliseconds between ordersend going to the server and ordersend returning the ticket number to "ticketlong", i think its sending 2 ordersends and then the EA is assigning the first returned ticket to my "ticketlong" variable and neglecting the second... the first is managed and closed when its stops are hit, but the first just sits there until i see it and close it manually.

my EA cannot get to ordersend if i'm already long, i have 2 safety nets in place "longcount==0" and "ticketlong==-1"... how is this happening?

do you think a sleep function after Ordersend will help?

Regards, M

 
miketinn:

hi V,

i have adjusted my code as above and the count function at the top works great, my EA wont go long on same symbol if im already long...

however, an "alien 2nd order" still seems to slip its way in somehow...

i suspect its in the milliseconds between ordersend going to the server and ordersend returning the ticket number to "ticketlong", i think its sending 2 ordersends and then the EA is assigning the first returned ticket to my "ticketlong" variable and neglecting the second... the first is managed and closed when its stops are hit, but the first just sits there until i see it and close it manually.

my EA cannot get to ordersend if i'm already long, i have 2 safety nets in place "longcount==0" and "ticketlong==-1"... how is this happening?

do you think a sleep function after Ordersend will help?

Regards, M

The EA will wait for a response at ordersend before executing the next line and it won't send 2 orders unless it is told to. Sleep won't change that fact and it won't run the ordersend line again until the next tick. By this time, you will have sent your order. longcount will read 1 and you therefore won't pass the if statement. the only thing I can think of is what is in the code for the error block function and lot sizing. The error function would be a good place to start as they often have methods to retry failed ordersend. As a first sugestion... put

err=GetLastError();

directly after the order send and then when you call your error block pass err.

Error_Long=ErrorBlock(err);

other than that it would be useful to see these two functions.

V

 

Noticed your ? in the comments about type>1...

https://docs.mql4.com/constants/trading

V

 
Viffer:

The EA will wait for a response at ordersend before executing the next line and it won't send 2 orders unless it is told to. Sleep won't change that fact and it won't run the ordersend line again until the next tick. By this time, you will have sent your order. longcount will read 1 and you therefore won't pass the if statement. the only thing I can think of is what is in the code for the error block function and lot sizing. The error function would be a good place to start as they often have methods to retry failed ordersend. As a first sugestion... put

directly after the order send and then when you call your error block pass err.

other than that it would be useful to see these two functions.

V


//----------------------------------------------- MY FUNCTION # 7 ------------------------------------------------------------
//------------------------------------ Calculates No. of lots based on Equity ------------------------------------------------
double NumOfLots(double Equity)
   {//
    double Real=(AccountEquity( )/Equity);  //
    double Round=MathRound(Real);   // rounds off answer
    double iNumOfLot=(Round*0.1);   // multilplies answer by 0.1 lots
    return(iNumOfLot);
   }//
Error function is still work in progress, as the error's come up in demo trading I add in the solution... so far I have only had these
//----------------------------------------------- MY FUNCTION # 8 ------------------------------------------------------------
//--------------------------------------------- Processing Errors ------------------------------------------------
int ErrorBlock(int err)
   {//
   switch(err)
      {//
       case 0: // No Error
         return(0);   // No Error
         break;
       case 6: // Error No connection
         Alert(Symbol(),": Error ",err,", No Connection");
         Sleep(60000);  // 
         return(1);   // Return(1) will make program retry sending the order it was trying
         break;
       case 138: 
         Alert(Symbol(),": Error ",err,", Refreshing rates"); 
         RefreshRates(); 
         return(1);   // Return(1) will make program retry sending the order it was trying
         break;
       default: 
         Alert(Symbol(),": Error ",err," not allowed for yet"); // not coded yet
         return(1);   // Return(1) will make program retry sending the order it was trying
      }//
   }//
//----------------------------------------------------------------------------------------------------------------------------
Regards,