OrderSend error 3 for SELLSTOP and BUYSTOP in EA but order params are OK

 

Hello everybody,

I'm coding EA which generates SELLSTOP and BUYSTOP orders. When testing in strategy tester I often (not in all cases) receive error 3 "invalid trade parameters" although the parameters are IMHO correct. I added extensive logging into the EA to know all the parameters and here is what I get:

2012.06.01 19:21  XXXXX EURUSD,M5: INFO: Evaluating Sell Stop conditions. Bid-OpenPrice (>= StopLevel): 0.00059, SL-OpenPrice (>= StopLevel): 0.00110, OpenPrice-TP (>= StopLevel): 0.00110
2012.06.01 19:21  XXXXX EURUSD,M5: INFO: MarketInfo - Ask: 1.24425, Bid: 1.24413, StopLevel: 40.0(0.00040), FreezeLevel: 0.0(0.00000)
2012.06.01 19:21  XXXXX EURUSD,M5: INFO: OrderSend params - lots: 0.01000000, price: 1.24354, slippage: 1, SL: 1.24464, TP: 1.24244, expiration: 2012.06.01 19:31
2012.06.01 19:21  XXXXX EURUSD,M5: ERROR: Failed placing order, error: 3 invalid trade parameters
2012.06.01 19:21  XXXXX EURUSD,M5: OrderSend error 3

I checked all conditions described in documentation (Requirements and Limitations in Making Trades) and it seems that my order meets all the conditions for SELLSTOP:

Condition My values Condition Met
Open price must be below the current Bid (Price < Bid)1.24354 < 1.24413 Yes
Bid-OpenPrice ≥ StopLevel0.00059 ≥ 0.00040Yes
SL-OpenPrice ≥ StopLevel0.00110 ≥ 0.00040Yes
OpenPrice-TP ≥ StopLevel0.00110 ≥ 0.00040Yes
Bid-OpenPrice > FreezeLevel0.00059 > 0.00000Yes

So, what I'm missing, that the order doesn't go through? I already searched the forums and google, but didn't find the answer :(

Thanks for help!

 
So you send order in strategy tester that expire 10 minutes later ?, try expiration = 0 ;)
 

Well, when setting the expiration to 0, then it works. But in some cases it works even when I set the expiration to 10 minutes. I experimented a little and found, that even with 11 minutes expiration all orders are placed.

It is very weird: how can I know what value is "acceptable" and what is not? Is it a bug or feature? Is it done by MT4 or by broker's setting?

Moreover, this is a wanted behaviour of the EA - it works on M5 chart and when the trend is not confirmed on the two following bars, then the pending order should be removed, so I need to get it working or live with 11 minutes :)

Anyway, thanks for hint!

 
dded:

So, what I'm missing, that the order doesn't go through? I already searched the forums and google, but didn't find the answer :(

You need to show your code if you want a reasonably accurate answer . . . I don't believe it's an Expiration issue . . .
 

OK, I'll try to show ... the code is pretty long, thus I'll concentrate on the main piece.

The function placing the order is:

//+------------------------------------------------------------------+
//| Place order with given parameters (TP, SL are absolute values)   |
//+------------------------------------------------------------------+ 
int PlaceOrderAbs(int Type, double Lots, double Price, int Slippage, double StopLoss, double TakeProfit, string Name, bool TakeCare = false, int HoldSeconds = 0, datetime Expire=0, int MagicNr=0)
{
   PrintInfo("PlaceOrderAbs params - Type:",Type,", Lots:",Lots,", Price: ",Price,", Slippage: ", Slippage,", SL: ",StopLoss," TP: ",TakeProfit,", HoldSeconds: ",HoldSeconds,", Expire: ",TimeToStr(Expire));
   // choose color for the arrow
   color ArrowColor = PickArrowColor(Type);
   double MinStopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL);
   double marketTakeProfit, marketStopLoss;
   if(TakeProfit == 0.0)
      marketTakeProfit = 0.0;
   else
      marketTakeProfit = AdjustStopLevel(MathAbs(TakeProfit - Price) / Point * MathPow(10, 4 - Digits), true, false);
   if(StopLoss == 0.0)
      marketStopLoss = 0.0;
   else
      marketStopLoss = AdjustStopLevel(MathAbs(StopLoss - Price) / Point * MathPow(10, 4 - Digits), true, false);
   if((Type == OP_BUY) || (Type == OP_BUYLIMIT) || (Type == OP_BUYSTOP)) {
      // if buying we want to deduct the stop loss value from price
      if(marketStopLoss != 0.0) marketStopLoss = - marketStopLoss;
   } else {
      // if selling we want to deduct the take profit value from price
      if(marketTakeProfit != 0.0) marketTakeProfit = - marketTakeProfit;
   }
   // place order
   if(marketStopLoss != 0.0) marketStopLoss += Price;
   if(marketTakeProfit != 0.0) marketTakeProfit += Price;
   int ticket = OrderSend(Symbol(), Type, Lots, Price, Slippage, marketStopLoss, marketTakeProfit, Name, MagicNr, Expire, ArrowColor);
