Problem with OrderSend and OrderClose

 

Hello


I'm writing my first EA and it includes and SMA. If it crosses, I just want it to close the old order(if there is one) and open the new order in the right direction. I tested it and improved it, but the EA opens the new position and doesn't close the old one. Here my codes:


The one to close the sell-order and to buy:


if (OrderSelect(i-1,SELECT_BY_POS)==true)
       {
        Lot=OrderLots();
        Ticket=OrderTicket();
        OrderClose(Ticket,Lot,OrderClosePrice(),10);      
       }
      Lot=1;
      OrderSend(Symbol(),OP_BUY,Lot,Ask,10,0,0);


The one to close the buy-order and to sell:

if (OrderSelect(i-1,SELECT_BY_POS)==true)
       {
        Lot=OrderLots();
        Ticket=OrderTicket();
        OrderClose(Ticket,Lot,OrderClosePrice(),10);             
       }
      Lot=1;
      OrderSend(Symbol(),OP_SELL,Lot,Bid,10,0,0);     



Could you please help me to fix my problem? Thank you!


Manag

 

Maybe you have a problem with the index in OrderSelect(), if u r selecting the first order then in your case u should have i=1 (indexing starts at zero). Also, make sure variable Lot is of type double.

 

Now I have a new code:


if(ind!=0)
         art=ind;
    if(test==0)
         test=art;
    Tick++;          
    if(art==-1 && test==1)
     {
      Alert("Tick: ",Tick);
      test=-1;
      
      if (OrderSelect(0,SELECT_BY_POS)==true)
            if(OrderType()==OP_BUY)
                  {
                   OrderClose(OrderTicket(),OrderLots(),Bid,10);      
                   OrderSend(Symbol(),OP_SELL,1,Ask,3,0,0);
                  }
     }                  
 
    if(art==1 && test==-1)
     {
      Alert("Tick: ",Tick);
      test=1;
      if (OrderSelect(0,SELECT_BY_POS)==true)
            if(OrderType()==OP_SELL)
                  {
                   OrderClose(OrderTicket(),OrderLots(),Ask,3);    
                   OrderSend(Symbol(),OP_BUY,1,Bid,3,0,0);
                  }
      }
    return(0);

I used "test"and "ind" to generate a buy or sell signal of the position to the chart changes.

But it doesn't open an order, because at the beginning, none is opened. Could you help me that I can open the first order that it continues?


Thank you!


Manag

 
Manag:

I used "test"and "ind" to generate a buy or sell signal of the position to the chart changes.

But it doesn't open an order, because at the beginning, none is opened. Could you help me that I can open the first order that it continues?

Do something like this for first order:

   static bool first_order = false;
   if ( first_order == false )
      {
      if ( opening criterion's... )
         int ticket = OrderSend(...);
      
      if ( ticket > 0 )
         first_order = true;
      }

Edit: this example is a bit simplified - doesn't take into account running multiple experts or a Terminal restart.

 

Ok, thank you, now it works and it looks like this:


if(art==1 && test==-1)
     {
      test=1;
      if (OrderSelect(0,SELECT_BY_POS)==true)
            if(OrderType()==OP_SELL)
                  {
                   OrderClose(OrderTicket(),OrderLots(),Ask,3);    
                   OrderSend(Symbol(),OP_BUY,1,Bid,10,0,0);
                  }
      if ( first_order == false )
      {
       Ticket=OrderSend(Symbol(),OP_BUY,1,Bid,10,0,0);
       if ( Ticket > 0 )
         first_order = true;     
      }                         
     }


As you can see, the slippage is 10 and very high. My Problem is, if I choose a lower one, the strategy test always tells me that there is an order send error 138. I just know that it means "requote", but I'm not an English native speaker and I don't know what it means! Can you please tell me? And what can i do that I can use a slippage of about 2 or 3?


Manag

 

You must also issue a RefreshRates() between orderClose and orderSend

If you are using a 5 digit broker then slippage is one pip not ten there.

//++++ These are adjusted for 5 digit brokers.
double  pips2points,    // slippage  3 pips    3=points    30=points
        pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
int init() {
    if (Digits == 5 || Digits == 3) {   // Adjust for five (5) digit brokers.
                pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
    } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0;
    }
//...
OrderSend(Symbol(),OP_BUY,1,Bid,10*pips2points,0,0);

I wouldn't use

if ( first_order == false ) 

Since if the trader is restarted, you'll be opening a second order. Use if (OrdersTotal()==0) if you are certain there will NEVER be any other opened orders. Otherwise, find out what orders belongs to the EA

    for(int index = OrdersTotal() - 1; index >= 0; index--) if (
        OrderSelect(index, SELECT_BY_POS)                   // Only my orders w/
    &&  OrderMagicNumber()  == MagicNumber + Period.index   // my magic number
    &&  OrderSymbol()       == Symbol() ) {             // and period and symbol

    // if test close and open
       return;
    }
    // No open orders, open one new one.
 
Manag:

As you can see, the slippage is 10 and very high. My Problem is, if I choose a lower one, the strategy test always tells me that there is an order send error 138. I just know that it means "requote", but I'm not an English native speaker and I don't know what it means! Can you please tell me? And what can i do that I can use a slippage of about 2 or 3?

Slippage informs the broker that he can open the order within +/- slippage points of the requested price. In certain cases, when prices are moving fast, by the time the request reaches the server the price might have moved MORE than slippage points away from the requested price, in that case the broker returns a requote error (138).

Obviously the larger the slippage, the less likely to be requoted. But then the opening price might be very far from the requested price... How big a slippage should rely on the expert's trading strategy. Some experts require more accuracy in placing orders than others.


Requotes differ among different brokers. Some brokers will work well with small slippage while others need larger. Some brokers (usually the ones that are 'ECN') ignore slippage completely and promise to give u 'the best available price at the time' (but they clearly state this in their website).

If u r using a 5 digit broker, then a slippage of 2-3 points is usually a bit small, 5 would be better and with 10 u r likely to have very few requotes (IMHO ...this is from my personal experience, but as I said, brokers differ).


p.s. WHRoeder is right about my example, it's a bit simplified - doesn't take into account running multiple experts or a Terminal restart. See his example for more details.

 
thank you very much, now my EA works :-)
 

