Error 130

 
Can anyone help with error 130?

I've paid for an EA and the developer says he can't see anything wrong with the code. This happens when I activate the breakeven or stoploss, I send an image, please I'm looking for someone who can help I don't understand anything about codes, it doesn't make sense to look for the previous posts about error 130, I don't understand.

//+------------------------------------------------------------------+
//|                                                      Plattan.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
input bool macd_en = false; // MACD Enable
input bool rsx1_en = false; // RSX1 Enable
input bool conf_en = false; // Confirmation Enable
input bool rsx2_en = false; // RSX2 Enable
input int sl = 100; // SL in pips
input int tp = 100; // TP in pips
input double vol = 0.02; // Lot Size
input bool b_en = false; // Breakeven Enable
input int b_step = 150; // Breakeven Step in pips
input bool tsl_en = false; // TSL enable
input int tsl_step = 150; // TSL threshold in pips
input int tsl_sl = 100; // TSL SL in pips
input int mgc = 101; // Magic No

input string Confirmation_Settings = " Confirmation Settings";
input ENUM_TIMEFRAMES TF = PERIOD_CURRENT;
input int count = 40;
input ENUM_APPLIED_PRICE Price = PRICE_CLOSE;
input int shift = 0;
input double coef = 0.0;

input string RSX_Settings = " RSX Settings";
input int Length = 12;
input ENUM_APPLIED_PRICE Price_ = PRICE_CLOSE;
input int    SignalPeriod   = 6;
input int    SignalMaMethod = MODE_LWMA;
input double multiplier     = 5;

input string RSX2_Settings = " RSX2 Settings";
input int Length2 = 12;
input ENUM_APPLIED_PRICE Price2_ = PRICE_CLOSE;
input int    SignalPeriod2   = 6;
input int    SignalMaMethod2 = MODE_LWMA;
input double multiplier2     = 5;

input string MACD_Settings = " MACD Settings";
input int Fast_Ema = 12;
input int Slow_Ema = 26;
input int Signal_Period = 9;