//   int ticket = 0;
   // verify order placement
   if(ticket > 0) {
      if(OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
         OrderPrint();
      else
         PrintWarning("Order #",ticket," opened, but now not found by OrderSelect",GetErrString());
      if(TakeCare) { // the EA wants the library to take care of the order
         //add order into arrays for orders watching
         TakeCare(ticket, Slippage, StopLoss, TakeProfit, HoldSeconds);
      }
   } else {
      int Err = GetLastError();
      if((Err == ERR_INVALID_STOPS) && ((marketStopLoss != 0.0) || (marketTakeProfit != 0.0))) {
         //we are possibly connected to ECN account, where stoploss and takeprofit cannot be set in OrdedSend but later by OrderModify
         PrintInfo("Order not placed, but probably on ECN account, trying alternative order placement ...");
         ticket = PlaceOrderAbs(Type, Lots, Price, Slippage, 0.0, 0.0, Name, TakeCare, MagicNr, Expire);
         if(ticket > 0) { // second order send succesfull, try set stopLoss and takeProfit
            if(!OrderModify(ticket, Price, marketStopLoss, marketTakeProfit, Expire, ArrowColor)) { // order modification failed
               if(!TakeCare) { // the library is not controlling the stop loss and take profit for the caller, notify user
                  Alert("Order #",ticket," placed, but stop loss and take profit not set, control the position manually!"); 
                  PrintError("Order #",ticket," placed, but stop loss and take profit not set, control the position manually!");
               } else {
                  PrintWarning("Order #",ticket," placed, but stop loss and take profit not set, conditions will be controlled by EA",GetErrString());
               }
            }
            TakeCare(ticket, Slippage, StopLoss, TakeProfit, HoldSeconds);
         }
      } else {
         PrintError(Err, "Failed placing order");
         if(LogLevel >= LogLevelInfo) {
            PrintInfo("OrderSend params - lots: ",Lots,", price: ",DoubleToStr(Price, Digits),", slippage: ",Slippage,", SL: ",DoubleToStr(marketStopLoss, Digits),", TP: ",DoubleToStr(marketTakeProfit, Digits),", expiration: ",TimeToStr(Expire));
            PrintInfo("MarketInfo - Ask: ",DoubleToStr(Ask, Digits),", Bid: ",DoubleToStr(Bid, Digits),", StopLevel: ",DoubleToStr(MarketInfo(Symbol(),MODE_STOPLEVEL), 1),"(",DoubleToStr(MarketInfo(Symbol(),MODE_STOPLEVEL)*Point, Digits),"), FreezeLevel: ",DoubleToStr(MarketInfo(Symbol(),MODE_FREEZELEVEL), 1),"(",DoubleToStr(MarketInfo(Symbol(),MODE_FREEZELEVEL)*Point, Digits),")");
            switch(Type)
            {
               case OP_BUY:
                  PrintInfo("Evaluating Buy conditions. Price == Ask, Bid-SL (>= StopLevel): ",DoubleToStr(Bid-marketStopLoss, Digits),", TP-Bid (>= StopLevel): ",DoubleToStr(marketTakeProfit-Bid, Digits));
                  break;
               case OP_SELL:
                  PrintInfo("Evaluating Sell conditions. Price == Bid, SL-Ask (>= StopLevel): ",DoubleToStr(marketStopLoss-Ask, Digits),", Ask-TP (>= StopLevel): ",DoubleToStr(Ask-marketTakeProfit, Digits));
                  break;
               case OP_BUYLIMIT:
                  PrintInfo("Evaluating Buy Limit conditions. Ask-OpenPrice (>= StopLevel): ",DoubleToStr(Ask-Price, Digits),", OpenPrice-SL (>= StopLevel): ",DoubleToStr(Price-marketStopLoss, Digits),", TP-OpenPrice (>= StopLevel): ",DoubleToStr(marketTakeProfit-Price, Digits));
                  break;
               case OP_SELLLIMIT:
                  PrintInfo("Evaluating Sell Limit conditions. OpenPrice-Bid (>= StopLevel): ",DoubleToStr(Price-Bid, Digits),", SL-OpenPrice (>= StopLevel): ",DoubleToStr(marketStopLoss-Price, Digits),", OpenPrice-TP (>= StopLevel): ",DoubleToStr(Price-marketTakeProfit, Digits));
                  break;
               case OP_BUYSTOP:
                  PrintInfo("Evaluating Buy Stop conditions. OpenPrice-Ask (>= StopLevel): ",DoubleToStr(Price-Ask, Digits),", OpenPrice-SL (>= StopLevel): ",DoubleToStr(Price-marketStopLoss, Digits),", TP-OpenPrice (>= StopLevel): ",DoubleToStr(marketTakeProfit-Price, Digits));
                  break;
               case OP_SELLSTOP:
                  PrintInfo("Evaluating Sell Stop conditions. Bid-OpenPrice (>= StopLevel): ",DoubleToStr(Bid-Price, Digits),", SL-OpenPrice (>= StopLevel): ",DoubleToStr(marketStopLoss-Price, Digits),", OpenPrice-TP (>= StopLevel): ",DoubleToStr(Price-marketTakeProfit, Digits));
                  break;
            }
         }
      }
   }
   return(ticket);
}

