OrderSend Error 130 in MT4/MQL4: Invalid Stops Fix

MT4 and MQL4 technical notes eyecatch image with a degu mascot, code panel, and trading chart background
スポンサーリンク

OrderSend Error 130 in MT4/MQL4 means that the stop settings in a trade request are not valid. The MQL4 error name is ERR_INVALID_STOPS.

The most common causes are a stop loss, take profit, or pending-order price that is too close to the current market price or does not satisfy the broker’s trading rules.

Quick answer:
OrderSend Error 130 is ERR_INVALID_STOPS. Check MODE_STOPLEVEL, confirm that SL and TP are on the correct side of the market, make sure the required distance is satisfied, and normalize calculated prices with NormalizeDouble(price, Digits).

What Does OrderSend Error 130 Mean?

  • Error code: 130
  • Error name: ERR_INVALID_STOPS
  • Meaning: Invalid stops

Error 130 means that MT4 or the trade server rejected a stop-related price in the request.

For a market order, this usually means the stop loss or take profit. For a pending order, the pending-order entry price itself must also satisfy the broker’s minimum distance rules.

int ticket = OrderSend(
    Symbol(),
    OP_BUY,
    Lots,
    Ask,
    Slippage,
    StopLoss,
    TakeProfit,
    "buy order",
    Magic,
    0,
    clrBlue
);

If StopLoss or TakeProfit violates the server’s stop rules, OrderSend() can return -1 with Error 130.

Common Causes of OrderSend Error 130

CauseWhat to CheckTypical Fix
Stop loss is too closeThe distance between the market price and SLCheck MODE_STOPLEVEL and move SL farther away
Take profit is too closeThe distance between the market price and TPIncrease the TP distance
SL or TP is on the wrong sideBuy/Sell stop directionCorrect the SL/TP direction
Pending-order distance is too smallThe pending entry price relative to Bid/AskMove the pending price farther from the current market
Calculated price precision is inappropriateSL, TP, or pending price decimal precisionUse NormalizeDouble(price, Digits)
Server-side stop restrictionsStopLevel is zero but the request is still rejectedAllow more distance or handle the restriction dynamically

Check MODE_STOPLEVEL First

MT4 provides the broker’s minimum stop distance through MODE_STOPLEVEL.

int stopLevel =
    (int)MarketInfo(Symbol(), MODE_STOPLEVEL);

double minStopDistance =
    stopLevel * Point;

Print("StopLevel=", stopLevel, " points");
Print("Minimum stop distance=", minStopDistance);

The value returned by MODE_STOPLEVEL is measured in points.

For example:

StopLevel = 20
Point     = 0.00001

Minimum distance = 20 * 0.00001
                 = 0.00020
Points and pips are different:
On a typical 5-digit EURUSD symbol, 10 points correspond to 1 pip. Make sure the EA does not confuse a stop distance expressed in pips with a broker restriction expressed in points.

Correct Stop Loss and Take Profit Direction

Even when the distance is large enough, SL and TP must also be placed on the correct side of the market.

Market OrderStop LossTake Profit
BuyBelow BidAbove Bid
SellAbove AskBelow Ask

Buy Example

RefreshRates();

double sl =
    NormalizeDouble(Bid - 100 * Point, Digits);

double tp =
    NormalizeDouble(Bid + 100 * Point, Digits);

Sell Example

RefreshRates();

double sl =
    NormalizeDouble(Ask + 100 * Point, Digits);

double tp =
    NormalizeDouble(Ask - 100 * Point, Digits);
Do not confuse Error 129 and Error 130:
Error 129 mainly concerns the execution price passed to OrderSend(). Error 130 concerns stop-related prices and minimum-distance rules.

MQL4 Code Example: Validate SL and TP Before OrderSend

A simple helper function can check the visible MODE_STOPLEVEL requirement before sending a market order.

bool IsStopDistanceValid(int orderType,
                         double sl,
                         double tp)
{
    RefreshRates();

    double minDistance =
        MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;

    if(orderType == OP_BUY)
    {
        if(sl > 0)
        {
            if(sl >= Bid)
                return false;

            if((Bid - sl) < minDistance)
                return false;
        }

        if(tp > 0)
        {
            if(tp <= Bid)
                return false;

            if((tp - Bid) < minDistance)
                return false;
        }

        return true;
    }

    if(orderType == OP_SELL)
    {
        if(sl > 0)
        {
            if(sl <= Ask)
                return false;

            if((sl - Ask) < minDistance)
                return false;
        }

        if(tp > 0)
        {
            if(tp >= Ask)
                return false;

            if((Ask - tp) < minDistance)
                return false;
        }

        return true;
    }

    return false;
}

Example for a Buy order:

RefreshRates();

double sl =
    NormalizeDouble(Bid - 100 * Point, Digits);

