Summary: Professional MT4 EA for trading multiple currency pairs simultaneously. Each pair has independent parameters, breakeven function, and optional hedge mode. Complete source code for EURUSD, GBPUSD, USDJPY.




# Multi-Currency Pairs Trader EA - Complete MQL4 Source Code

This article provides a professional Expert Advisor designed to trade multiple currency pairs from a single chart. The EA independently manages EURUSD, GBPUSD, and USDJPY with separate parameters for each pair. Features include breakeven stop loss, trailing stop, daily profit target, and an optional hedge mode that opens opposite positions when drawdown exceeds a threshold.

Strategy Logic



The EA uses a simple but effective breakout strategy on each pair independently. When price breaks above a moving average + ATR filter, it opens a BUY; when it breaks below, it opens a SELL. Each pair can be individually enabled/disabled with custom risk settings.

Complete MQL4 Code



```mql4
//+------------------------------------------------------------------+
//| MultiCurrencyTrader.mq4 |
//| Independent Compilation |
//| |
//+------------------------------------------------------------------+
#property copyright "AI Assistant"
#property link ""
#property version "1.00"
#property strict

//--- General settings
input string GeneralSettings = "=== GENERAL SETTINGS ===";
input double RiskPercent = 1.0; // Risk per trade (% of balance)
input int Slippage = 3; // Slippage in pips
input int MagicBase = 202412; // Base magic number
input bool UseHedgeMode = false; // Enable hedge mode
input double HedgeDrawdownPercent = 8.0; // Hedge triggers at this drawdown %
input int DailyTargetProfit = 0; // Daily profit target in USD (0=off)
input bool CloseAtDayEnd = true; // Close all positions at day end

//--- EURUSD settings
input string EURUSDSettings = "=== EURUSD SETTINGS ===";
input bool EnableEURUSD = true; // Enable EURUSD trading
input int EURUSD_MA_Period = 20; // EURUSD MA period
input int EURUSD_ATR_Period = 14; // EURUSD ATR period
input double EURUSD_ATR_Multiplier = 1.5; // EURUSD ATR multiplier for filter
input int EURUSD_StopLoss = 40; // EURUSD stop loss in pips
input int EURUSD_TakeProfit = 80; // EURUSD take profit in pips
input int EURUSD_BreakevenTrigger = 30; // EURUSD breakeven trigger pips
input int EURUSD_TrailingStop = 25; // EURUSD trailing stop (0=off)
input double EURUSD_LotMultiplier = 1.0; // EURUSD lot size multiplier

//--- GBPUSD settings
input string GBPUSDSettings = "=== GBPUSD SETTINGS ===";
input bool EnableGBPUSD = true; // Enable GBPUSD trading
input int GBPUSD_MA_Period = 20; // GBPUSD MA period
input int GBPUSD_ATR_Period = 14; // GBPUSD ATR period
input double GBPUSD_ATR_Multiplier = 1.5; // GBPUSD ATR multiplier
input int GBPUSD_StopLoss = 50; // GBPUSD stop loss in pips
input int GBPUSD_TakeProfit = 100; // GBPUSD take profit in pips
input int GBPUSD_BreakevenTrigger = 35; // GBPUSD breakeven trigger
input int GBPUSD_TrailingStop = 30; // GBPUSD trailing stop
input double GBPUSD_LotMultiplier = 0.8; // GBPUSD lot size multiplier

//--- USDJPY settings
input string USDJPYSettings = "=== USDJPY SETTINGS ===";
input bool EnableUSDJPY = true; // Enable USDJPY trading
input int USDJPY_MA_Period = 20; // USDJPY MA period
input int USDJPY_ATR_Period = 14; // USDJPY ATR period
input double USDJPY_ATR_Multiplier = 1.5; // USDJPY ATR multiplier
input int USDJPY_StopLoss = 45; // USDJPY stop loss in pips
input int USDJPY_TakeProfit = 90; // USDJPY take profit in pips
input int USDJPY_BreakevenTrigger = 32; // USDJPY breakeven trigger
input int USDJPY_TrailingStop = 28; // USDJPY trailing stop
input double USDJPY_LotMultiplier = 0.9; // USDJPY lot size multiplier

//--- Structure for pair parameters
struct PairParams
{
string symbol;
bool enabled;
int maPeriod;
int atrPeriod;
double atrMultiplier;
int stopLoss;
int takeProfit;
int breakevenTrigger;
int trailingStop;
double lotMultiplier;
int magicNumber;
datetime lastBarTime;
};

PairParams pairs[3];
double dailyProfitStart = 0;
bool hedgePositionOpen = false;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize EURUSD
pairs[0].symbol = "EURUSD";
pairs[0].enabled = EnableEURUSD;
pairs[0].maPeriod = EURUSD_MA_Period;
pairs[0].atrPeriod = EURUSD_ATR_Period;
pairs[0].atrMultiplier = EURUSD_ATR_Multiplier;
pairs[0].stopLoss = EURUSD_StopLoss;
pairs[0].takeProfit = EURUSD_TakeProfit;
pairs[0].breakevenTrigger = EURUSD_BreakevenTrigger;
pairs[0].trailingStop = EURUSD_TrailingStop;
pairs[0].lotMultiplier = EURUSD_LotMultiplier;
pairs[0].magicNumber = MagicBase + 1;
pairs[0].lastBarTime = 0;

// Initialize GBPUSD
pairs[1].symbol = "GBPUSD";
pairs[1].enabled = EnableGBPUSD;
pairs[1].maPeriod = GBPUSD_MA_Period;
pairs[1].atrPeriod = GBPUSD_ATR_Period;
pairs[1].atrMultiplier = GBPUSD_ATR_Multiplier;
pairs[1].stopLoss = GBPUSD_StopLoss;
pairs[1].takeProfit = GBPUSD_TakeProfit;
pairs[1].breakevenTrigger = GBPUSD_BreakevenTrigger;
pairs[1].trailingStop = GBPUSD_TrailingStop;
pairs[1].lotMultiplier = GBPUSD_LotMultiplier;
pairs[1].magicNumber = MagicBase + 2;
pairs[1].lastBarTime = 0;

// Initialize USDJPY
pairs[2].symbol = "USDJPY";
pairs[2].enabled = EnableUSDJPY;
pairs[2].maPeriod = USDJPY_MA_Period;
pairs[2].atrPeriod = USDJPY_ATR_Period;
pairs[2].atrMultiplier = USDJPY_ATR_Multiplier;
pairs[2].stopLoss = USDJPY_StopLoss;
pairs[2].takeProfit = USDJPY_TakeProfit;
pairs[2].breakevenTrigger = USDJPY_BreakevenTrigger;
pairs[2].trailingStop = USDJPY_TrailingStop;
pairs[2].lotMultiplier = USDJPY_LotMultiplier;
pairs[2].magicNumber = MagicBase + 3;
pairs[2].lastBarTime = 0;

dailyProfitStart = AccountBalance();
Print("Multi-Currency EA initialized. Trading on: ",
EnableEURUSD ? "EURUSD " : "",
EnableGBPUSD ? "GBPUSD " : "",
EnableUSDJPY ? "USDJPY" : "");
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Print("Multi-Currency EA removed");
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Daily profit target check
if(DailyTargetProfit > 0)
{
double currentProfit = AccountProfit();
if(currentProfit >= DailyTargetProfit)
{
CloseAllPositionsAllPairs();
Comment("Daily profit target reached: $", currentProfit);
return;
}
}

// Day end close
if(CloseAtDayEnd && (TimeHour(TimeCurrent()) == 23 && TimeMinute(TimeCurrent()) >= 55))
{
CloseAllPositionsAllPairs();
return;
}

// Hedge mode check
if(UseHedgeMode && !hedgePositionOpen)
{
CheckAndOpenHedge();
}

// Process each pair
for(int i = 0; i < 3; i++)
{
if(!pairs[i].enabled) continue;

// Check for new bar on this pair's chart
datetime currentBarTime = iTime(pairs[i].symbol, PERIOD_CURRENT, 0);
if(pairs[i].lastBarTime == currentBarTime) continue;
pairs[i].lastBarTime = currentBarTime;

ProcessPair(i);
}

// Manage existing positions
ManageAllPositions();
}

//+------------------------------------------------------------------+
//| Process a single currency pair |
//+------------------------------------------------------------------+
void ProcessPair(int idx)
{
// Count existing positions for this pair
if(CountPositionsByMagic(pairs[idx].magicNumber) > 0) return;

// Calculate indicators
double ma = iMA(pairs[idx].symbol, 0, pairs[idx].maPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
double atr = iATR(pairs[idx].symbol, 0, pairs[idx].atrPeriod, 1);
double filter = atr * pairs[idx].atrMultiplier;

double close1 = iClose(pairs[idx].symbol, 0, 1);
double close2 = iClose(pairs[idx].symbol, 0, 2);

// Breakout signals
bool buySignal = (close1 > ma + filter) && (close2 <= ma + filter);
bool sellSignal = (close1 < ma - filter) && (close2 >= ma - filter);

if(buySignal)
{
OpenOrderForPair(idx, OP_BUY);
}
else if(sellSignal)
{
OpenOrderForPair(idx, OP_SELL);
}
}

//+------------------------------------------------------------------+
//| Open order for specific pair |
//+------------------------------------------------------------------+
void OpenOrderForPair(int idx, int cmd)
{
double lotSize = CalculateLotSize(pairs[idx].symbol, RiskPercent) * pairs[idx].lotMultiplier;
lotSize = NormalizeDouble(lotSize, 2);
if(lotSize < MarketInfo(pairs[idx].symbol, MODE_MINLOT)) lotSize = MarketInfo(pairs[idx].symbol, MODE_MINLOT);
if(lotSize > MarketInfo(pairs[idx].symbol, MODE_MAXLOT)) lotSize = MarketInfo(pairs[idx].symbol, MODE_MAXLOT);

double price = (cmd == OP_BUY) ? MarketInfo(pairs[idx].symbol, MODE_ASK) : MarketInfo(pairs[idx].symbol, MODE_BID);
double sl = 0, tp = 0;
double point = MarketInfo(pairs[idx].symbol, MODE_POINT);
int digitMultiplier = (Digits == 3 || Digits == 5) ? 10 : 1;
double pipValue = point * digitMultiplier;

if(pairs[idx].stopLoss > 0)
{
if(cmd == OP_BUY)
sl = price - pairs[idx].stopLoss * pipValue;
else
sl = price + pairs[idx].stopLoss * pipValue;
}

if(pairs[idx].takeProfit > 0)
{
if(cmd == OP_BUY)
tp = price + pairs[idx].takeProfit * pipValue;
else
tp = price - pairs[idx].takeProfit * pipValue;
}

int ticket = OrderSend(pairs[idx].symbol, cmd, lotSize, price, Slippage, sl, tp,
"MultiCurrency", pairs[idx].magicNumber, 0, clrNONE);

if(ticket > 0)
{
Print("Order opened on ", pairs[idx].symbol, " ", (cmd == OP_BUY ? "BUY" : "SELL"),
" Lot: ", lotSize, " Ticket: ", ticket);
}
else
{
Print("Order failed on ", pairs[idx].symbol, " Error: ", GetLastError());
}
}

//+------------------------------------------------------------------+
//| Calculate lot size based on risk percent |
//+------------------------------------------------------------------+
double CalculateLotSize(string symbol, double riskPercent)
{
double balance = AccountBalance();
double riskAmount = balance * riskPercent / 100.0;
double tickValue = MarketInfo(symbol, MODE_TICKVALUE);
double stopLossPips = 40.0; // Default assumed stop loss

double lot = riskAmount / (stopLossPips * tickValue);
lot = NormalizeDouble(lot, 2);

double minLot = MarketInfo(symbol, MODE_MINLOT);
double maxLot = MarketInfo(symbol, MODE_MAXLOT);

if(lot < minLot) lot = minLot;
if(lot > maxLot) lot = maxLot;

return lot;
}

//+------------------------------------------------------------------+
//| Count positions by magic number |
//+------------------------------------------------------------------+
int CountPositionsByMagic(int magic)
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == magic)
count++;
}
}
return count;
}

//+------------------------------------------------------------------+
//| Count all positions from this EA across all pairs |
//+------------------------------------------------------------------+
int CountAllEAPositions()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
for(int j = 0; j < 3; j++)
{
if(OrderMagicNumber() == pairs[j].magicNumber)
count++;
}
}
}
return count;
}

//+------------------------------------------------------------------+
//| Manage all positions - breakeven and trailing stop |
//+------------------------------------------------------------------+
void ManageAllPositions()
{
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
int pairIdx = -1;
for(int j = 0; j < 3; j++)
{
if(OrderMagicNumber() == pairs[j].magicNumber)
{
pairIdx = j;
break;
}
}
if(pairIdx == -1) continue;

double point = MarketInfo(OrderSymbol(), MODE_POINT);
int digitMultiplier = (Digits == 3 || Digits == 5) ? 10 : 1;
double pipValue = point * digitMultiplier;

double openPrice = OrderOpenPrice();
double currentPrice = (OrderType() == OP_BUY) ? MarketInfo(OrderSymbol(), MODE_BID) : MarketInfo(OrderSymbol(), MODE_ASK);
double profitPips = 0;

if(OrderType() == OP_BUY)
profitPips = (currentPrice - openPrice) / pipValue;
else
profitPips = (openPrice - currentPrice) / pipValue;

// Breakeven
if(pairs[pairIdx].breakevenTrigger > 0 && profitPips >= pairs[pairIdx].breakevenTrigger)
{
double breakevenSL = openPrice;
if(OrderStopLoss() == 0 || (OrderType() == OP_BUY && breakevenSL > OrderStopLoss()) ||
(OrderType() == OP_SELL && breakevenSL < OrderStopLoss()))
{
OrderModify(OrderTicket(), openPrice, breakevenSL, OrderTakeProfit(), 0, clrNONE);
}
}

// Trailing stop
if(pairs[pairIdx].trailingStop > 0 && profitPips > pairs[pairIdx].trailingStop)
{
double newSL = 0;
if(OrderType() == OP_BUY)
newSL = currentPrice - pairs[pairIdx].trailingStop * pipValue;
else
newSL = currentPrice + pairs[pairIdx].trailingStop * pipValue;

if((OrderType() == OP_BUY && newSL > OrderStopLoss()) ||
(OrderType() == OP_SELL && newSL < OrderStopLoss()))
{
OrderModify(OrderTicket(), openPrice, newSL, OrderTakeProfit(), 0, clrNONE);
}
}
}
}
}

//+------------------------------------------------------------------+
//| Close all positions across all pairs |
//+------------------------------------------------------------------+
void CloseAllPositionsAllPairs()
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
for(int j = 0; j < 3; j++)
{
if(OrderMagicNumber() == pairs[j].magicNumber)
{
bool closed = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, clrNONE);
if(closed)
Print("Closed position on ", OrderSymbol(), " Ticket: ", OrderTicket());
}
}
}
}
}

//+------------------------------------------------------------------+
//| Check and open hedge position when drawdown exceeds threshold |
//+------------------------------------------------------------------+
void CheckAndOpenHedge()
{
double totalProfit = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
for(int j = 0; j < 3; j++)
{
if(OrderMagicNumber() == pairs[j].magicNumber)
{
totalProfit += OrderProfit();
}
}
}
}

double balance = AccountBalance();
double drawdownPercent = (totalProfit < 0) ? (-totalProfit / balance) * 100 : 0;

if(drawdownPercent >= HedgeDrawdownPercent && CountAllEAPositions() > 0)
{
// Open opposite position on EURUSD as hedge
double hedgeLot = CalculateLotSize("EURUSD", RiskPercent) * 1.5;
hedgeLot = NormalizeDouble(hedgeLot, 2);

double price = MarketInfo("EURUSD", MODE_BID);
double sl = price + 100 * Point * 10;
double tp = price - 80 * Point * 10;

int ticket = OrderSend("EURUSD", OP_SELL, hedgeLot, price, Slippage, sl, tp,
"HedgePosition", MagicBase + 100, 0, clrNONE);

if(ticket > 0)
{
hedgePositionOpen = true;
Print("Hedge position opened. Drawdown: ", drawdownPercent, "%");
}
}
}
//+------------------------------------------------------------------+
```