string ind_c = "Confirmation_TT_SW.ex4";
string ind_r = "Rsx_SigMayhisto_mtf.ex4"; 
string ind_r2 = "Rsx_SigMayhisto_mtf_2.ex4"; 
int pip_dig = 1, bar_count;
double lot_size = 0.1;
bool buy_flag = true, sell_flag = true;
int OnInit()
  {
//---
   if(_Digits == 2 || _Digits == 4) pip_dig = 1;
   else if(_Digits == 3 || _Digits == 5) pip_dig = 10;
   lot_size = NormalizeDouble(vol, 2);
//---
//----
   bar_count = iBars(_Symbol, 0);

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(bar_count != iBars(_Symbol, 0)) { buy_flag = true; sell_flag = true; }
   //if(bar_count == iBars(_Symbol, 0)) return;
   //else { buy_flag = true; sell_flag = true; }
   string s = "Current time frame";
   double macd = iMACD(_Symbol, 0, Fast_Ema, Slow_Ema, Signal_Period, PRICE_CLOSE, 1, 0);
   double macd_prev = iMACD(_Symbol, 0, Fast_Ema, Slow_Ema, Signal_Period, PRICE_CLOSE, 1, 1);
////---- RSX Values
   double rsx = iCustom(_Symbol, 0, ind_r, s , Length, Price_, SignalPeriod, SignalMaMethod,multiplier, 4, 0);
   double rsx_ma = iCustom(_Symbol, 0, ind_r, s , Length, Price_, SignalPeriod, SignalMaMethod,multiplier, 5, 0);
   double rsx_prev = iCustom(_Symbol, 0, ind_r, s , Length, Price_, SignalPeriod, SignalMaMethod,multiplier, 4, 1);
   double rsx_ma_prev = iCustom(_Symbol, 0, ind_r, s , Length, Price_, SignalPeriod, SignalMaMethod,multiplier, 5, 1);

////---- RSX2 Values
   double rsx2 = iCustom(_Symbol, 0, ind_r2, s , Length2, Price2_, SignalPeriod2, SignalMaMethod2,multiplier2, 4, 0);
   double rsx2_ma = iCustom(_Symbol, 0, ind_r2, s , Length2, Price2_, SignalPeriod2, SignalMaMethod2,multiplier2, 5, 0);
   double rsx2_prev = iCustom(_Symbol, 0, ind_r2, s , Length2, Price2_, SignalPeriod2, SignalMaMethod2,multiplier2, 4, 1);
   double rsx2_ma_prev = iCustom(_Symbol, 0, ind_r2, s , Length2, Price2_, SignalPeriod2, SignalMaMethod2,multiplier2, 5, 1);
//------
   ////--
   double conf  = iCustom(_Symbol, 0, ind_c, TF, count, Price,shift, coef, 3, 0);
   double conf_prev = iCustom(_Symbol, 0, ind_c, TF, count, Price, shift, coef, 3, 1);
   if(!macd_en && rsx1_en && !rsx2_en && !conf_en) //rsx1 is selected
   {
      if(sell_flag && rsx < rsx_ma && rsx_prev > rsx_ma_prev){ Alert("Negative Crossovver"); GetTrade("sell");}
      else if(buy_flag && rsx > rsx_ma && rsx_prev < rsx_ma_prev) { Alert("Pos Crossover"); GetTrade("buy"); }
   }
   else if(!macd_en && !rsx1_en && !rsx2_en && conf_en) // Conf is selected
   {
      if(conf == 1 && buy_flag && conf_prev == -1) { Alert("Confirmation no bar"); GetTrade("buy"); }
      else if(conf == -1 && sell_flag && conf_prev == 1) { GetTrade("sell"); Alert("confirmation bar"); }
   }
   else if(macd_en && rsx1_en && !rsx2_en && !conf_en)  // Macd And RSX selected
   {
      if(buy_flag && macd>0 && rsx > rsx_ma && rsx_prev < rsx_ma_prev){ Alert("RSX crossover and MACD");  GetTrade("buy"); }
      else if(sell_flag && macd < 0 && rsx < rsx_ma && rsx_prev > rsx_ma_prev) { Alert("RSX crossover and MACD");  GetTrade("sell"); }
   }
   else if(macd_en && !rsx1_en && !rsx2_en && conf_en) // MACD and Confirmation selected
   {
      if(buy_flag && macd>0 && conf==1 && conf_prev == -1) { Alert("Macd and Confirmation"); GetTrade("buy"); }
      else if(sell_flag && macd < 0 && conf==-1 && conf_prev == 1) { Alert("Macd and Confirmation"); GetTrade("sell"); }
   }
   else if(macd_en && !rsx1_en && rsx2_en && !conf_en)
   {
      if(buy_flag && macd>0 && rsx2 > rsx2_ma && rsx2_prev < rsx2_ma_prev) { Alert("RSX2 and MACD"); GetTrade("buy");}
      else if(sell_flag && macd<0 && rsx2 < rsx2_ma && rsx2_prev > rsx2_ma_prev) { Alert("RSX2 and MACD"); GetTrade("sell");}
   }
   else if(macd_en && rsx1_en && !rsx2_en && conf_en) /// RSX MACD and Confirmatiom
   {
      if(buy_flag && macd>0 && conf==1 && conf_prev == -1 && rsx > rsx_ma) { GetTrade("buy"); }
      else if(sell_flag && macd<0 && conf==-1 && conf_prev == 1 && rsx < rsx_ma) { GetTrade("sell"); }
   }
   else if(macd_en && !rsx1_en && rsx2_en && conf_en)
   {
      if(buy_flag && macd>0 && conf==1 && conf_prev==-1 && rsx2 > rsx2_ma) GetTrade("buy");
      else if(sell_flag && macd<0 && conf==-1 && conf_prev==1 && rsx2 < rsx2_ma) GetTrade("sell");
   }
   else if(macd_en && rsx1_en && rsx2_en && conf_en)
   {
      if(buy_flag && macd>0 && conf==1 && conf_prev == -1 &&  rsx > rsx_ma && rsx2 > rsx2_ma) GetTrade("buy");
      else if(sell_flag && macd<0 && conf==-1 && conf_prev == 1 &&  rsx < rsx_ma && rsx2 < rsx2_ma) GetTrade("sell");
   }
//-------------
   if(b_en) BEven();
   else if(tsl_en) TSL();
//------
   bar_count = iBars(_Symbol, 0);
  }
