Summary: This comprehensive guide covers all conditional statements in MQL4 including if, else if, else, and switch. Learn how to control EA trading logic flow, validate trade conditions, and implement multi-branch decision making with practical examples.




Why Conditional Statements Matter in EA Development
Conditional statements are the decision-making backbone of any Expert Advisor. They allow your EA to evaluate market conditions and choose different actions based on those evaluations. Without conditional statements, an EA would execute the same instructions every time, making it incapable of adapting to changing market conditions.

Complete Conditional Statements Reference Table
| Statement | Syntax | Use Case | Execution |
|-----------|--------|----------|-----------|
| if | if(condition) { code } | Single condition check | Executes only if condition is true |
| if-else | if(condition) { code1 } else { code2 } | Two-way branching | Executes code1 if true, code2 if false |
| else-if | if(cond1) { code1 } else if(cond2) { code2 } | Multi-way branching | Executes first true condition block |
| switch | switch(expression) { case x: code; break; } | Multiple discrete values | Jumps to matching case value |

1. The if Statement - Single Condition Testing
The if statement is the most basic conditional statement. It executes a block of code only when the specified condition evaluates to true.
```mql4
// Basic if statement syntax
if(condition) {
// Code executes only when condition is true
}

// Practical EA example - Simple trade signal
void CheckBuySignal() {
double rsi = iRSI(NULL, 0, 14, PRICE_CLOSE, 1);

if(rsi < 30) {
// RSI indicates oversold condition - potential buy
double lotSize = 0.1;
int ticket = OrderSend(Symbol(), OP_BUY, lotSize, Ask, 30, 0, 0, "RSI Buy", magicNumber, 0, clrGreen);

if(ticket > 0) {
Print("Buy order placed successfully at ", Ask);
}
}
}

// Multiple independent if statements
void CheckMultipleConditions() {
double maFast = iMA(NULL, 0, 10, 0, MODE_SMA, PRICE_CLOSE, 1);
double maSlow = iMA(NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1);
double rsi = iRSI(NULL, 0, 14, PRICE_CLOSE, 1);

if(maFast > maSlow) {
Print("Bullish trend detected");
}

if(rsi < 30) {
Print("Oversold condition detected");
}

if(rsi > 70) {
Print("Overbought condition detected");
}
}

// Nested if statements
void CheckWithConfirmation() {
double maFast = iMA(NULL, 0, 10, 0, MODE_SMA, PRICE_CLOSE, 1);
double maSlow = iMA(NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1);
double rsi = iRSI(NULL, 0, 14, PRICE_CLOSE, 1);

if(maFast > maSlow) {
// Primary condition met - check secondary
if(rsi < 30) {
// Both conditions met - strong buy signal
Print("Strong buy signal: Bullish trend + Oversold RSI");
OpenBuyOrder();
}
else if(rsi < 40) {
// Moderate conditions
Print("Moderate buy signal: Bullish trend + RSI below 40");
}
}
}
```

2. The if-else Statement - Two-Way Branching
The if-else statement provides two execution paths: one when the condition is true, another when it is false.
```mql4
// Basic if-else syntax
if(condition) {
// Executes when condition is true
} else {
// Executes when condition is false
}

// Practical EA example - Buy or Sell decision
void DetermineTradeDirection() {
double maFast = iMA(NULL, 0, 10, 0, MODE_SMA, PRICE_CLOSE, 1);
double maSlow = iMA(NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1);

if(maFast > maSlow) {
// Bullish - consider buying
Print("Bullish trend - evaluating buy setup");
if(ConfirmBuyConditions()) {
OpenBuyOrder();
}
} else {
// Bearish or sideways - consider selling
Print("Bearish trend - evaluating sell setup");
if(ConfirmSellConditions()) {
OpenSellOrder();
}
}
}

// Position management with if-else
void ManageOpenPosition(double entryPrice, double currentPrice) {
double profitPoints = (currentPrice - entryPrice) / Point();

if(profitPoints >= 50) {
// Move stop loss to breakeven
ModifyStopLoss(entryPrice);
Print("Stop loss moved to breakeven");
} else {
// Keep original stop loss
Print("Profit insufficient for breakeven adjustment");
}
}

// Trade validation with if-else
bool ValidateTrade() {
double spread = MarketInfo(Symbol(), MODE_SPREAD);
int orderCount = CountOrders(magicNumber);

if(spread <= 30 && orderCount == 0) {
Print("Trade validation passed: spread=", spread, " orders=", orderCount);
return true;
} else {
Print("Trade validation failed: spread=", spread, " orders=", orderCount);
return false;
}
}
```

