Quick Answer
possible loss of data due to type conversion is a compiler warning, not an error. The EA still compiles, but the compiler is telling you that a value is being stored in a type that is smaller or less exact than the value itself. Some of the data can be lost.
In an EA the usual causes are SymbolInfoInteger() or PositionGetInteger() stored in an int (they return long), a ticket stored in an int (tickets are ulong), a double stored in an int (the decimals are cut off), and a datetime stored in an int. The fix is to use the type that matches the function, or to round on purpose with MathRound() before you cast.
From the author: I convert and review Expert Advisors between Pine Script, MQL5 and cTrader C#. This warning is easy to scroll past, because the EA still builds. It is worth fixing anyway, because one of the causes below, the lot step calculation, can silently give a lot size that is one step too small. That is why this guide has a worked example with real numbers.
Key Facts
| What you see | Usual cause | Fix |
|---|---|---|
| int spread = SymbolInfoInteger(...) | The function returns long, and int is smaller | Declare the variable as long |
| int magic = PositionGetInteger(POSITION_MAGIC) | Same: PositionGetInteger() returns long | Declare it as long |
| int ticket = PositionGetTicket(i) | Tickets are ulong | Declare it as ulong |
| int steps = lots / step | A double is stored in an int, and the decimals are cut off | Round on purpose: (int)MathRound(lots / step) |
| int t = TimeCurrent() | datetime is a 64-bit value, and int is 32-bit | Declare it as datetime |
| string s = "Lots: " + lots | A number is converted to a string without a format | DoubleToString(lots, 2) or StringFormat() |
What the Compiler Is Telling You
The message is shown in the Errors tab of MetaEditor with a yellow warning icon, the line and the column. It does not stop the build:
possible loss of data due to type conversion MyEA.mq5 15 16
0 error(s), 4 warning(s)
Read the line number, then look at the right side of the = on that line. The type of that value is the one that does not fit.
The EA With Warnings
This EA prints a few values once when it starts. It does not place trades. Every marked line gives the warning:
int OnInit()
{
int spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD); // long -> int
double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
int steps = 0.29 / step; // double -> int
Print("Spread: ", spread, ", steps in 0.29 lots: ", steps);
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
int ticket = PositionGetTicket(i); // ulong -> int
int magic = PositionGetInteger(POSITION_MAGIC); // long -> int
Print("Ticket ", ticket, ", magic ", magic);
}
return INIT_SUCCEEDED;
}
Each of the four lines has a different cause. The third one, steps, is the dangerous one, because the result looks plausible.
Cause 1: long Stored in an int
Many MQL5 functions that read integer properties return long: SymbolInfoInteger(), PositionGetInteger(), AccountInfoInteger() and HistoryDealGetInteger(). A long has 64 bits and an int has 32. If you store the result in an int, the compiler warns you:
int spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD); // warning
long spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD); // correct
A spread or a magic number is small enough to fit, so the value is usually right today. The warning is still correct: the type does not match the function, and a value that fits now may not fit later. Magic numbers are a good example, because people choose large numbers on purpose. See How to filter positions by magic number in MQL5 for the full pattern.
Cause 2: Tickets Stored in an int
Position and order tickets are ulong values. Storing one in an int is more than a warning: ticket numbers can be larger than an int can hold, and then the stored number is wrong, so the EA can no longer find or close that position.
int ticket = PositionGetTicket(i); // warning, and unsafe
ulong ticket = PositionGetTicket(i); // correct
The same applies to trade.ResultOrder(), trade.ResultDeal() and to the ticket parameters of the trade functions.
Cause 3: double Stored in an int
Storing a double in an int cuts off the decimals. It does not round. Most of the time that is not what you want, and with floating-point numbers it has a surprising effect: a division that should give a whole number can give a value a tiny bit below it.
double lots = 0.29;
double step = 0.01;
int steps = lots / step; // warning. The result is 28, not 29
Why: 0.29 / 0.01 is stored as 28.999999999999996, because neither 0.29 nor 0.01 can be written exactly in binary. Cutting off the decimals gives 28. The same happens for 0.57 / 0.01, which gives 56, not 57.
The fix is to round on purpose, to the nearest whole number, and to make the cast visible:
int steps = (int)MathRound(lots / step); // 29
This matters when you calculate a lot size from the volume step. See MQL5 lot size calculation for the complete method. If you need to round down and never up, for example to stay under a risk limit, add a small tolerance before MathFloor() so a result like 28.999999999999996 is not pushed down by a full step:
int steps = (int)MathFloor(lots / step + 1e-8);
A cast such as (int) silences the warning. It does not make the conversion safe. Use it only after you have decided how the value should be rounded.
Cause 4: datetime Stored in an int
A datetime is a 64-bit number of seconds. Storing it in an int has the same problem as with tickets, and a 32-bit number of seconds since 1970 runs out in 2038:
int now = TimeCurrent(); // warning
datetime now = TimeCurrent(); // correct
Use datetime for times, and compare times with times.
Cause 5: A Number Joined to a String
When you add a number to a string, MQL5 converts it for you, and it can warn about an implicit conversion. You also have no control over the number of decimals:
string text = "Lots: " + lots; // implicit conversion
string text = "Lots: " + DoubleToString(lots, 2); // correct
string text = StringFormat("Lots: %.2f, spread: %d", lots, (int)spread);
Use DoubleToString() and IntegerToString() for single values, or StringFormat() and PrintFormat() for several values at once. For Print, you can also pass the values as separate arguments, as in the first example in this article.
The Fixed EA
This version uses the types that match each function and rounds on purpose:
int OnInit()
{
long spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
int steps = (int)MathRound(0.29 / step);
PrintFormat("Spread: %d, steps in 0.29 lots: %d", (int)spread, steps);
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0) continue;
long magic = PositionGetInteger(POSITION_MAGIC);
PrintFormat("Ticket %I64u, magic %I64d", ticket, magic);
}
return INIT_SUCCEEDED;
}
The (int)spread cast in the first PrintFormat is a visible, deliberate conversion of a value that is known to be small. The %I64u and %I64d formats print a ulong and a long without losing digits.
Warning or Error?
| Message | Kind | Meaning | |---|---|---| | possible loss of data due to type conversion | Warning | The value may not fit in the target type | | implicit conversion from 'number' to 'string' | Warning | A number was converted to text without a format | | cannot convert enum | Error | An enum value was used where another type is expected | | 'x' - undeclared identifier | Error | The name is not declared. See MQL5 undeclared identifier error |
A warning does not stop the build, but a clean build without warnings is the better target. Warnings are often the first sign of a real bug.
Checklist: What to Check When You See This Warning
- Go to the line and look at the value on the right side of the
=. What type does it have? - Check the function in the MQL5 documentation. Does it return
long,ulong,doubleordatetime? - Use the same type for the variable. Integer properties are
long, tickets areulong, times aredatetime. - Double into int? Decide how to round:
MathRound(),MathFloor()orMathCeil(), and cast on purpose. - Floor on a division? Add a small tolerance, or round to the nearest value first.
- Number joined to text? Use
DoubleToString(),IntegerToString()orStringFormat(). - Use a cast only on purpose.
(int)hides the warning but does not fix a wrong conversion. - Build again and check that the warning count is zero.
- Print the value before and after the change when it is a lot size or a ticket.
Common Mistakes
- Declaring everything as
int. Uselong,ulong,doubleanddatetimewhere the function uses them. - Storing a ticket in an
int. - Cutting off a division instead of rounding it.
0.29 / 0.01gives 28. - Adding a cast to hide the warning without choosing the rounding.
- Joining numbers to text with
+. - Ignoring warnings because the EA builds.
FAQ
Related Guides
- MQL5 lot size calculation: position sizing for an EA.
- How to filter positions by magic number in MQL5: tickets, magic numbers and the right types.
- MQL5 undeclared identifier error: the compile error for a name that is not declared.
- MQL5 array out of range error: another common runtime problem.
- What to check in a trading bot before going live: a pre-live checklist for stops, lot size, spread and trade results.
Fix Compile Problems Without Guessing
If an EA or a cBot does not build, or builds with warnings you do not understand, paste the code and the compiler messages into the CodeFlowOS Error Fixer. It suggests a minimal fix, explains each problem and shows what changed. A fix uses 1 credit, with up to 3 attempts included, and the compiler check is optional. Outputs are not guaranteed, and code that compiles can still have wrong trading logic, so always review the result. Before a bot goes live, the Code Review is free during the early-bird period. CodeFlowOS also converts strategies between Pine Script, MQL5 and cTrader C#: try the converter page.
This article is educational. It does not describe trading performance and is not financial advice. Always compile and test code in MetaEditor and the Strategy Tester before using it on a live account.