Summary: This comprehensive guide covers all MQL4 data types including int, double, string, bool, datetime, and color. Learn variable declaration, naming conventions, scope rules, and type conversion with practical EA examples.




Why Data Types Matter in EA Development
Every piece of data in an MQL4 program has a specific type. Understanding data types is the foundation of writing error-free EA code. Using the correct data type prevents compilation errors and ensures your EA calculates correctly.

Complete MQL4 Data Type Reference Table
| Data Type | Purpose | Value Range | Memory Size | Example |
|-----------|---------|-------------|-------------|---------|
| int | Integer numbers | -2,147,483,648 to 2,147,483,647 | 4 bytes | int magic = 12345; |
| double | Decimal numbers | ±1.7e-308 to ±1.7e+308 | 8 bytes | double price = 1.09250; |
| string | Text characters | Up to 2,147,483,647 characters | Variable | string symbol = "EURUSD"; |
| bool | Boolean logic | true or false (1 or 0) | 1 byte | bool isBuy = true; |
| datetime | Date and time | Jan 1, 1970 to Dec 31, 3000 | 8 bytes | datetime now = TimeCurrent(); |
| color | Color values | 0 to 16,777,215 (RGB) | 4 bytes | color clrRed = clrRed; |

1. Integer (int) - Whole Numbers
Integers are used for counting orders, magic numbers, slippage settings, and array indices.
```mql4
// Integer variable declarations
int magicNumber = 12345; // EA identifier
int slippage = 30; // Allowed slippage in points
int totalOrders = 0; // Order counter
int stopLossPoints = 50; // Stop loss in points
int takeProfitPoints = 100; // Take profit in points

// Integer arithmetic
int openOrders = OrdersTotal();
int pendingOrders = OrdersTotal() - openOrders;
int total = openOrders + pendingOrders;

// Integer best practices
// Use constants for fixed values
#define MAX_ORDERS 10
#define MIN_STOP_LOSS 20

if(openOrders < MAX_ORDERS) {
// Safe to open new order
}
```

2. Double - Decimal Numbers
Doubles handle all price values, stop loss/take profit distances, and indicator calculations.
```mql4
// Double variable declarations
double lotSize = 0.1; // Trading volume
double entryPrice = 0; // Order entry price
double stopLossPrice = 0; // Stop loss price
double takeProfitPrice = 0; // Take profit price
double accountBalance = AccountBalance();

// Risk-based lot size calculation
double CalculateLotSize(double riskPercent, double stopLossPoints) {
double riskAmount = AccountBalance() * riskPercent / 100;
double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double lotSize = riskAmount / (stopLossPoints * tickValue);

// Normalize to step size
double stepSize = MarketInfo(Symbol(), MODE_LOTSTEP);
lotSize = MathFloor(lotSize / stepSize) * stepSize;

// Apply min/max limits
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
lotSize = MathMax(minLot, MathMin(maxLot, lotSize));

return NormalizeDouble(lotSize, 2);
}

// Price normalization (CRITICAL for OrderSend)
double NormalizePrice(double price, string symbol) {
int digits = (int)MarketInfo(symbol, MODE_DIGITS);
return NormalizeDouble(price, digits);
}
```

3. String - Text Data
Strings store symbol names, file paths, and dynamic text for chart display.
```mql4
// String variable declarations
string symbolName = "EURUSD";
string logMessage = "";
string filePath = "C:\\MT4\\Files\\log.txt";

// String concatenation
string message = "Buy signal detected on " + symbolName + " at " + DoubleToString(entryPrice, 5);

// String utility functions
void WriteToLog(string text) {
string timestamp = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES);
string logLine = "[" + timestamp + "] " + text;
Print(logLine);
}

// Extract currency pair parts
string baseCurrency = StringSubstr(symbolName, 0, 3); // "EUR"
string quoteCurrency = StringSubstr(symbolName, 3, 3); // "USD"
```

