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
スポンサーリンク

OrderSend Error 129 in MT4/MQL4 means that the price passed to OrderSend() is invalid. The MQL4 error name is ERR_INVALID_PRICE.

For market orders, one of the first things to check is whether the EA is using the correct current price: Ask for Buy and Bid for Sell. Price precision and the timing of the price update should also be checked.

Quick answer:
OrderSend Error 129 is ERR_INVALID_PRICE. For a market Buy, use the current Ask; for a market Sell, use the current Bid. Call RefreshRates() before reading the price, normalize it with NormalizeDouble(price, Digits), and log GetLastError() immediately if OrderSend() fails.

What Does OrderSend Error 129 Mean?

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

Error 129 means that MT4 did not accept the price supplied in the trade request.

The relevant argument is the price parameter in OrderSend().

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

If price is not valid for the order being sent, OrderSend() returns -1. You can then read the MQL4 error code with GetLastError().

Common Causes of OrderSend Error 129

CauseWhat to CheckTypical Fix
Wrong market-order priceBuy is not using Ask or Sell is not using BidUse the correct current Bid/Ask price
Invalid price precisionThe calculated price contains an inappropriate number of decimal placesUse NormalizeDouble(price, Digits)
Price value was calculated earlierThe EA performs calculations before sending the orderCall RefreshRates() and recalculate the execution price immediately before OrderSend()
Incorrect pending-order calculationThe requested pending price does not match the intended order typeCheck both price direction and broker stop-distance rules
Wrong symbol priceThe EA reads Bid/Ask from a different symbol than the order symbolUse the correct symbol-specific price when trading another symbol

Use Ask for Buy and Bid for Sell

For MT4 market orders, Buy and Sell orders use different sides of the quote.

Market OrderExecution Price
BuyAsk
SellBid

Buy Order Example

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)
{
    int err = GetLastError();

    Print("OrderSend failed. Error=", err,
          " Ask=", Ask,
          " Price=", price);
}

Sell Order Example

RefreshRates();

double price = NormalizeDouble(Bid, Digits);

ResetLastError();

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

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

    Print("OrderSend failed. Error=", err,
          " Bid=", Bid,
          " Price=", price);
}
First check for Error 129:
Print the order type, Bid, Ask, and the exact price supplied to OrderSend(). This usually makes an incorrect market-order price easy to identify.

Call RefreshRates Before Reading the Execution Price

An EA may perform indicator calculations, loops, file processing, or other work before it reaches OrderSend(). During that time, the market price may change.

Calling RefreshRates() immediately before reading Bid or Ask helps update the predefined price variables available to the EA.

RefreshRates();

double buyPrice =
    NormalizeDouble(Ask, Digits);

double sellPrice =
    NormalizeDouble(Bid, Digits);

It is better to calculate the execution price immediately before sending the order rather than storing a market price much earlier in the EA logic.

Error 129 and Error 138 are different:
A price-related failure is not always Error 129. Depending on the price state and execution situation, an outdated market price can also result in Error 138 (Requote). Always inspect the actual error code returned by MT4.

Normalize the Order Price

A calculated price may contain more decimal precision than the symbol supports. Before passing a calculated price to a trade function, normalize it to the symbol’s number of digits.

double price =
    NormalizeDouble(Ask, Digits);

The same principle applies to calculated stop-loss, take-profit, and pending-order prices.

RefreshRates();

double price =
    NormalizeDouble(Ask, Digits);

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

double tp =
    NormalizeDouble(Ask + 100 * Point, Digits);
Price precision and price distance are different issues:
NormalizeDouble() adjusts decimal precision. It does not guarantee that the SL, TP, or pending-order distance satisfies the broker’s trading rules.

Pending Order Prices Need Two Checks

Pending orders need more than a normalized price. You should check both:

  1. The price is on the correct side of the current market.
  2. The price satisfies the broker’s minimum distance requirements.
Pending OrderBasic Price Direction
Buy LimitBelow the current Ask
Buy StopAbove the current Ask
Sell LimitAbove the current Bid
Sell StopBelow the current Bid

A simple direction check can be written like this:

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;
}
Do not treat every pending-order rejection as Error 129:
If the pending price, stop loss, or take profit violates the broker’s minimum distance requirements, MT4 may return Error 130 (Invalid Stops). Price direction and stop distance should therefore be checked separately.