//+------------------------------------------------------------------+

void BEven()
{
   double o_price, c_price, n_stopls; // open, current price and new stoploss
   bool b = false;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS) && OrderMagicNumber() != mgc) continue;
      o_price = OrderOpenPrice();
      if(OrderType() == OP_BUY) c_price = MarketInfo(_Symbol, MODE_BID);
      else if(OrderType() == OP_SELL) c_price = MarketInfo(_Symbol, MODE_ASK);
      if(c_price - o_price > b_step * _Point * pip_dig && OrderType() == OP_BUY) // Current - Open > Trigger
      {
         n_stopls = o_price + 2*  _Point * pip_dig; // new stoploss = open + distance
         if(n_stopls == OrderStopLoss()) continue;
         b = OrderModify(OrderTicket(), OrderOpenPrice(), n_stopls, OrderTakeProfit(),0);  // Moodify stop loss
         if(b) Alert(" New Breakeven Stoploss is set in Long Pos...");
         else { Alert("Modifiying problem ", GetLastError()); }
      }
      else if(o_price - c_price > b_step * _Point * pip_dig && OrderType() == OP_SELL) // Open - Current > Trigger
      {
         n_stopls = o_price - 2 * _Point * pip_dig; // New stoploss = open - distance
         if(n_stopls == OrderStopLoss()) continue;
         b = OrderModify(OrderTicket(), OrderOpenPrice(),  n_stopls, OrderTakeProfit(),0);
         if(b) Alert(" New Breakeven Stoploss is set in Short Pos...");
         else { Alert("Modifiying problem ", GetLastError()); }
      }
   }
}


void GetTrade(string s)
{
   if(s == "buy")
   {
      double pr = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      double SL = pr - sl * _Point * pip_dig;
      double TP = pr + tp * _Point * pip_dig;
      int o = OrderSend(_Symbol, OP_BUY, lot_size, pr, 30*_Point, SL, TP, "", mgc);
      if(o>0) { Alert(_Symbol, " is bought "); buy_flag = false; } 
      else if(o<0) Alert(_Symbol, " is bought problem "); 
   }
   else if(s == "sell")
   {
      double pr = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double SL = pr + sl * _Point * pip_dig;
      double TP = pr - tp * _Point * pip_dig;
      int o = OrderSend(_Symbol, OP_SELL, lot_size, pr, 30*_Point, SL, TP, "", mgc);
      if(o>0) { Alert(_Symbol, " is sold ");  sell_flag = false; }
      else if(o<0) Alert(_Symbol, " is sold problem "); 
   }
}

