How to deal with error 130?

 

Hello! I’ve been working on my EA for the past several months. Today, I finally reached the stage where I can start using the Strategy Tester. Unfortunately, I encountered an error. Since I am fairly new to trading commands, I searched the forum for general advice. Thanks to the courtesy of several forum members who uploaded their code in response to other users’ inquiries, I implemented the following functions in my code:

bool CheckStopLoss_Takeprofit(ENUM_ORDER_TYPE type,double price,double SL,double TP) {
//--- get the SYMBOL_TRADE_STOPS_LEVEL level
   int stops_level=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
   if(stops_level!=0) {
      PrintFormat("SYMBOL_TRADE_STOPS_LEVEL=%d: StopLoss and TakeProfit must"+
                  " not be nearer than %d points from the closing price",stops_level,stops_level);
     }
//---
   bool SL_check=false,TP_check=false;
//--- check the order type
   switch(type) {
      //--- Buy operation
      case OP_BUY:
        {
         //--- check the StopLoss
         SL_check=(Bid-SL>stops_level*_Point);
         if(!SL_check)
            PrintFormat("For order %s   StopLoss=%.5f must be less than %.5f"+
                        " (Bid=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),SL,Bid-stops_level*_Point,Bid,stops_level);
         //--- check the TakeProfit
         TP_check=(TP-Bid>stops_level*_Point);
         if(!TP_check)
            PrintFormat("For order %s   TakeProfit=%.5f must be greater than %.5f"+
                        " (Bid=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),TP,Bid+stops_level*_Point,Bid,stops_level);
         //--- return the result of checking
         return(SL_check&&TP_check);
        }
      //--- Sell operation
      case  OP_SELL:
        {
         //--- check the StopLoss
         SL_check=(SL-Ask>stops_level*_Point);
         if(!SL_check)
            PrintFormat("For order %s   StopLoss=%.5f must be greater than %.5f"+
                        " (Ask=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),SL,Ask+stops_level*_Point,Ask,stops_level);
         //--- check the TakeProfit
         TP_check=(Ask-TP>stops_level*_Point);
         if(!TP_check)
            PrintFormat("For order %s   TakeProfit=%.5f must be less than %.5f"+
                        " (Ask=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),TP,Ask-stops_level*_Point,Ask,stops_level);
         //--- return the result of checking
         return(TP_check&&SL_check);
        }
      break;
      //--- BuyLimit pending order
      case  OP_BUYLIMIT:
        {
         //--- check the StopLoss
         SL_check=((price-SL)>stops_level*_Point);
         if(!SL_check)
            PrintFormat("For order %s   StopLoss=%.5f must be less than %.5f"+
                        " (Open-StopLoss=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),SL,price-stops_level*_Point,(int)((price-SL)/_Point),stops_level);
         //--- check the TakeProfit
         TP_check=((TP-price)>stops_level*_Point);
         if(!TP_check)
            PrintFormat("For order %s   TakeProfit=%.5f must be greater than %.5f"+
                        " (TakeProfit-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),TP,price+stops_level*_Point,(int)((TP-price)/_Point),stops_level);
         //--- return the result of checking
         return(SL_check&&TP_check);
        }
      //--- SellLimit pending order
      case  OP_SELLLIMIT:
        {
         //--- check the StopLoss
         SL_check=((SL-price)>stops_level*_Point);
         if(!SL_check)
            PrintFormat("For order %s   StopLoss=%.5f must be greater than %.5f"+
                        " (StopLoss-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),SL,price+stops_level*_Point,(int)((SL-price)/_Point),stops_level);
         //--- check the TakeProfit
         TP_check=((price-TP)>stops_level*_Point);
         if(!TP_check)
            PrintFormat("For order %s   TakeProfit=%.5f must be less than %.5f"+
                        " (Open-TakeProfit=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),TP,price-stops_level*_Point,(int)((price-TP)/_Point),stops_level);
         //--- return the result of checking
         return(TP_check&&SL_check);
        }
      break;
      //--- BuyStop pending order
      case  OP_BUYSTOP:
        {
         //--- check the StopLoss
         SL_check=((price-SL)>stops_level*_Point);
         if(!SL_check)
            PrintFormat("For order %s   StopLoss=%.5f must be less than %.5f"+
                        " (Open-StopLoss=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),SL,price-stops_level*_Point,(int)((price-SL)/_Point),stops_level);
         //--- check the TakeProfit
         TP_check=((TP-price)>stops_level*_Point);
         if(!TP_check)
            PrintFormat("For order %s   TakeProfit=%.5f must be greater than %.5f"+
                        " (TakeProfit-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),TP,price-stops_level*_Point,(int)((TP-price)/_Point),stops_level);
         //--- return the result of checking
         return(SL_check&&TP_check);
        }
      //--- SellStop pending order
      case  OP_SELLSTOP:
        {
         //--- check the StopLoss
         SL_check=((SL-price)>stops_level*_Point);
         if(!SL_check)
            PrintFormat("For order %s   StopLoss=%.5f must be greater than %.5f"+
                        " (StopLoss-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),SL,price+stops_level*_Point,(int)((SL-price)/_Point),stops_level);
         //--- check the TakeProfit
         TP_check=((price-TP)>stops_level*_Point);
         if(!TP_check)
            PrintFormat("For order %s   TakeProfit=%.5f must be less than %.5f"+
                        " (Open-TakeProfit=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),TP,price-stops_level*_Point,(int)((price-TP)/_Point),stops_level);
         //--- return the result of checking
         return(TP_check&&SL_check);
        }
      break;
     }

//---
   return false;
  }
        bool CheckIfPriceAllowsToSendOrder(ENUM_ORDER_TYPE type) {
           RefreshRates();
           switch(type) {
              case OP_BUYLIMIT:
                 return entry.GetNormalizedPrice() < Ask;
              case OP_SELLLIMIT:
                 return entry.GetNormalizedPrice() > Bid;
              case OP_BUYSTOP:
                 return entry.GetNormalizedPrice() > Ask;
              case OP_SELLSTOP:
                 return entry.GetNormalizedPrice() < Bid;
           }
           return false;
        }
bool IsNewOrderAllowed()
  {
//--- get the number of pending orders allowed on the account
   int max_allowed_orders=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);

//--- if there is no limitation, return true; you can send an order
   if(max_allowed_orders==0) return(true);

//--- if we passed to this line, then there is a limitation; find out how many orders are already placed
   int orders=OrdersTotal();

//--- return the result of comparing
   return(orders<max_allowed_orders);
  }

The part of the code responsible for sending an order is:

                 if (CheckIfPriceAllowsToSendOrder(GetOrderType()) && CheckStopLoss_Takeprofit(GetOrderType(), entry.GetNormalizedPrice(), stoploss.GetNormalizedPrice(), takeProfit)) {
                    ResetLastError();
                    if (IsNewOrderAllowed()) {
                       SendOrder();
                    }
        void SendOrder() {
           ResetLastError();
           Print("StopLoss: ", stoploss.GetNormalizedPrice(), "; minimal sl: ", MarketInfo(_Symbol,MODE_STOPLEVEL));
           Print("Entry: ", entry.GetNormalizedPrice());
           Print("Take Profit: ", takeProfit);
           Print("Ask: ", Ask);
           Print("Bid ", Bid);
         ticket = OrderSend(  _Symbol,
                              GetIsBuy() ? OP_BUYLIMIT : OP_SELLLIMIT,
                              LotSize(),
                              entry.GetNormalizedPrice(),
                              GetIsBuy() ? gLiveSlippageBuy : gLiveSlippageSell,
                              stoploss.GetNormalizedPrice(),
                              GetTakeProfit()
                              );
         if (ticket < 0) {
            Print("OrderSend failed; error: ", GetLastError());
         } else {
            Print("OrderSend placed successfully");
         }               
        }

This is the output from the terminal for an attempt to send an order on Decemeber 30, 2024, at 12:10, EURUSD:

OrderSend failed; error: 130
OrderSend error 130
Bid 1.04462
Ask: 1.04464 (I set spread as 2 to see if it makes a difference; it doesn't)
Take Profit: 1.04094
Entry: 1.04461
StopLoss: 1.04598; minimal sl: 0.0

I read that if minal sl is set to 0, this means that the broker doesn't know it (https://www.mql5.com/en/forum/360654, comment #3) and it is stated on mql4 website (here: https://docs.mql4.com/trading/ordersend): "A zero value of MODE_STOPLEVEL means either absence of any restrictions on the minimal distance for Stop Loss/Take Profit or the fact that a trade server utilizes some external mechanisms for dynamic level control, which cannot be translated in the client terminal".However, I failed to find any source providing a definitive answer on how to deal with this situation. In comment #3 of the forum thread I linked, the user claims that at least 2 pips are required - but in my case, the difference is already greater than that. What can I do to resolve this error? Where is my mistake?

MarketInfo(Symbol(),MODE_STOPLEVEL) to get the minimum Stoploss or Takeprofit level still error 130
MarketInfo(Symbol(),MODE_STOPLEVEL) to get the minimum Stoploss or Takeprofit level still error 130
  • 2021.01.19
  • noSkill06s
  • www.mql5.com
From the topic u will get fast my problem I'm a beginner EA programmer, this is my first EA pls see my Code I really dont get why its still not wor...
 

there is another link that describes 0 as "floating". My old broker had 0, just like my current broker. But my current broker, never gives me that error when i set stop level of 20 points, however, with old broker I had to put 70 points to keep from getting that error. But note that these are floating or as you found "dynamic". So you wont get that error all the time.

However, as some moderators might comment -- you dont need to have an ea to do pending orders. I suggest that you make the ea wait until a desired price, and then open a market order, instead.

/EDIT: do not forget that you may need to add FREEZE_LEVEL as well as stop level.
 
I tried to change StopLoss to 1.39298, but the error persists. Why is that? I don't understand. I may need to change to OP_SELL and OP_BUY, but I wouldn't like that. Is there anything I can do?
 

I followed your advice and set both Take Profit and Stop Loss to 0 now:

        void SendOrder() {
           ResetLastError();
           Print("StopLoss: ", stoploss.GetNormalizedPrice(), "; minimal sl: ", MarketInfo(_Symbol,MODE_STOPLEVEL));
           Print("Entry: ", entry.GetNormalizedPrice());
           Print("Take Profit: ", takeProfit);
           Print("Ask: ", Ask);
           Print("Bid: ", Bid);
         ticket = OrderSend(  _Symbol,
                              GetIsBuy() ? OP_BUYLIMIT : OP_SELLLIMIT,
                              LotSize(),
                              entry.GetNormalizedPrice(),
                              GetIsBuy() ? gLiveSlippageBuy : gLiveSlippageSell,
                              0,
                              0
                              );
         if (ticket < 0) {
            Print("OrderSend failed; error: ", GetLastError());
         } else {
            Print("OrderSend placed successfully");
         }               
        }

but the error is still there. What do I do wrong?

 
pagul #:

I followed your advice and set both Take Profit and Stop Loss to 0 now:

but the error is still there. What do I do wrong?

Dare I ask the obvious question...

Shouldn't you be sending stop orders as stoplosses instead of limit orders?

 

I've been debugging this for the last 10 hours or so with multiple versions of the function open in the same time. Either I copied the wrong one to the comment above, or I am an idiot. Let me check.


edit. Yup, I'm an idiot. I got it right the very first time when I defined the class, but for some reason I had to input it manually into the code and mess up. Thanks a lot, internet stranger! I owe you one!
 
pagul #:

I've been debugging this for the last 10 hours or so with multiple versions of the function open in the same time. Either I copied the wrong one to the comment above, or I am an idiot. Let me check.


edit. Yup, I'm an idiot. I got it right the very first time when I defined the class, but for some reason I had to input it manually into the code and mess up. Thanks a lot, internet stranger! I owe you one!

You're welcome. You were rather straightforward in your OP when you said that you're fairly new to trading commands. There's no need to beat yourself up. This is the whole point of this forum.