double tp =
    NormalizeDouble(Bid + 100 * Point, Digits);

if(!IsStopDistanceValid(OP_BUY, sl, tp))
{
    Print("Invalid SL/TP.");
    return;
}

double price =
    NormalizeDouble(Ask, Digits);

ResetLastError();

int ticket = OrderSend(
    Symbol(),
    OP_BUY,
    Lots,
    price,
    Slippage,
    sl,
    tp,
    "buy order",
    Magic,
    0,
    clrBlue
);

if(ticket < 0)
{
    int err = GetLastError();

    Print("OrderSend failed. Error=", err,
          " Bid=", Bid,
          " Ask=", Ask,
          " SL=", sl,
          " TP=", tp);
}
This is a pre-check, not a guarantee:
The function can validate the StopLevel currently reported by MT4, but the server may still apply dynamic restrictions that are not fully visible to the terminal.

Pending Orders Can Also Produce Error 130

A pending order must satisfy both its basic price direction and the broker’s minimum distance requirement.

Pending OrderBasic Direction
Buy LimitBelow Ask
Buy StopAbove Ask
Sell LimitAbove Bid
Sell StopBelow Bid

For example, a Buy Limit must be below Ask and far enough away to satisfy the applicable stop-distance rule.

RefreshRates();

double minDistance =
    MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;

double price =
    NormalizeDouble(Ask - 100 * Point, Digits);

if(price >= Ask)
{
    Print("Buy Limit price must be below Ask.");
    return;
}

if((Ask - price) < minDistance)
{
    Print("Buy Limit is too close to Ask.");
    return;
}

ResetLastError();

int ticket = OrderSend(
    Symbol(),
    OP_BUYLIMIT,
    Lots,
    price,
    Slippage,
    0,
    0,
    "buy limit",
    Magic,
    0,
    clrBlue
);

if(ticket < 0)
{
    Print("OrderSend failed. Error=",
          GetLastError());
}
Direction and distance are separate checks:
A pending-order price can be on the correct side of the market and still be rejected because it is too close. Always check both conditions.

MODE_STOPLEVEL Is Zero but Error 130 Still Occurs

A MODE_STOPLEVEL value of zero does not always mean that every stop distance will be accepted.

It can mean that there is no fixed minimum distance reported to MT4. The server may still apply a dynamic or floating restriction that the terminal cannot represent as one constant StopLevel value.

If Error 130 occurs while MODE_STOPLEVEL is zero:

  • Increase the SL/TP or pending-order distance.
  • Refresh Bid and Ask before recalculating the prices.
  • Normalize all calculated price values.
  • Print the exact Bid, Ask, SL, TP, and pending price used.
  • Check whether the restriction changes under different market conditions.
Important:
A zero StopLevel should not be interpreted as proof that a stop can always be placed at any distance.

OrderModify Can Also Fail Because of Stop Restrictions

Error 130 is not limited to the initial OrderSend(). An OrderModify() request can also fail when a new SL or TP violates the allowed price-distance rules.

When modifying an existing order, it is also useful to check MODE_FREEZELEVEL.

int stopLevel =
    (int)MarketInfo(Symbol(), MODE_STOPLEVEL);

int freezeLevel =
    (int)MarketInfo(Symbol(), MODE_FREEZELEVEL);

Print("StopLevel=", stopLevel);
Print("FreezeLevel=", freezeLevel);

The freeze level defines a price area in which some order operations may be restricted. This is especially relevant when modifying or deleting orders close to the current market price.

Send the Market Order First, Then Add SL/TP

In some trading environments, a market order may be accepted more reliably when it is first opened without SL and TP and then modified afterward.

The workflow is:

  1. Send the market order with SL and TP set to zero.
  2. Confirm that the order was opened.
  3. Select the new ticket.
  4. Calculate valid SL and TP levels.
  5. Apply them with OrderModify().
RefreshRates();

double price =
    NormalizeDouble(Ask, Digits);

ResetLastError();

int ticket = OrderSend(
    Symbol(),
    OP_BUY,
    Lots,
    price,
    Slippage,
    0,
    0,
    "buy order",
    Magic,
    0,
    clrBlue
);

if(ticket < 0)
{
    Print("OrderSend failed. Error=",
          GetLastError());

    return;
}

if(OrderSelect(ticket, SELECT_BY_TICKET))
{
    RefreshRates();

    double sl =
        NormalizeDouble(Bid - 100 * Point, Digits);

    double tp =
        NormalizeDouble(Bid + 100 * Point, Digits);

    ResetLastError();

    bool modified = OrderModify(
        ticket,
        OrderOpenPrice(),
        sl,
        tp,
        0,
        clrNONE
    );

    if(!modified)
    {
        Print("OrderModify failed. Error=",
              GetLastError());
    }
}
This is not a universal requirement:
Do not automatically remove SL and TP from every market order. Use this approach when your execution environment or broker rules require the stops to be added after the position is opened.