On the same input in the same point in time it behaves consistently all times (I tried it 20 times at least).

Here is a log sample, when it places the pending order:

2012.06.12 18:12  XXXXX EURUSD,M5: #2 2012.06.12 18:12 sell stop 0.01 EURUSD 1.24982 1.25049 1.24915 0.00000 0.00 0.00 0.00 PivotAllSell 0 expiration 2012.06.12 18:23
2012.06.12 18:12  XXXXX EURUSD,M5: open #2 sell stop 0.01 EURUSD at 1.24982 sl: 1.25049 tp: 1.24915 ok
2012.06.12 18:12  XXXXX EURUSD,M5: INFO: MarketInfo - Ask: 1.25039000, Bid: 1.25029000, StopLevel: 40.0(0.00040000), FreezeLevel: 0.0(0.00000000)
2012.06.12 18:12  XXXXX EURUSD,M5: INFO: PlaceOrderAbs params - Type:5, Lots:0.01000000, Price: 1.24982000, Slippage: 1, SL: 1.25049000 TP: 1.24915000, HoldSeconds: 6000, Expire: 2012.06.12 18:23
2012.06.12 18:12  XXXXX EURUSD,M5: INFO: Placing waiting SELL with SL: 1.25049000, TP: 1.24915000

And here is a log, when it fails to place the pending order:

2012.06.12 18:12  XXXXX EURUSD,M5: INFO: Evaluating Sell Stop conditions. Bid-OpenPrice (>= StopLevel): 0.00082, SL-OpenPrice (>= StopLevel): 0.00067, OpenPrice-TP (>= StopLevel): 0.00067
2012.06.12 18:12  XXXXX EURUSD,M5: INFO: OrderSend params - lots: 0.01000000, price: 1.24982, slippage: 1, SL: 1.25049, TP: 1.24915, expiration: 2012.06.12 18:22
2012.06.12 18:12  XXXXX EURUSD,M5: ERROR: Failed placing order, error: 3 invalid trade parameters
2012.06.12 18:12  XXXXX EURUSD,M5: OrderSend error 3
2012.06.12 18:12  XXXXX EURUSD,M5: INFO: MarketInfo - Ask: 1.25076000, Bid: 1.25064000, StopLevel: 40.0(0.00040000), FreezeLevel: 0.0(0.00000000)
2012.06.12 18:12  XXXXX EURUSD,M5: INFO: PlaceOrderAbs params - Type:5, Lots:0.01000000, Price: 1.24982000, Slippage: 1, SL: 1.25049000 TP: 1.24915000, HoldSeconds: 6000, Expire: 2012.06.12 18:22
2012.06.12 18:12  XXXXX EURUSD,M5: INFO: Placing waiting SELL with SL: 1.25049000, TP: 1.24915000