3. The else-if Statement - Multi-Way Branching
The else-if chain allows you to test multiple conditions in sequence. The first condition that evaluates to true executes its corresponding block.
```mql4
// Basic else-if syntax
if(condition1) {
// Executes when condition1 is true
} else if(condition2) {
// Executes when condition1 is false AND condition2 is true
} else if(condition3) {
// Executes when condition1 and condition2 are false AND condition3 is true
} else {
// Executes when all conditions are false
}

// Practical EA example - RSI signal strength classification
int ClassifyRSISignal(double rsiValue) {
if(rsiValue < 20) {
Print("Extreme oversold - Strong buy signal");
return SIGNAL_STRONG_BUY;
} else if(rsiValue < 30) {
Print("Oversold - Moderate buy signal");
return SIGNAL_BUY;
} else if(rsiValue > 80) {
Print("Extreme overbought - Strong sell signal");
return SIGNAL_STRONG_SELL;
} else if(rsiValue > 70) {
Print("Overbought - Moderate sell signal");
return SIGNAL_SELL;
} else {
Print("Neutral zone - No signal");
return SIGNAL_NEUTRAL;
}
}

// Multi-condition trading strategy
void ExecuteMultiConditionStrategy() {
double maFast = iMA(NULL, 0, 10, 0, MODE_SMA, PRICE_CLOSE, 1);
double maSlow = iMA(NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1);
double rsi = iRSI(NULL, 0, 14, PRICE_CLOSE, 1);
double macd = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
int orderCount = CountOrders(magicNumber);

if(orderCount > 0) {
// Already have position - manage it
ManageExistingPositions();
}
else if(maFast > maSlow && rsi < 30 && macd < 0) {
// Strong buy signal - all indicators align
Print("Strong buy signal detected");
OpenBuyOrder(CalculateLotSize(2, 50));
}
else if(maFast > maSlow && rsi < 40) {
// Moderate buy signal - trend up + RSI not oversold
Print("Moderate buy signal detected");
OpenBuyOrder(CalculateLotSize(1, 50));
}
else if(maFast < maSlow && rsi > 70 && macd > 0) {
// Strong sell signal - all indicators align
Print("Strong sell signal detected");
OpenSellOrder(CalculateLotSize(2, 50));
}
else if(maFast < maSlow && rsi > 60) {
// Moderate sell signal
Print("Moderate sell signal detected");
OpenSellOrder(CalculateLotSize(1, 50));
}
else {
// No clear signal - wait
Comment("No trading signal at this time");
}
}

// Time-based strategy selection
void SelectTimeBasedStrategy() {
MqlDateTime timeStruct;
TimeToStruct(TimeCurrent(), timeStruct);
int hour = timeStruct.hour;

if(hour >= 2 && hour < 6) {
Print("Asian session - using range trading strategy");
ExecuteRangeStrategy();
}
else if(hour >= 6 && hour < 12) {
Print("London session - using breakout strategy");
ExecuteBreakoutStrategy();
}
else if(hour >= 12 && hour < 18) {
Print("New York session - using momentum strategy");
ExecuteMomentumStrategy();
}
else if(hour >= 18 && hour < 22) {
Print("Overlap session - using scalp strategy");
ExecuteScalpStrategy();
}
else {
Print("Low liquidity period - monitoring only");
MonitorOnly();
}
}
```

4. The switch Statement - Multiple Discrete Value Branching
The switch statement is ideal when you need to branch based on the value of a single integer or enumeration variable.
```mql4
// Basic switch syntax
switch(expression) {
case value1:
// Executes when expression == value1
break;
case value2:
// Executes when expression == value2
break;
default:
// Executes when no case matches
break;
}

// Practical EA example - Order type handling
string GetOrderTypeName(int orderType) {
switch(orderType) {
case OP_BUY:
return "Buy";
case OP_SELL:
return "Sell";
case OP_BUYLIMIT:
return "Buy Limit";
case OP_SELLLIMIT:
return "Sell Limit";
case OP_BUYSTOP:
return "Buy Stop";
case OP_SELLSTOP:
return "Sell Stop";
default:
return "Unknown";
}
}

// Signal processing with switch
void ProcessSignal(int signalType) {
switch(signalType) {
case SIGNAL_STRONG_BUY:
OpenBuyOrder(0.2);
SendAlert("Strong buy signal - opening 0.2 lots");
break;

case SIGNAL_BUY:
OpenBuyOrder(0.1);
SendAlert("Buy signal - opening 0.1 lots");
break;

case SIGNAL_STRONG_SELL:
OpenSellOrder(0.2);
SendAlert("Strong sell signal - opening 0.2 lots");
break;

case SIGNAL_SELL:
OpenSellOrder(0.1);
SendAlert("Sell signal - opening 0.1 lots");
break;

case SIGNAL_CLOSE_ALL:
CloseAllPositions();
SendAlert("Close signal - closing all positions");
break;

default:
Print("Unknown signal type: ", signalType);
break;
}
}

// Error code handling with switch
void HandleOrderSendError(int errorCode) {
switch(errorCode) {
case 130:
Print("Error 130: Invalid stops - check distance requirements");
AdjustStopLossDistance();
break;

case 134:
Print("Error 134: Not enough money - reduce lot size");
ReduceLotSize();
break;

case 146:
Print("Error 146: Trading context busy - retrying");
Sleep(1000);
break;

case 148:
Print("Error 148: Too many orders - close some positions first");
CloseOldestPosition();
break;

default:
Print("Unknown error: ", errorCode, " - ", ErrorDescription(errorCode));
break;
}
}
```

Complete EA Template Using All Conditional Statements
```mql4
//+------------------------------------------------------------------+
//| ConditionalEA.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024"
#property version "1.00"
#property strict

input double InpLotSize = 0.1;
input int InpMagic = 12345;
input int InpMaxSpread = 30;
input int InpMaxDailyTrades = 5;
input bool InpUseTimeFilter = true;
input int InpStartHour = 8;
input int InpEndHour = 17;

int g_dailyTradeCount = 0;
double g_dailyProfit = 0;
datetime g_lastReset = 0;

// Signal constants
#define SIGNAL_NONE 0
#define SIGNAL_BUY 1
#define SIGNAL_SELL 2
#define SIGNAL_STRONG_BUY 3
#define SIGNAL_STRONG_SELL 4

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
g_lastReset = GetMidnight();
Print("Conditional EA initialized");
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
static datetime lastBarTime = 0;

// New bar detection
if(Time[0] == lastBarTime) return;
lastBarTime = Time[0];

// Reset daily counters at midnight
ResetDailyIfNeeded();

// Check trading conditions using if statements
if(!IsTradeAllowed()) {
Comment("Auto-trading disabled");
return;
}

if(IsMaxTradesReached()) {
Comment("Daily trade limit reached: ", g_dailyTradeCount, "/", InpMaxDailyTrades);
return;
}

if(InpUseTimeFilter && !IsTradingHours()) {
Comment("Outside trading hours");
return;
}

// Main trading logic with else-if chain
ExecuteTradingStrategy();
}

//+------------------------------------------------------------------+
//| Reset daily counters |
//+------------------------------------------------------------------+
void ResetDailyIfNeeded() {
datetime midnight = GetMidnight();
if(midnight != g_lastReset) {
g_dailyTradeCount = 0;
g_dailyProfit = 0;
g_lastReset = midnight;
Print("Daily counters reset");
}
}

//+------------------------------------------------------------------+
//| Main trading strategy with else-if |
//+------------------------------------------------------------------+
void ExecuteTradingStrategy() {
// Calculate indicators
double maFast = iMA(NULL, 0, 10, 0, MODE_SMA, PRICE_CLOSE, 1);
double maSlow = iMA(NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1);
double rsi = iRSI(NULL, 0, 14, PRICE_CLOSE, 1);
double macd = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
double spread = MarketInfo(Symbol(), MODE_SPREAD);
int currentOrders = CountOrders(InpMagic);

// Spread validation using if
if(spread > InpMaxSpread) {
Comment("Spread too high: ", spread);
return;
}

// Position management using if-else
if(currentOrders > 0) {
ManageOpenPositions();
return;
}

// Signal generation using else-if chain
int signal = SIGNAL_NONE;

if(maFast > maSlow && rsi < 30 && macd < 0) {
signal = SIGNAL_STRONG_BUY;
}
else if(maFast > maSlow && rsi < 40) {
signal = SIGNAL_BUY;
}
else if(maFast < maSlow && rsi > 70 && macd > 0) {
signal = SIGNAL_STRONG_SELL;
}
else if(maFast < maSlow && rsi > 60) {
signal = SIGNAL_SELL;
}

// Execute based on signal using switch
switch(signal) {
case SIGNAL_STRONG_BUY:
OpenTrade(OP_BUY, InpLotSize * 1.5);
break;
case SIGNAL_BUY:
OpenTrade(OP_BUY, InpLotSize);
break;
case SIGNAL_STRONG_SELL:
OpenTrade(OP_SELL, InpLotSize * 1.5);
break;
case SIGNAL_SELL:
OpenTrade(OP_SELL, InpLotSize);
break;
default:
// Nested if for different market conditions
if(maFast > maSlow) {
Comment("Bullish but no entry condition");
} else if(maFast < maSlow) {
Comment("Bearish but no entry condition");
} else {
Comment("Sideways market - waiting");
}
break;
}
}

//+------------------------------------------------------------------+
//| Manage open positions |
//+------------------------------------------------------------------+
void ManageOpenPositions() {
for(int i = 0; i < OrdersTotal(); i++) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderMagicNumber() == InpMagic && OrderSymbol() == Symbol()) {
double profit = OrderProfit();
double currentPrice = (OrderType() == OP_BUY) ? Bid : Ask;
double profitPoints = 0;

if(OrderType() == OP_BUY) {
profitPoints = (currentPrice - OrderOpenPrice()) / Point();
} else {
profitPoints = (OrderOpenPrice() - currentPrice) / Point();
}

// Trailing stop logic with else-if
if(profitPoints >= 50) {
// Move to breakeven
double newStop = OrderOpenPrice();
if(ModifyStopLoss(OrderTicket(), newStop)) {
Print("Stop moved to breakeven");
}
}
else if(profitPoints >= 30) {
// Partial trail
double newStop = OrderOpenPrice() + (OrderType() == OP_BUY ? 10 * Point() : -10 * Point());
ModifyStopLoss(OrderTicket(), newStop);
}
else {
// Monitor only
Comment("Monitoring position: profit=", profitPoints, " points");
}
}
}
}
}

//+------------------------------------------------------------------+
//| Open trade with validation |
//+------------------------------------------------------------------+
void OpenTrade(int orderType, double lotSize) {
double price = (orderType == OP_BUY) ? Ask : Bid;
double stopLoss = 0;
double takeProfit = 0;

// Set stop loss and take profit using if-else
if(orderType == OP_BUY) {
stopLoss = price - 50 * Point();
takeProfit = price + 100 * Point();
} else {
stopLoss = price + 50 * Point();
takeProfit = price - 100 * Point();
}

// Validate stop loss distance using if
int stopLevel = (int)MarketInfo(Symbol(), MODE_STOPLEVEL);
double minDistance = stopLevel * Point();

if(orderType == OP_BUY && (price - stopLoss) < minDistance) {
Print("Stop loss too close - adjusting");
stopLoss = price - minDistance;
}
else if(orderType == OP_SELL && (stopLoss - price) < minDistance) {
Print("Stop loss too close - adjusting");
stopLoss = price + minDistance;
}

// Execute order
int ticket = OrderSend(Symbol(), orderType, lotSize, price, 30, stopLoss, takeProfit, "Conditional EA", InpMagic, 0, clrNONE);

// Handle result using if-else
if(ticket > 0) {
g_dailyTradeCount++;
Print("Order opened successfully. Ticket: ", ticket);
} else {
int error = GetLastError();
Print("Order failed. Error: ", error);

// Handle specific errors using switch
switch(error) {
case 130:
Print("Invalid stops - check broker requirements");
break;
case 134:
Print("Not enough money - reduce lot size");
break;
default:
Print("Unknown error - check logs");
break;
}
}
}
```

Conditional Statements Best Practices Checklist
  • [ ] Always use braces {} even for single-line if bodies

  • [ ] Keep conditions simple and readable (use parentheses for clarity)

  • [ ] Avoid deep nesting (more than 3 levels) - refactor into functions

  • [ ] Use else-if chains for mutually exclusive conditions

  • [ ] Use switch for discrete value comparisons (enums, error codes)

  • [ ] Always include a default case in switch statements

  • [ ] Place the most likely condition first in else-if chains for efficiency

  • [ ] Use comments to explain complex conditional logic

  • [ ] Test all branches of your conditional statements with different market scenarios


  • Reference:
  • MetaQuotes Ltd. "MQL4 Documentation - Conditional Operators" (2024)

  • McConnell, Steve. "Code Complete" (2004)


  • 9. Next Step
    Part 9 will explain Loop Structures in MQL4 (for/while/do-while) – Complete guide to batch processing orders, array traversal, and repetitive tasks with practical EA examples.