How to Debug OrderSend Error 130

When Error 130 occurs, print the actual market and stop values used by the EA.

RefreshRates();

int stopLevel =
    (int)MarketInfo(Symbol(), MODE_STOPLEVEL);

int freezeLevel =
    (int)MarketInfo(Symbol(), MODE_FREEZELEVEL);

double minStopDistance =
    stopLevel * Point;

Print("Bid=", Bid);
Print("Ask=", Ask);
Print("Digits=", Digits);
Print("Point=", Point);
Print("StopLevel=", stopLevel);
Print("FreezeLevel=", freezeLevel);
Print("MinimumStopDistance=", minStopDistance);
Print("SL=", StopLoss);
Print("TP=", TakeProfit);

Then inspect the Experts and Journal tabs in MT4.

A practical troubleshooting order is:

  1. Confirm that the actual error is 130.
  2. Check the SL/TP direction.
  3. Check MODE_STOPLEVEL.
  4. Compare the actual SL/TP distance with the minimum distance.
  5. Normalize calculated prices.
  6. For pending orders, check both direction and distance.
  7. If modifying an existing order, also check MODE_FREEZELEVEL.
  8. If StopLevel is zero, allow for possible dynamic server restrictions.

Error 129 vs Error 130

Errors 129 and 130 are closely related to price values, but they refer to different parts of the trade request.

ErrorMeaningMain Area to Check
129 Invalid priceThe execution price supplied to OrderSend()
130Invalid stopsSL, TP, pending-order distance, and stop restrictions

If a Buy market order uses an invalid execution price, investigate Error 129. If the market entry price is valid but the SL, TP, or pending-order distance is rejected, investigate Error 130.

Related OrderSend Errors

ErrorNameMain CauseGuide
129ERR_INVALID_PRICEInvalid execution price Error 129 Guide
130ERR_INVALID_STOPSInvalid SL, TP, or pending-order distanceThis guide
131ERR_INVALID_TRADE_VOLUMEInvalid lot size Error 131 Guide
134ERR_NOT_ENOUGH_MONEYInsufficient free margin Error 134 Guide

Related MQL4 OrderSend Guides

FAQ About OrderSend Error 130

Q. What does OrderSend Error 130 mean in MT4?

OrderSend Error 130 is ERR_INVALID_STOPS. It means that a stop loss, take profit, pending-order price, or related stop distance does not satisfy the trading rules applied to the request.

Q. How can I check the minimum stop distance in MQL4?

Use MarketInfo(Symbol(), MODE_STOPLEVEL). The returned value is in points, so multiply it by Point when comparing it with an actual price distance.

Q. Why does MODE_STOPLEVEL return zero but Error 130 still occur?

A zero value can mean there is no fixed StopLevel reported to MT4, while the server still uses dynamic or floating stop restrictions. In that case, increasing the distance and logging the actual prices can help identify the restriction.

Q. Can pending orders cause OrderSend Error 130?

Yes. A pending-order entry price must satisfy both the correct price direction and the minimum distance required from the current Bid or Ask.

Q. Can OrderModify return Error 130?

Yes. A new SL or TP can be rejected during OrderModify() when it violates stop-distance rules. When modifying an order near the current market price, MODE_FREEZELEVEL may also be relevant.

Q. Should I always send a market order without SL and TP first?

No. Many environments accept SL and TP in the initial OrderSend() request. Sending the order first and adding stops with OrderModify() is useful only when the trading environment or server rules require that workflow.

Q. How do I fix OrderSend Error 130?

Check MODE_STOPLEVEL, verify the SL/TP direction, increase the distance when necessary, normalize calculated prices, and check both direction and distance for pending orders. If the error occurs during modification, also review the freeze level and current market price.

Summary

OrderSend Error 130 in MT4/MQL4 is ERR_INVALID_STOPS. The fastest way to diagnose it is to compare the actual SL, TP, or pending-order price with the current Bid/Ask and the broker’s stop-distance rules.

  • Error 130 means Invalid Stops.
  • Check MODE_STOPLEVEL and remember that it is returned in points.
  • Buy SL is below Bid and Buy TP is above Bid.
  • Sell SL is above Ask and Sell TP is below Ask.
  • Pending orders must satisfy both direction and minimum-distance rules.
  • A StopLevel of zero can still be associated with dynamic server-side restrictions.
  • OrderModify() can also fail because of stop restrictions.
  • When modifying orders, MODE_FREEZELEVEL may also be relevant.
  • Do not confuse Error 130 with Error 129, which concerns the execution price itself.

Back to MT4/MQL4 Technical Notes

タイトルとURLをコピーしました