DEV Community

Arnold Holm
Arnold Holm

Posted on

MT5 invalid price: two decimal places can still miss the tick

Your price can keep 2 decimals and still miss the allowed tick. My native MT5 check rejected 100.13 on a chosen 0.25 grid. Rounding by the tick produced 100.25, which passed the same check.

I check the price grid before widening deviation or changing the entry signal.

The question came from an MT5 developer whose XAUUSD position closes returned 10015. Increasing deviation had not helped. A reply pointed to a mismatch between the symbol's tick size and prices returned in that old tester case. That thread concerns older terminal builds. My check below isolates the arithmetic, rather than diagnosing that person's broker today.

The mistake I put under test

The assumption is simple: if a symbol displays two decimals, rounding to two decimals makes a price valid.

That fails when the allowed price step is larger than the displayed decimal unit. With a tick size of 0.25, 100.00 and 100.25 sit on the grid. 100.13 does not. Keeping two decimals leaves 100.13 unchanged.

Here is the incomplete version from my example:

double raw = 100.13;
double price = NormalizeDouble(raw, 2);
// Still 100.13. Decimal rounding did not check the 0.25 grid.
Enter fullscreen mode Exit fullscreen mode

The number of displayed decimals and the minimum price change are separate symbol properties in MQL5. I read the actual symbol settings rather than infer its step from its appearance on a chart.

The change and the three results

For this isolated example I chose the values explicitly. That makes the failure easy to repeat without waiting for a particular instrument or quote.

bool OnGrid(double price, double tick) {
    return price > 0 && tick > 0 &&
        MathAbs(price / tick - MathRound(price / tick)) < 0.000001;
}
double raw = NormalizeDouble(100.13, 2);
double tick = 0.25;
double rounded = NormalizeDouble(MathRound(raw / tick) * tick, 2);
// OnGrid(raw, tick) is false. OnGrid(rounded, tick) is true.
Enter fullscreen mode Exit fullscreen mode

I compiled and ran this check in native MT5. The compiler reported zero errors. The output was:

Input Expected Actual
Zero price Reject Rejected
100.13, tick 0.25 Off grid Off grid
100.25, tick 0.25 On grid On grid

Nearest rounding is a demonstration here, not a universal order rule. Rounding a buy limit upward can change its intended distance or put it on the wrong side of the market. Choose floor, ceiling or nearest rounding for the specific order rule, then check its relationship to Bid or Ask again.

Native MT5 price-grid run: zero rejected, 100.13 off grid, 100.25 on grid. Chosen 0.25 tick, zero orders.

Find the same mistake in five minutes

Open one rejected request in your MT5 log. Write down the requested price, symbol tick size, Bid, Ask and order type from that request.

Divide the requested price by the tick size. If it is far from a whole number, inspect where the price was formed. Check the entry, stop and target separately. A correctly rounded entry does not repair a target calculated on another grid.

Keep the timestamp with those values. A fresh quote read later cannot explain what the program submitted earlier. Once the grid is correct, check the order side and required distances separately. Passing this arithmetic check does not settle those questions.

The three cases used chosen inputs and sent zero orders. They did not reproduce server return code 10015 or establish broker acceptance. They show exactly why decimal rounding alone missed one invalid price in my code. I would keep this small check beside the order-building code so a later change cannot quietly bring the same mistake back.

If you have a small trading-code fault, the free bug check starts with the expected result, actual result and the smallest source excerpt you are allowed to share.

Top comments (0)