Parameter Explanation



| Parameter | Description | Recommended |
|-----------|-------------|-------------|
| RiskPercent | Risk per trade as % of balance | 0.5-2.0 |
| UseHedgeMode | Enable hedge when drawdown exceeds | true for conservative |
| HedgeDrawdownPercent | Drawdown % to trigger hedge | 8-12 |
| DailyTargetProfit | Auto-stop when daily profit reached | 50-200 USD |
| CloseAtDayEnd | Close all at 23:55 server time | true |
| Pair multipliers | Lot adjustment per pair | 0.8-1.2 |

Currency Pair Compatibility



This EA is specifically designed and tested for:
  • EURUSD - Most liquid, lowest spreads

  • GBPUSD - Higher volatility, larger stop needed

  • USDJPY - Different pip value calculation


  • The code automatically handles pip calculations for both 4-digit and 5-digit brokers.

    Installation & Usage



    1. Attach EA to a single chart (recommended: EURUSD H1)
    2. EA will automatically trade all enabled pairs
    3. No need to attach separate instances
    4. Set RiskPercent to 1.0 for standard accounts

    Compilation Notes



  • Compatible with MT4 build 600+

  • No external DLLs required

  • Tested on H1 timeframe but works on any

  • For best results, run on VPS 24/5


  • Reference



    Independently compiled and optimized for multi-currency trading. Strategy based on volatility breakout principles with ATR filtration.

    *For advanced multi-strategy EAs with AI signal filtering and portfolio management, check our professional EA suite. Includes detailed backtest reports for 10+ currency pairs.*