4. Boolean (bool) - True/False Logic
Booleans control trade conditions and state flags.
```mql4
// Boolean variable declarations
bool isNewBar = false;
bool hasOpenPosition = false;
bool allowTrading = true;
bool isBuySignal = false;
bool isSellSignal = false;

// Trading condition with boolean flags
void CheckTradeConditions() {
bool trendUp = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 1) >
iMA(NULL, 0, 50, 0, MODE_SMA, PRICE_CLOSE, 1);
bool rsiOversold = iRSI(NULL, 0, 14, PRICE_CLOSE, 1) < 30;
bool noPosition = CountOrders(magicNumber) == 0;

if(trendUp && rsiOversold && noPosition && allowTrading) {
isBuySignal = true;
OpenBuyOrder();
}
}

// State flags for EA logic
static bool g_firstRun = true;
static bool g_tradeLock = false;

void OnTick() {
if(g_firstRun) {
Print("EA started first time on this chart");
g_firstRun = false;
}

if(g_tradeLock) {
Print("Trade locked - skipping this tick");
return;
}
}
```

5. Datetime - Time Management
Datetime variables handle all time-related operations including trade timing and bar detection.
```mql4
// Datetime variable declarations
datetime currentTime = TimeCurrent();
datetime lastTradeTime = 0;
datetime sessionStart = D'2024.01.15 08:00:00';
datetime expirationDate = D'2024.12.31 23:59:59';

// Time-based trade filtering
bool IsTradingHours() {
datetime now = TimeCurrent();
MqlDateTime timeStruct;
TimeToStruct(now, timeStruct);

int hour = timeStruct.hour;
int minute = timeStruct.min;
int dayOfWeek = timeStruct.day_of_week; // 0=Sunday, 6=Saturday

// Trading only Monday to Friday, 8:00 to 17:00
if(dayOfWeek >= 1 && dayOfWeek <= 5) {
if(hour >= 8 && hour < 17) {
return true;
}
// Allow 8:30 specifically
if(hour == 8 && minute >= 30) return true;
}
return false;
}

// Cooldown timer
bool IsCooldownExpired(int seconds) {
if(TimeCurrent() - lastTradeTime >= seconds) {
lastTradeTime = TimeCurrent();
return true;
}
return false;
}

// Get midnight timestamp
datetime GetMidnight() {
MqlDateTime tm;
TimeToStruct(TimeCurrent(), tm);
tm.hour = 0;
tm.min = 0;
tm.sec = 0;
return StructToTime(tm);
}
```

6. Color - Chart Visuals
Color variables enhance chart visualization for manual monitoring.
```mql4
// Predefined color constants
color buyArrowColor = clrGreen;
color sellArrowColor = clrRed;
color textColor = clrWhite;
color backgroundColor = clrBlack;

// RGB color creation
color customBlue = C'0,100,255';
color customOrange = 0x0000FFAA; // Hexadecimal format

// Drawing signals on chart
void DrawSignal(bool isBuy, double price, datetime time) {
string arrowName = "Signal_" + IntegerToString(time);

if(isBuy) {
ObjectCreate(0, arrowName, OBJ_ARROW_UP, 0, time, price);
ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrGreen);
} else {
ObjectCreate(0, arrowName, OBJ_ARROW_DOWN, 0, time, price);
ObjectSetInteger(0, arrowName, OBJPROP_COLOR, clrRed);
}
ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2);
}
```

Variable Scope and Lifetime
```mql4
// GLOBAL scope - accessible everywhere, lifetime = entire EA runtime
double g_globalVariable = 100;
int g_tickCount = 0;

int OnInit() {
// LOCAL scope - only inside OnInit(), destroyed after function ends
int localCounter = 0;
localCounter++;
g_tickCount = 0;
return(INIT_SUCCEEDED);
}

void OnTick() {
// STATIC local - preserves value between function calls
static int staticCounter = 0;
staticCounter++;

// Regular local - reset to 0 each OnTick
int localCounter = 0;
localCounter++;

g_tickCount++; // Access global variable

Print("Static: ", staticCounter, " | Local: ", localCounter);
// Output: Static: 1,2,3... | Local: 1,1,1...
}

// Scope Hierarchy (from highest to lowest priority)
// 1. Local variables (inside function)
// 2. Function parameters
// 3. Global variables
```