But now I have the same problem again and I don't understand it...I still use this code:


if(art==-1 && test==1)
     {
      test=-1;
      
      if (OrderSelect(0,SELECT_BY_POS)==true)
            if(OrderType()==OP_BUY)
                  {
                   OrderClose(OrderTicket(),OrderLots(),Bid,10);      
                   OrderSend(Symbol(),OP_SELL,1,Ask,10,0,0);
                  }
      if ( first_order == false )
      {
       Ticket=OrderSend(Symbol(),OP_SELL,1,Ask,10,0,0);
       if ( Ticket > 0 )
         first_order = true;     
      }                 
     }                  


But now, there is always an error 138 when it tries to open an order, also if I use 20 or 30 as slippage, only if I use 100 or more it works. I really don't understand why, yesterday it worked fine with a slippage of 10!

Can you help me?



Manag

 

Use "OrderClose ( OrderTicket (), OrderLots (), OrderClosePrice (), 0 ) ;" to close order

Use NormalizeDouble ( ) for prices to send order

Sample:


...     
extern string aes.Symbol             = "EURUSD"                                                     ; //<  41>
...     
int    avi.Digits                                                                                   ; //< 148>
...     
       avi.Digits  = MarketInfo      ( aes.Symbol , MODE_DIGITS                                   ) ; //< 413>
...     
{ avd.Price        = NormalizeDouble ( avd.QuoteBid                                  , avi.Digits ) ; //< 576>
  avd.Stop         = NormalizeDouble ( avd.Low.1                + avd.QuoteStop      , avi.Digits ) ; //< 577>
  avd.Take         = NormalizeDouble ( avd.QuoteBid             - avd.QuoteTake      , avi.Digits ) ; //< 578>
                                                                                                      //< 579>
  if               ( NormalizeDouble (                                                                //< 580>
                   ( avd.Price - avd.Take                     ) - avd.QuoteStops , avi.Digits ) > 0 ) //< 581>
  if               ( NormalizeDouble (                                                                //< 582>
                   ( avd.Stop  - avd.Price - avd.QuoteSpread  ) - avd.QuoteStops , avi.Digits ) > 0 ) //< 583>
       avi.Command = OP_SELL                                                                      ; } //< 584>
     
...     
      int ali.Ticket          = OrderSend          ( aes.Symbol    , avi.Command  , ald.Size      ,   //< 654>
                                avd.Price   ,  0   , avd.Stop      , avd.Take     , ""            ,   //< 655>
                                aci.OrderID ,  0   , 0                                            ) ; //< 656>
... 
  
 

Manag wrote >>

But now, there is always an error 138 when it tries to open an order, also if I use 20 or 30 as slippage, only if I use 100 or more it works. I really don't understand why, yesterday it worked fine with a slippage of 10!

Can you help me?

I recommend u go over Roeder's notes. One of the things he said is that u need RefreshRates() between orderClose and orderSend, without it u might be attempting to open an order with an old price. That would cause error 138 (requote).


p.s. You realize market is closed now...?

Reason: