error 130 even with market orders?

 

I'm going crazy, I think I checked all google results on how to avoid error 130 but still... hope somebody can point me in the right direction

here's the function I use to send orders:

-order without Stoploss (0 for longs, 99999 for shorts, actual stoploss to be added only after the order is accepted) to avoid 130 coming from that side

-it tries iteratively to enter with a limit order a couple pips away, but if Ask/bid reach my entry price then tries a market order at Ask or Bid, in case of error 130 sleeps a while, refreshes rates and tries again with limit or market order, same logic

-Stoplevel + spreads are already included in actual SL distance, but at the moment SL is only a subsequent modification of the trade, I never get there

-NL = NormalizeLots, ND = NormalizeDigits

-it logs everything at every cycle, see the log below

void RobustOrderSend(string sym, int tradedir, double lots, double ep, double sl, double tp, string desc, int magicno)
{

  int otyp;
  int tkt = -1;
  double minLot = MarketInfo(sym, MODE_MINLOT);
  if(NL(lots)<minLot)
  {
    loggerAdd(_Log,(string)Time[0]+sym+" lots "+(string)NL(lots)+"< MINLOT "+(string)minLot, clrRed);
    return;
  }
  
  int maxAttempts = 500;
  int i;
  for(i = 1; i < maxAttempts && tkt<0; i++)
  {
    RefreshRates();

    double price =  ND(ep);
    if(tradedir>0 && Ask>=price) {otyp = OP_BUY; price = Ask;} else otyp = OP_BUYSTOP; 
    if(tradedir<0 && Bid<=price) {otyp = OP_SELL; price = Bid;} else otyp = OP_SELLSTOP;

    // 130 !!!
    double slMod = tradedir> 0 ? 0 : 99999;
            
    tkt = OrderSend(sym, otyp, NL(lots), price, 3, ND(slMod), ND(tp), desc, magicno);
    if(tkt < 0)
    {
      int _GetLastError = GetLastError();
      if(i>0)
      {
        string AskBid = tradedir>0 ? " Ask "+(string)Ask : " Bid "+(string)Bid;
        loggerAdd(_Log, (string)Time[0]+" Error OrderSend  "+sym+" #"+(string)_GetLastError+" lots "+(string)NL(lots)+ 
                                        " @ "+(string)(price)+" TP "+(string)ND(tp)+" SL "+(string)ND(sl)+AskBid+
                                        " attempt "+(string)i, clrRed);
      }
      if( _GetLastError==130) // Off quotes or Invalid stops
      {
        if(i>0)
        {
           double stopLevelPts = MarketInfo(sym, MODE_STOPLEVEL);
           double spreadPts = MarketInfo(sym, MODE_SPREAD);
           loggerAdd(_Log,(string)Time[0]+" Stop Level "+sym+" "+(string)stopLevelPts+" Spread "+(string)spreadPts+
                          " slDelta "+(string)(MathAbs(price-NP(sl)))+
                          " tpDelta "+(string)(MathAbs(price-NP(tp))), clrRed); 
        }      
        Sleep(3000);
      }
    }
    else
    {
       loggerAdd(_Log, (string)Time[0]+" Order Sent "+sym+" lots "+(string)NL(lots)+" @ "+dts(price)+" ep "+dts(ep)+" tiket "+(string)tkt+" @attempt"+(string)i, clrGreen);
       if(sl != slMod)
         RobustOrderModify(sym, tkt, price, ND(sl), ND(tp), " adding SL after OrderSend");

       break;
    }
  }       
   
}

Here's an example of the log

tryng to enter at 0.66934

Ask is initially 0.66932 but after some  iterations (at 436) goes beyond my (buy) entry price, and then you can see that the entry price follows the ask to 0.66934, but the ordersend still gives 130...

SLDelta tracks the distance between entry price and Stoploss, but as I said that's for later modification of the ticket 

Stoplevel is 60 points, spread 6 or 9 points, limit entry price is closer than that, but then why I can't enter with market order?

2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66934 TP 99999 SL 0.66854 Ask 0.66932 attempt 434
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008000000000000229 tpDelta 99998.33066000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66934 TP 99999 SL 0.66854 Ask 0.66933 attempt 435
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 6 slDelta 0.0008000000000000229 tpDelta 99998.33066000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66934 TP 99999 SL 0.66854 Ask 0.66934 attempt 436
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008000000000000229 tpDelta 99998.33066000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66934 TP 99999 SL 0.66854 Ask 0.66934 attempt 437
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008000000000000229 tpDelta 99998.33066000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66934 TP 99999 SL 0.66854 Ask 0.66934 attempt 438
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008000000000000229 tpDelta 99998.33066000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66934 TP 99999 SL 0.66854 Ask 0.66934 attempt 439
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008000000000000229 tpDelta 99998.33066000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66934 TP 99999 SL 0.66854 Ask 0.66934 attempt 440
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008000000000000229 tpDelta 99998.33066000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66934 TP 99999 SL 0.66854 Ask 0.66934 attempt 441
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008000000000000229 tpDelta 99998.33066000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66934 TP 99999 SL 0.66854 Ask 0.66934 attempt 442
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008000000000000229 tpDelta 99998.33066000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66935 TP 99999 SL 0.66854 Ask 0.66935 attempt 443
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008099999999999774 tpDelta 99998.33065000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66935 TP 99999 SL 0.66854 Ask 0.66935 attempt 444
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008099999999999774 tpDelta 99998.33065000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66935 TP 99999 SL 0.66854 Ask 0.66935 attempt 445
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008099999999999774 tpDelta 99998.33065000002
2020.02.19 06:35:00 Error OrderSend  AUDUSD #130 lots 0.98 @ 0.66936 TP 99999 SL 0.66854 Ask 0.66936 attempt 446
2020.02.19 06:35:00 Stop Level AUDUSD 60 Spread 9 slDelta 0.0008199999999999319 tpDelta 99998.33064000001

Thanks in advance

Luigi

 

It has been discussed so many times. I hope you searched on the forum at least.

In your log we can't see the order type. Are they market orders or pending orders? Seems like market orders but then, on attempt 434, for example, why is the 'ask' different of the 'price' ?

What is the ND() code ?

 

Hi Alain, thanks for replying, I certainly searched the forum, as I stated I read almost all google results for error 130...

And you're right I planned on changing the logging code to be 200% sure I was entering market orders, but if you look below at this particular snippet of the code I'm confident (but may be wrong) I'm going with market orders as soon as the price goes beyond my planned entry price

at attempt 434 (and all attempts before) the Ask is still below my planned entry price (I try to enter beyond the close of the setup bar, for confirmation), so I'm still trying to enter with a limit order (failing because too close to Ask) at attempt 436 Ask reaches planned entry price, order type should change to market order (see below) but no trade :(


ND is NormalizeDouble with default Digits() (rewrote the function for brevity)


 double price =  ND(ep);
 if(tradedir>0 && Ask>=price) {otyp = OP_BUY; price = Ask;} else otyp = OP_BUYSTOP; 
 if(tradedir<0 && Bid<=price) {otyp = OP_SELL; price = Bid;} else otyp = OP_SELLSTOP;
Documentation on MQL5: Constants, Enumerations and Structures / Codes of Errors and Warnings / Compilation Errors
Documentation on MQL5: Constants, Enumerations and Structures / Codes of Errors and Warnings / Compilation Errors
  • www.mql5.com
Constants, Enumerations and Structures / Codes of Errors and Warnings / Compilation Errors - Reference on algorithmic/automated trading language for MetaTrader 5
 
luigisimoncini:

Hi Alain, thanks for replying, I certainly searched the forum, as I stated I read almost all google results for error 130...

And you're right I planned on changing the logging code to be 200% sure I was entering market orders, but if you look below at this particular snippet of the code I'm confident (but may be wrong) I'm going with market orders as soon as the price goes beyond my planned entry price

at attempt 434 (and all attempts before) the Ask is still below my planned entry price (I try to enter beyond the close of the setup bar, for confirmation), so I'm still trying to enter with a limit order (failing because too close to Ask) at attempt 436 Ask reaches planned entry price, order type should change to market order (see below) but no trade :(


ND is NormalizeDouble with default Digits() (rewrote the function for brevity)


The ask in your log is the one before your OrderSend(), and as you have
otyp = OP_BUY; price = Ask;

If it was a market order, the price should be equal to ask. So my hypothesis is it's actually not a market order but a pending order which is too close to the market.

Sorry but I can't help without more information. Improve your log the include all relevant information. Add the order type, the 'ep' value, the bid AND the ask (in all cases), before AND after your OrderSend(). To get the updated Bid/Ask after your OrderSend() use RefreshRates().

 
Ask and Bid do belong to the current chart symbol, but your function is working with the string sym. You need to make sure to get the right ask/bid values with SymbolInfoTick(sym,...) or something similar .
 

@Alain Verleyen thank you, I enriched the log, it will surely help

@lippmaje correct, the original code was meant to be more general, but I'm always using it on the current chart symbol. True that the extensions I made are not as general, will fix it

Also: today I also found an error 136 and searching the forum lead me to think that also the way I set my slippage at just "3" may be incorrect (was never a problem with Oanda... puzzling...) 

tkt = OrderSend(sym, otyp, NL(lots), price, 3, ND(slMod), ND(tp), desc, magicno);

changed according to another suggestion I read there from WHROEDER, this is now SlippagePips * pips2points where SlippagePips =2 and pips2points is computed in init() to take into account the number of digits for the current pair. Just saying, maybe I'll catch 2 birds (136+130) with just this stone...

 
luigisimoncini:

@Alain Verleyen thank you, I enriched the log, it will surely help

@lippmaje correct, the original code was meant to be more general, but I'm always using it on the current chart symbol. True that the extensions I made are not as general, will fix it

Also: today I also found an error 136 and searching the forum lead me to think that also the way I set my slippage at just "3" may be incorrect (was never a problem with Oanda... puzzling...) 

changed according to another suggestion I read there from WHROEDER, this is now SlippagePips * pips2points where SlippagePips =2 and pips2points is computed in init() to take into account the number of digits for the current pair. Just saying, maybe I'll catch 2 birds (136+130) with just this stone...

The slippage parameter is in points, so a value of 3 is correct, but of course that means some orders can be rejected if you broker is using Instant execution. There is no need to use a pips2points here.
 

Thank you Alain!!! The extended logging did the trick, I was seeing a Sell stop order when expecting a buy, due to this piece of code

 if(tradedir>0 && Ask>=price) {otyp = OP_BUY; price = Ask;} else otyp = OP_BUYSTOP; 
 if(tradedir<0 && Bid<=price) {otyp = OP_SELL; price = Bid;} else otyp = OP_SELLSTOP;

the program always went thru the second else even for long trades (tradedir>0) whenever Bid > price

as always, great contribution! 

 
luigisimoncini:

Thank you Alain!!! The extended logging did the trick, I was seeing a Sell stop order when expecting a buy, due to this piece of code

the program always went thru the second else even for long trades (tradedir>0) whenever Bid > price

as always, great contribution! 

Right, I had missed that too.
Reason: