Invalid stops error.

 
Hi,

I used to use tighest SL at MarketInfo(symbol, MODE_STOPLEVEL)+STOPLEVEL_OFFSET)*Point; where STOPLEVEL_OFFSET used to be 1. However, from some time it does not work anymore for market orders. I must set STOPLEVEL_OFFSET to 2. Strange is, that it still works for pending orders, ie with offset 1. Is this a feature or a bug? Why this difference?

Regards,

Michal
 
Price can be changed. Stops calculated from the price.
 
Price can be changed. Stops calculated from the price.

Can price change when there is no movement on the chart? Just run the attched script and see it for yourself.
#define STOPLEVEL_OFFSET 1
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   OrderSendExt(Symbol(), OP_BUY, 0.1, Ask, 3, Ask-Point,Ask+Point,"OrderSendExt",0,0,Blue);
   OrderSendExt(Symbol(), OP_BUYLIMIT, 0.1, Ask-20*Point, 3, Ask-21*Point,Ask-19*Point,"OrderSendExt",0,0,Blue);
//----
   return(0);
  }
  
int OrderSendExt( string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit,
                  string comment="", int magic=0, datetime expiration=0, color arrow_color=CLR_NONE)
{
  // Extended OrderSend with Stops and Error support:
  // Check stop
  double stop_level = (MarketInfo(symbol, MODE_STOPLEVEL)+STOPLEVEL_OFFSET)*Point;
  double market = 0.0;
  bool cont  = true;
  bool retry = false;
  int  retries = 0;

  //MathSrand(CurTime());
  Print(" Order: @", DoubleToStr(price,Digits),
            " slippage: ", slippage," SL: ",DoubleToStr(stoploss,Digits)," TP: ",DoubleToStr(takeprofit,Digits)," level: ",
            DoubleToStr(stop_level-Point,Digits));
  while(cont){
    switch(cmd)
    { case OP_BUYLIMIT:
      case OP_BUYSTOP:
      case OP_BUY : if(retry && price > Ask) price = Ask;
                    if(price-stoploss < stop_level) stoploss = price - stop_level;
                    if(takeprofit-price < stop_level) takeprofit = price + stop_level;
                    break;
      case OP_SELLLIMIT:
      case OP_SELLSTOP:
      case OP_SELL: if(retry && price < Bid) price = Bid;
                    if(stoploss-price < stop_level) stoploss = price + stop_level;
                    if(price-takeprofit < stop_level) takeprofit = price - stop_level;
      default:      break;
    }

    int ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, 
                           comment, magic, expiration, arrow_color);
    int err = GetLastError();
    if(ticket < 0){
      RefreshRates();
      if(cmd == OP_BUY)
        market = Ask;
      else
        market = Bid;
      Print(symbol, " OrderSend failed with error #",ErrorDescription(err),
            " Order: @", DoubleToStr(price,Digits), " Market: @", DoubleToStr(market,Digits),
            " slippage: ", slippage," SL: ",DoubleToStr(stoploss,Digits)," TP: ",DoubleToStr(takeprofit,Digits)," level: ",
            DoubleToStr(stop_level-Point,Digits));
    }else
      cont = false;
    if(err == 146){ // Trade conetx busy
      int ms = 250;//MathRound(MathRand()/10);
      Print(symbol, " Sleeping for ", ms, " ms");
      Sleep(ms); // sleep between 0 and 3.2767 sec
      RefreshRates();
    }else
      cont = false;
    retry = true;

    if(retries >= 2) 
      return(ticket);
    else
      retries++;
  }
  return(ticket);
}
 
Stops are calculated from close price not from open
 
It's easy. If You get some error then print current bid, ask and stops, then RefreshRates, then print bid and ask. And analyze printed values

Exactly what the script does. So please analyze this line for me, because my analysis is in the first post. Is it bug or the feature? I don't understand why stops are invalid now.

2006.06.23 12:50:42 SendOrderExt AUDUSD,M1: AUDUSD OrderSend failed with error #invalid stops Order: @0.7324 Market: @0.7324 slippage: 3 SL: 0.7318 TP: 0.7330 level: 0.0005
 
Stops are calculated from close price not from open

What this mean now? Which price open? I use Ask and Bid arrays like always.
 
your code
      case OP_BUY : if(retry && price > Ask) price = Ask;
                    if(price-stoploss < stop_level) stoploss = price - stop_level;
                    if(takeprofit-price < stop_level) takeprofit = price + stop_level;
...
   int ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, 
                           comment, magic, expiration, arrow_color);


in this case stoploss and take profit are calculated from open price named price
try to calculate your stoplos from bid (your position will be closed by bid price)

stoploss=Bid-stop_level;


 
your code
      case OP_BUY : if(retry && price > Ask) price = Ask;
                    if(price-stoploss < stop_level) stoploss = price - stop_level;
                    if(takeprofit-price < stop_level) takeprofit = price + stop_level;
...
   int ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, 
                           comment, magic, expiration, arrow_color);


in this case stoploss and take profit are calculated from open price named price
try to calculate your stoplos from bid (your position will be closed by bid price)

stoploss=Bid-stop_level;




No joy (I have spread 2 pips by MIG on this instument). Can you analyze this line for me?

2006.06.23 14:36:55 SendOrderExt AUDUSD,H1: AUDUSD OrderSend failed with error #invalid stops Order: @0.7310 Market: @0.7310 slippage: 3 SL: 0.7302 TP: 0.7314 level: 0.0005

Maybe I was not clear. This code used to work for 8 months. Sudenly it stopped. Adding 1 more point to stoplevel solves the problem. For pending orders is does work. My question is not why it is now 2 instead of 1 but why it is different for market orders and for pending orders.
 

Error still exists in 195. Why do I need 2 pips extra offset for market order and only 1 for pending order? Where this difference comes from?
 
Please see my post at 23.06.06 16:24.

Stops should be calculated from close price not from open price!
Reason: