Comparing prices in MQL without floating point surprises
Posted: Mon Oct 19, 2026 9:09 am
Comparing prices in MQL without floating point surprises
A small coding issue that causes real bugs in EAs: comparing prices directly with == or even with > and <.
Prices are stored as double precision floating point numbers. A price that should be 1.08500 might be stored as 1.0849999999 or 1.0850000001. If your EA checks whether the bid equals your level, it might never be true. If it checks whether the bid is above the level, it might be true one tick too early or too late.
The usual fix is to normalise before comparing. NormalizeDouble(price, _Digits) rounds to the symbol's digits. Comparing two normalised values is much safer. Another approach is to compare the difference to half a point: if the absolute difference between two prices is less than _Point divided by two, treat them as equal.
The same applies to lot sizes. Your sizing calculation might come out to 0.2300000001 lots, and the broker will reject it if it isn't a multiple of the volume step. Round it down to SYMBOL_VOLUME_STEP, clamp it between minimum and maximum volume, and then send it.
Stops and targets need it too. Send a stop price with too many decimals and some brokers reject the order with invalid stops.
None of this is exciting. It's just the kind of thing that turns a good strategy into an EA that behaves strangely.
A small coding issue that causes real bugs in EAs: comparing prices directly with == or even with > and <.
Prices are stored as double precision floating point numbers. A price that should be 1.08500 might be stored as 1.0849999999 or 1.0850000001. If your EA checks whether the bid equals your level, it might never be true. If it checks whether the bid is above the level, it might be true one tick too early or too late.
The usual fix is to normalise before comparing. NormalizeDouble(price, _Digits) rounds to the symbol's digits. Comparing two normalised values is much safer. Another approach is to compare the difference to half a point: if the absolute difference between two prices is less than _Point divided by two, treat them as equal.
The same applies to lot sizes. Your sizing calculation might come out to 0.2300000001 lots, and the broker will reject it if it isn't a multiple of the volume step. Round it down to SYMBOL_VOLUME_STEP, clamp it between minimum and maximum volume, and then send it.
Stops and targets need it too. Send a stop price with too many decimals and some brokers reject the order with invalid stops.
None of this is exciting. It's just the kind of thing that turns a good strategy into an EA that behaves strangely.