Edgoro
Compiler warning 43 · MQL5

MQL5 warning: possible loss of data due to type conversion

Why MetaEditor warns "possible loss of data due to type conversion" (long to int, double to int) and how to cast and round correctly in MQL5.

MetaEditor · Errors tab · warning 43 · line 3
possible loss of data due to type conversion from 'long' to 'int'

What it means

A value is stored in a type that can't hold every value of the original type: a long into an int, a double into an int or a long. The program compiles, with warning 43, and the conversion happens anyway. MetaEditor warns because a large value can be cut, and a decimal part is always dropped.

Usual causes

  • SymbolInfoInteger(), AccountInfoInteger() and PositionGetInteger() return long. Storing the result in an int (stops level, digits, spread) triggers the warning.
  • A price distance in points stored as int, such as int points = distance / _Point.
  • A double volume or price stored in an integer type.

How to detect it

  • MetaEditor's Errors tab lists the warning with the types involved, the line and the column. The build still succeeds, so look at the warning count in the last line of the log.

Broken code

This script compiles with two warnings: possible loss of data due to type conversion from 'long' to 'int' (line 3) and from 'double' to 'int' (line 5).

MQL5
void OnStart()
  {
   int    stopsLevel = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double atrPrice   = 0.00153;            // an ATR value, in price
   int    atrPoints  = atrPrice / _Point;   // drops the decimals, sometimes one point too many
   Print("Stops level ", stopsLevel, " points, ATR ", atrPoints, " points");
  }

Fixed code

The same program, corrected. It compiles in MetaEditor with 0 errors and 0 warnings.

MQL5
void OnStart()
  {
   // The stops level always fits in an int: say so with a cast
   int    stopsLevel = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double atrPrice   = 0.00153;
   // Round first, then cast: 152.99999... becomes 153, not 152
   int    atrPoints  = (int)MathRound(atrPrice / _Point);
   Print("Stops level ", stopsLevel, " points, ATR ", atrPoints, " points");
  }

Why the fix works

An explicit cast tells the compiler the conversion is intended, which removes the warning. For the stops level that's all it takes: the value is a small number of points. For the distance, the cast alone would still be wrong now and then: a division of prices can give 152.99999999 instead of 153, and a cast to int truncates it to 152. Rounding with MathRound() before casting gives the number you expect.

Questions

Does (int) round or truncate in MQL5?

It truncates: the decimals are dropped, so 2.9 becomes 2. Use MathRound() before the cast to round to the nearest integer, or MathFloor() / MathCeil() to round down or up.

Why does SymbolInfoInteger return long?

Because it returns every integer property of a symbol through one function, including values that need 64 bits. For properties that are small numbers, such as the stops level or the number of digits, an (int) cast is safe.

Should I just use long everywhere?

For values that come from SymbolInfoInteger() and similar functions, a long variable avoids the warning without a cast. For conversions from double, the type isn't the issue: decide how to round, then cast.

The programs on this page are minimal examples written to show the error and its fix, not trading systems. Some of them send orders when they run: try them on a demo account. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

Rather not write the error handling yourself?

Edgoro's MT5 EA generator writes complete MQL5 Expert Advisors from plain English and compiles each one in MetaEditor before you get it. A clean build proves the code compiles, not that a strategy works: test it on a demo account.