What is really suspicious to me is that a minute later on the same EA run, as was the previous unsuccessful attempt, it succeeded in placing the pending order:

2012.06.12 18:13  XXXXX EURUSD,M5: #1 2012.06.12 18:13 sell stop 0.01 EURUSD 1.24982 1.25049 1.24915 0.00000 0.00 0.00 0.00 PivotAllSell 0 expiration 2012.06.12 18:23
2012.06.12 18:13  XXXXX EURUSD,M5: open #1 sell stop 0.01 EURUSD at 1.24982 sl: 1.25049 tp: 1.24915 ok
2012.06.12 18:13  XXXXX EURUSD,M5: INFO: MarketInfo - Ask: 1.25086000, Bid: 1.25074000, StopLevel: 40.0(0.00040000), FreezeLevel: 0.0(0.00000000)
2012.06.12 18:13  XXXXX EURUSD,M5: INFO: PlaceOrderAbs params - Type:5, Lots:0.01000000, Price: 1.24982000, Slippage: 1, SL: 1.25049000 TP: 1.24915000, HoldSeconds: 6000, Expire: 2012.06.12 18:23
2012.06.12 18:13  XXXXX EURUSD,M5: INFO: Placing waiting SELL with SL: 1.25049000, TP: 1.24915000

As you can see the input parameters are the same except the Expire parameter.

I tried it only in strategy tester, not on demo account, but don't know if this can be a problem.

 
Sell Stop conditions. Bid-OpenPrice (>= StopLevel): 0.00082, SL-OpenPrice (>= StopLevel): 0.00067
OrderSend params - lots: 0.01000000, price: 1.24982, slippage: 1, SL: 1.25049, TP: 1.24915, 
Ask: 1.25076000, Bid: 1.25064000, StopLevel: 40.0(0.00040000)

On a Sell, the SL is relative to the Ask, not the open price (Bid). Your stop was below the Ask so invalid. It has to be 4.0 pips above the Ask.

On ECN brokers you must open first and THEN set stops. You may or may not get a 130 with pending orders nor can you test for a zero StopLevel. Why not always open with no SL and then set.

On ECN brokers you may not be able to set expiration.

Pending orders are useful for humans as they can't watch the screen 24/5. EA's can. Why don't you just wait for the market to reach your open price and then open. No expiration needed

 
RaptorUK:
You need to show your code if you want a reasonably accurate answer . . . I don't believe it's an Expiration issue . . .

Sorry for the wild goose chase . . . it's nice to see some code where errors are trapped and reported :-)

Perhaps it is an expiration issue after all . . .

https://www.mql5.com/en/forum/116782

https://www.mql5.com/en/forum/110244

https://www.mql5.com/en/forum/110952

definitive answer . . . https://www.mql5.com/en/forum/106796

alternative: https://www.mql5.com/en/forum/134079

 
WHRoeder:

On a Sell, the SL is relative to the Ask, not the open price (Bid). Your stop was below the Ask so invalid. It has to be 4.0 pips above the Ask.

That's not relevant for a SellStop though . . .
 

RaptorUK:

Thanks, I started to thing that there is a condition, which I didn't found in documentation. I only found conditions in the table in the first post ...

I'm rather a skilled programer than a skilled Forex trader, so code looks good, but the results are still poor :)))

WHRoeder:

Thanks for the hints regarding the code. I played a little with the possibilities of the MT4, so did some things in a pretty complex way :)

Reason: