OrderSend Error 129 in MT4/MQL4: Invalid Price Fix

MT4 and MQL4 technical notes eyecatch image with a degu mascot, code panel, and trading chart background
Advertisement

OrderSend Error 129 in MT4/MQL4 means that the order price is invalid. In most cases, this error occurs when the price passed to OrderSend() does not match the current Bid/Ask price or the broker’s order rules.

This error is commonly shown as Invalid Price. It often happens when an EA uses the wrong price for Buy or Sell orders, sends an old price, or uses a pending order price on the wrong side of the market.

Quick answer:
OrderSend Error 129 is ERR_INVALID_PRICE. For market orders, use Ask for Buy and Bid for Sell. Always call RefreshRates() and normalize the price with NormalizeDouble(price, Digits) before sending an order.

What Does OrderSend Error 129 Mean?

In MQL4, Error 129 is known as:

  • Error code: 129
  • Error name: ERR_INVALID_PRICE
  • Meaning: Invalid price

This means that the price value passed to OrderSend() is not accepted by MT4 or the broker server.

OrderSend(Symbol(), OP_BUY, Lots, price, Slippage, StopLoss, TakeProfit, "buy order", Magic, 0, clrBlue);

If price is wrong, outdated, not normalized, or not valid for the order type, MT4 may return Error 129 and the order will not be placed.

Common Causes of OrderSend Error 129

CauseExampleHow to Fix
Wrong price for market orderUsing Bid for a Buy order or Ask for a Sell orderUse Ask for Buy and Bid for Sell
Old Bid/Ask priceThe EA uses a price value before the latest tick updateCall RefreshRates() before OrderSend()
Price is not normalizedThe EA sends a price with too many decimal placesUse NormalizeDouble(price, Digits)
Pending order price is on the wrong sideA Buy Limit is placed above the current Ask priceCheck the correct price direction for each pending order type
Price changed during order processingThe market moves quickly before the order is sentRefresh prices and use proper slippage settings

Correct Price for Buy and Sell Orders

For market orders, the price must match the order type.

Order TypeCorrect PriceCommon Mistake
BuyAskUsing Bid
SellBidUsing Ask

A Buy order should be opened at the Ask price.

RefreshRates();

double price = NormalizeDouble(Ask, Digits);

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

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

A Sell order should be opened at the Bid price.

RefreshRates();

double price = NormalizeDouble(Bid, Digits);

int ticket = OrderSend(
    Symbol(),
    OP_SELL,
    Lots,
    price,
    Slippage,
    0,
    0,
    "sell order",
    Magic,
    0,
    clrRed
);

if(ticket < 0)
{
    Print("OrderSend failed. Error: ", GetLastError());
}
Important:
If you use Bid for Buy or Ask for Sell, MT4 may return Error 129 because the price is not valid for that market order type.

Use RefreshRates Before OrderSend

Error 129 can occur when the EA uses an old price. Before sending an order, call RefreshRates() to update Bid and Ask.

RefreshRates();

double buyPrice  = NormalizeDouble(Ask, Digits);
double sellPrice = NormalizeDouble(Bid, Digits);

Print("Bid: ", Bid);
Print("Ask: ", Ask);
Print("Buy price: ", buyPrice);
Print("Sell price: ", sellPrice);

This is especially important when the EA performs several calculations before calling OrderSend(). The longer the delay between price calculation and order execution, the more likely the price may become outdated.

Normalize Price with NormalizeDouble

Another common cause of Error 129 is a price with invalid decimal digits. Use NormalizeDouble(price, Digits) before sending the price to OrderSend().

double price = Ask;

// Normalize the price according to the symbol digits
price = NormalizeDouble(price, Digits);

This is also important for stop loss, take profit, and pending order prices.

RefreshRates();

double price = NormalizeDouble(Ask, Digits);
double sl    = NormalizeDouble(Bid - 100 * Point, Digits);
double tp    = NormalizeDouble(Bid + 100 * Point, Digits);
Note:
If your stop loss or take profit is too close to the current price, MT4 may return Error 130 instead of Error 129. Error 129 is mainly about the order price itself.

Pending Orders Can Also Cause Error 129

Pending order prices must be placed on the correct side of the current market price. If the pending order price is logically invalid, OrderSend() may fail.

Pending Order TypeCorrect Price Direction
Buy LimitBelow the current Ask price
Buy StopAbove the current Ask price
Sell LimitAbove the current Bid price
Sell StopBelow the current Bid price

For example, a Buy Limit should be placed below the current Ask price.

RefreshRates();

double price = Ask - 100 * Point; // Buy Limit below Ask
price = NormalizeDouble(price, Digits);

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

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

MQL4 Code Example: Check Pending Order Price Direction

The following function checks whether the pending order price is on the correct side of the current price.

//+------------------------------------------------------------------+
//| Check whether pending order price direction is valid             |
//+------------------------------------------------------------------+
bool IsPendingPriceDirectionValid(int orderType, double price)
{
    RefreshRates();

    price = NormalizeDouble(price, Digits);

    if(orderType == OP_BUYLIMIT)
        return price < Ask;

    if(orderType == OP_BUYSTOP)
        return price > Ask;

    if(orderType == OP_SELLLIMIT)
        return price > Bid;

    if(orderType == OP_SELLSTOP)
        return price < Bid;

    return false;
}

Usage example:

RefreshRates();

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

if(!IsPendingPriceDirectionValid(OP_BUYLIMIT, price))
{
    Print("Invalid pending order price direction.");
    return;
}

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

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

This check helps prevent invalid pending order prices before the EA sends the order.

MQL4 Code Example: Get Correct Market Order Price

For market orders, you can use a helper function to return the correct price based on the order type.

//+------------------------------------------------------------------+
//| Get correct market order price                                   |
//+------------------------------------------------------------------+
double GetMarketOrderPrice(int orderType)
{
    RefreshRates();

    if(orderType == OP_BUY)
        return NormalizeDouble(Ask, Digits);

    if(orderType == OP_SELL)
        return NormalizeDouble(Bid, Digits);

    return 0;
}

Usage example:

int orderType = OP_BUY;
double price = GetMarketOrderPrice(orderType);

if(price <= 0)
{
    Print("Invalid order type.");
    return;
}

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

if(ticket < 0)
{
    Print("OrderSend failed. Error: ", GetLastError(), " Price: ", price);
}

How to Debug OrderSend Error 129

When Error 129 occurs, print the order type, Bid, Ask, price, and Digits. This makes it much easier to identify why the order price was rejected.

RefreshRates();

Print("Order type: ", OrderType);
Print("Bid: ", Bid);
Print("Ask: ", Ask);
Print("Price used: ", Price);
Print("Digits: ", Digits);
Print("Point: ", Point);
Print("Normalized price: ", NormalizeDouble(Price, Digits));

Then check the Experts tab or the Journal tab in MT4. If the EA used Bid for a Buy order, Ask for a Sell order, or an old price, that is likely the reason for Error 129.

Error 129 vs Error 130

Error 129 and Error 130 are often confused because both are related to order prices. However, the meaning is different.

ErrorMeaningMain Cause
Error 129Invalid priceThe order price itself is invalid
Error 130Invalid stopsSL, TP, or pending order distance is invalid

If the market order uses the wrong Bid/Ask price, check Error 129. If the stop loss, take profit, or pending order price is too close to the current price, check Error 130.

Related MQL4 Errors

OrderSend Error 129 is one of several common OrderSend errors in MT4. The table below shows related errors that are often checked together.

Error CodeError NameMain Cause
129ERR_INVALID_PRICEThe order price is invalid
130ERR_INVALID_STOPSStop loss, take profit, or pending order price is invalid
131ERR_INVALID_TRADE_VOLUMEThe lot size is invalid
134ERR_NOT_ENOUGH_MONEYThe account does not have enough free margin
4107ERR_INVALID_PRICE_PARAMA price parameter is invalid

FAQ About OrderSend Error 129

What does OrderSend Error 129 mean in MT4?

OrderSend Error 129 means ERR_INVALID_PRICE. It occurs when the price used in OrderSend() is not valid for the order type or current market condition.

Why does Error 129 occur when my entry signal is correct?

Error 129 is usually caused by the order price, not the entry signal. Even if the buy or sell condition is correct, the order can fail if the EA uses the wrong Bid/Ask price, an old price, or an invalid pending order price.

Should I use Bid or Ask for a Buy order?

For a Buy market order, use Ask. For a Sell market order, use Bid. Using the wrong price can cause OrderSend Error 129.

Can pending orders cause OrderSend Error 129?

Yes. A pending order can cause Error 129 if the order price is on the wrong side of the current market price, such as placing a Buy Limit above Ask or a Sell Limit below Bid.

How can I prevent old prices from causing Error 129?

Call RefreshRates() before OrderSend() and use the latest Bid or Ask value. Also normalize the price with NormalizeDouble(price, Digits).

How do I fix OrderSend Error 129?

Use Ask for Buy orders and Bid for Sell orders, call RefreshRates() before OrderSend(), normalize price values with NormalizeDouble(price, Digits), and check that pending order prices are on the correct side of the market.

Summary

OrderSend Error 129 in MT4/MQL4 means that the order price is invalid. In most cases, the EA is using the wrong Bid/Ask price, an outdated price, a non-normalized price, or an invalid pending order price.

  • Error 129 is ERR_INVALID_PRICE.
  • Use Ask for Buy market orders.
  • Use Bid for Sell market orders.
  • Call RefreshRates() before OrderSend().
  • Use NormalizeDouble(price, Digits) for order prices.
  • Check the correct price direction for pending orders.
  • If the problem is related to SL, TP, or stop distance, check OrderSend Error 130 instead.

If your EA returns Error 129, start by printing Bid, Ask, the order type, and the price passed to OrderSend(). Understanding which price was rejected is the fastest way to fix the EA and avoid repeated order failures.

Related: OrderSend Error 130 in MT4/MQL4

Related: OrderSend Error 131 in MT4/MQL4

Related: OrderSend Error 134 in MT4/MQL4

Back to MT4/MQL4 Technical Notes

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