MQL4 Helper Function for Market Order Prices

If the EA opens both Buy and Sell positions, a small helper function can keep the price-selection rule in one place.

double GetMarketOrderPrice(int orderType)
{
    RefreshRates();

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

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

    return 0;
}

Example:

int orderType = OP_BUY;

double price =
    GetMarketOrderPrice(orderType);

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

ResetLastError();

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

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

    Print("OrderSend failed. Error=", err,
          " Price=", price,
          " Bid=", Bid,
          " Ask=", Ask);
}

For a larger EA, the same idea can be expanded into a reusable wrapper that also handles lot validation, spread checks, retries, and error logging.

How to Debug OrderSend Error 129

When Error 129 occurs, do not only print the error number. Print the values that were actually used to build the order request.

RefreshRates();

Print("OrderType=", orderType);
Print("Bid=", Bid);
Print("Ask=", Ask);
Print("Price=", price);
Print("Digits=", Digits);
Print("Point=", Point);
Print("NormalizedPrice=",
      NormalizeDouble(price, Digits));

Then check the Experts and Journal tabs in MT4.

A practical debugging order is:

  1. Confirm the exact error is 129.
  2. Confirm the order symbol.
  3. Confirm Buy uses Ask and Sell uses Bid.
  4. Call RefreshRates().
  5. Normalize the execution price.
  6. For pending orders, check direction and minimum distance separately.
  7. Print the exact values sent to OrderSend().

Error 129 vs Error 130 vs Error 138

These three errors can appear during order execution, but they indicate different problems.

ErrorMeaningMain Area to Check
129Invalid priceThe price passed to OrderSend()
130 Invalid stopsSL, TP, pending-order price, and minimum stop distance
138RequoteThe requested market price is no longer available under the current execution conditions

If MT4 returns 129, investigate the actual execution price first. If it returns 130, investigate stop and pending-order distances. If it returns 138, refresh the market price and review the execution/retry logic.

Related OrderSend Errors

ErrorNameMain CauseGuide
129ERR_INVALID_PRICEInvalid order priceThis guide
130ERR_INVALID_STOPSInvalid SL, TP, or pending-order distance Error 130 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 129

Q. What does OrderSend Error 129 mean in MT4?

OrderSend Error 129 is ERR_INVALID_PRICE. It means that MT4 rejected the price supplied to the trade request.

Q. Should I use Bid or Ask for a Buy order?

A Buy market order uses Ask, while a Sell market order uses Bid. Check this first when debugging Error 129.

Q. Should I call RefreshRates() before OrderSend()?

It is useful when the EA has performed calculations or other processing before sending the order. RefreshRates() updates the predefined Bid and Ask values before the execution price is calculated.

Q. Does NormalizeDouble() fix Error 129?

NormalizeDouble(price, Digits) fixes price precision, which is one possible cause of an invalid price. It does not correct the wrong Bid/Ask side, an incorrect symbol price, or invalid stop-distance rules.

Q. Can an old price cause Error 129?

Price timing can contribute to an order failure, but an outdated market price may also produce Error 138 (Requote) depending on the situation. Check the actual MT4 error code rather than assuming every stale-price failure is Error 129.

Q. What is the difference between Error 129 and Error 130?

Error 129 concerns the order price itself. Error 130 concerns invalid stop levels, such as SL, TP, or pending-order prices that violate the broker’s minimum distance requirements.

Q. How do I fix OrderSend Error 129?

Confirm the order symbol and order type, use Ask for Buy or Bid for Sell, call RefreshRates(), normalize the price to Digits, and print the exact price and error code when OrderSend() fails.

Summary

OrderSend Error 129 in MT4/MQL4 is ERR_INVALID_PRICE. The fastest way to debug it is to inspect the exact price that the EA passed to OrderSend().

  • Error 129 means Invalid Price.
  • Use Ask for Buy market orders.
  • Use Bid for Sell market orders.
  • Call RefreshRates() before calculating a fresh execution price when needed.
  • Normalize calculated prices with NormalizeDouble(price, Digits).
  • For pending orders, check both price direction and minimum stop distance.
  • Do not confuse Error 129 with Error 130 or Error 138.
  • Use GetLastError() immediately after a failed OrderSend() call.

Back to MT4/MQL4 Technical Notes

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