void TSL()
{
   double o_price, c_price, n_stopls;
   bool b;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS) && OrderMagicNumber() != mgc) continue;
      o_price = OrderOpenPrice();
      if(OrderType() == OP_BUY) c_price = MarketInfo(_Symbol, MODE_BID);
      else if(OrderType() == OP_SELL) c_price = MarketInfo(_Symbol, MODE_ASK);
      if(c_price - o_price > tsl_step * _Point * pip_dig && OrderType() == OP_BUY)
      {
         n_stopls = c_price - tsl_sl * _Point * pip_dig; // New stoploss
         if(n_stopls < OrderStopLoss() + 5 * _Point) continue;
         if(c_price - n_stopls < SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) * _Point) continue;
         b = OrderModify(OrderTicket(), OrderOpenPrice(), n_stopls , OrderTakeProfit() ,0);
         if(b) Alert(" New TSL  is set in Long Pos...");
         else { Alert("Modifiying problem ", GetLastError()); }
      }
      else if(o_price - c_price > tsl_step * _Point * pip_dig && OrderType() == OP_SELL)
      {
         n_stopls = c_price + tsl_sl * _Point * pip_dig;
         if(n_stopls > OrderStopLoss() - 5 * _Point) continue;
         if(n_stopls - c_price < SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) * _Point) continue;
         b= OrderModify(OrderTicket(), OrderOpenPrice(), n_stopls, OrderTakeProfit(), 0);
         if(b) Alert(" New TSL Stoploss is set in Short Pos...");
         else { Alert("Modifiying problem ", GetLastError()); }
      }
   } 
}



 
ThePlattan:

I have moved this thread here to "MQL4 and MetaTrader 4". Please make sure you post in the correct section before posting.

Thank you.

 
Hello,

Error 130 is due to invalid stops. Such as placing stops as a value that makes no sense.


Try printing out the values that you are modifying.


 
thanks for answering, this says ERR_INVALID_STOPS 130 Invalid stops.
The EA works well for TP and SL but not if I only activate breakeven or trailingstopp or both. If I have TP at 100 and Sl at 100
breakeven to 30 should work but I get error 130 . I have no problems with other EAs with this setup.
 
  1.    lot_size = NormalizeDouble(vol, 2);

    You used NormalizeDouble, It's use is usually wrong, as it is in your case.

    1. Floating point has an infinite number of decimals, it's you were not understanding floating point and that some numbers can't be represented exactly. (like 1/10.)
                Double-precision floating-point format - Wikipedia, the free encyclopedia

      See also The == operand. - MQL4 programming forum (2013)

    2. Print out your values to the precision you want with DoubleToString - Conversion Functions - MQL4 Reference.

    3. SL/TP (stops) need to be normalized to tick size (not Point) — code fails on non-currencies.
                On 5Digit Broker Stops are only allowed to be placed on full pip values. How to find out in mql? - MQL4 programming forum #10 (2011)

      And abide by the limits Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial and that requires understanding floating point equality Can price != price ? - MQL4 programming forum (2012)

    4. Open price for pending orders need to be adjusted. On Currencies, Point == TickSize, so you will get the same answer, but it won't work on non-currencies. So do it right.
                Trailing Bar Entry EA - MQL4 programming forum (2013)
                Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 programming forum (2012)

    5. Lot size must also be adjusted to a multiple of LotStep and check against min and max. If that is not a power of 1/10 then NormalizeDouble is wrong. Do it right.
                (MT4 2013)) (MT5 2022))

    6. MathRound() and NormalizeDouble() are rounding in a different way. Make it explicit.
                MT4:NormalizeDouble - MQL5 programming forum (2017)
                How to Normalize - Expert Advisors and Automated Trading - MQL5 programming forum (2017)

    7. Prices you get from the terminal are already correct (normalized).

    8. PIP, Point, or Tick are all different in general.
                What is a TICK? - MQL4 programming forum (2014)

  2. int OnInit()  {
    ⋮
       bar_count = iBars(_Symbol, 0);
    Don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:
    1. Terminal starts.
    2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
    3. OnInit is called.
    4. For indicators OnCalculate is called with any existing history.
    5. Human may have to enter password, connection to server begins.
    6. New history is received, OnCalculate called again.
    7. A new tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

  3.    if(bar_count != iBars(_Symbol, 0)) { buy_flag = true; sell_flag = true; }

    You can't know when a candle closes. Only when a new tick arrives that starts a new bar is the old bar closed, and that tick could arrive almost at the end of a bar's duration.

    For a new bar test, Bars is unreliable (a refresh/reconnect can change number of bars on chart), volume is unreliable (miss ticks), Price is unreliable (duplicate prices and The == operand. - MQL4 programming forum.) Always use time.
              MT4: New candle - MQL4 programming forum #3 (2014)
              MT5: Accessing variables - MQL4 programming forum #3 (2022)

    I disagree with making a new bar function, because it can only be called once per tick (second call returns false). A variable can be tested multiple times.
              Running EA once at the start of each bar - MQL4 programming forum (2011)

  4.    for(int i = 0; i < OrdersTotal(); i++)
       {
          if(!OrderSelect(i, SELECT_BY_POS) && OrderMagicNumber() != mgc) continue;
    Broken test. If the order select fails the second condition might be false and you process garbage. If the select succeeds you process any orders with any magic number. Don't use negative logic.
       for(int i = 0; i < OrdersTotal(); i++) if(
          OrderSelect(i, SELECT_BY_POS) 
       && OrderMagicNumber() == mgc
                                   
       ){ // Only process selected mgc
    No symbol filtering means every chart must have a different MN. Code breaks if human forgets to change it.

    You need one Magic Number for each symbol/timeframe/strategy.
         Trade current timeframe, one strategy, and filter by symbol requires one MN.
         If trading multiple timeframes, and filter by symbol requires use a range of MN (base plus timeframe).
              Why are MT5 ENUM_TIMEFRAMES strange? - General - MQL5 programming forum - Page 2 #11 (2020)

  5. In the presence of multiple orders (one EA multiple charts, multiple EAs, manual trading), while you are waiting for the current operation (closing, deleting, modifying) to complete, any number of other operations on other orders could have concurrently happened and changed the position indexing and order count:

    1. For non-FIFO (non-US brokers), (or the EA only opens one order per symbol), you can simply count down, in an index loop, and you won't miss orders. Get in the habit of always counting down.
                Loops and Closing or Deleting Orders - MQL4 programming forum

    2. For In First Out (FIFO rules — US brokers), and you (potentially) process multiple orders per symbol, you must find the earliest order (count up), close it, and on a successful operation, reprocess all positions (from zero).
                CloseOrders by FIFO Rules - Strategy Tester - MQL4 programming forum - Page 2 #16
                MetaTrader 5 platform beta build 2155: MQL5 scope, global Strategy Tester and built-in Virtual Hosting updates - Best Expert Advisors - General - MQL5 programming forum #1.11

    and check OrderSelect in case other positions were deleted.
              What are Function return values ? How do I use them ? - MQL4 programming forum
              Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles

    and if you (potentially) process multiple orders, must call RefreshRates() after server calls if you want to use, on the next order / server call, the Predefined Variables (Bid/Ask.) Or instead, be direction independent and just use OrderClosePrice().

  6.       if(OrderType() == OP_BUY) c_price = MarketInfo(_Symbol, MODE_BID);
          else if(OrderType() == OP_SELL) c_price = MarketInfo(_Symbol, MODE_ASK);

    MT4: You can use OrderClosePrice() instead of Bid/Ask and be direction independent — no need to check order type to get the close price.

  7.          if(c_price - n_stopls < SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) * _Point) continue;

    You can't move stops (or pending prices) closer to the market than the minimum: MODE_STOPLEVEL * _Point or SymbolInfoInteger(SYMBOL_TRADE_STOPS_LEVEL).
              Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial

    On some ECN type brokers, the value might be zero (the broker doesn't know). Use a minimum of two (2) PIPs.

    The checks a trading robot must pass before publication in the Market - MQL5 Articles (2016)

  8. Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?
              Code debugging - Developing programs - MetaEditor Help
              Error Handling and Logging in MQL5 - MQL5 Articles (2015)
              Tracing, Debugging and Structural Analysis of Source Code - MQL5 Articles (2011)
              Introduction to MQL5: How to write simple Expert Advisor and Custom Indicator - MQL5 Articles (2010)