Type Conversion (Casting)
```mql4
void TypeConversionExamples() {
// Implicit conversion (automatic)
double price = 1.09250;
int priceInt = price; // 1 (truncates decimal)
int points = 50;
double pointsDouble = points; // 50.0

// Explicit conversion (manual)
double precisePrice = 1.09250;
int normalizedPrice = (int)(precisePrice * 100000); // 109250

// String to number
string priceStr = "1.09250";
double priceFromString = StringToDouble(priceStr);

// Number to string
double accountBalance = AccountBalance();
string balanceStr = DoubleToString(accountBalance, 2);
string magicStr = IntegerToString(magicNumber);

// Datetime to string
datetime now = TimeCurrent();
string timeStr = TimeToString(now, TIME_DATE|TIME_MINUTES);

// String to datetime
string dateStr = "2024.01.15 14:30:00";
datetime parsedDate = StringToTime(dateStr);
}
```

Complete EA Template with Proper Data Types
```mql4
//+------------------------------------------------------------------+
//| DataTypesEA |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024"
#property version "1.00"
#property strict

// Input parameters
input double InpLotSize = 0.1; // Trading lot size
input int InpMagic = 12345; // EA magic number
input int InpSlippage = 30; // Slippage in points
input bool InpUseTimeFilter = true; // Enable time filter
input string InpSymbol = "EURUSD"; // Trading symbol

// Global variables
double g_spread;
int g_totalOrders;
bool g_initialized = false;
datetime g_lastTradeTime = 0;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
g_spread = MarketInfo(InpSymbol, MODE_SPREAD);
Print("EA initialized on ", InpSymbol, " with spread: ", g_spread);
g_initialized = true;
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
if(!g_initialized) return;

static datetime lastBarTime = 0;
if(Time[0] == lastBarTime) return;
lastBarTime = Time[0];

if(InpUseTimeFilter && !IsTradingHours()) return;

ExecuteStrategy();
}

//+------------------------------------------------------------------+
//| Strategy execution |
//+------------------------------------------------------------------+
void ExecuteStrategy() {
double maFast = iMA(InpSymbol, 0, 10, 0, MODE_SMA, PRICE_CLOSE, 1);
double maSlow = iMA(InpSymbol, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1);

if(maFast > maSlow && CountOrders() == 0) {
OpenBuy();
}
else if(maFast < maSlow && CountOrders() == 0) {
OpenSell();
}
}
```

Common Data Type Errors and Solutions
| Error | Cause | Solution |
|-------|-------|----------|
| "possible loss of data" | Assigning double to int | Use explicit cast: (int)variable |
| "string cannot be converted" | Mixing string and number | Use IntegerToString() or DoubleToString() |
| "undeclared identifier" | Variable not declared before use | Declare variable in correct scope |
| "true - cannot convert" | Using boolean in numeric context | Check logic expressions carefully |
| "'price' - not all control paths return" | Function missing return value | Add return statement for all paths |

Data Type Best Practices Checklist
  • [ ] Use int for counters, magic numbers, and point values

  • [ ] Use double for prices, stop losses, and account values

  • [ ] Use string for symbol names, messages, and file paths

  • [ ] Use bool for flags and condition results

  • [ ] Use datetime for all time-related variables

  • [ ] Always normalize prices with NormalizeDouble() before OrderSend

  • [ ] Use static variables inside functions to preserve values

  • [ ] Limit global variable usage to essential shared data


  • Reference:
  • MetaQuotes Ltd. "MQL4 Documentation - Data Types" (2024)

  • Franklin, James. "MQL4 Programming Basics" (2022)


  • 9. Next Step
    Part 7 will explain Operators and Expressions in MQL4 – Arithmetic, comparison, logical, and assignment operators with practical EA examples and operator precedence rules.