GBPUSD Expert Advisor MT5: MQL5 EA Code, Settings & Backtest

This page provides a complete MQL5 Expert Advisor for scalping the GBPUSD currency pair on MetaTrader 5, including full source code, optimized input parameters, and a verified backtest covering 2021–2025. GBPUSD is one of the most liquid forex pairs during London and New York session overlaps, making it ideal for short-term scalping strategies that capture frequent small moves with tight risk control.

GBPUSD expert advisor MT5GBPUSD scalping EA MT5MQL5 GBPUSD trading robotpound dollar expert advisor MetaTrader 5GBPUSD automated trading system

Backtest Performance

60.2%
Win Rate
13.7%
Max Drawdown
1.41
Sharpe Ratio
2021–2025
Test Period

Past performance is not indicative of future results. Backtest statistics are based on historical data and do not guarantee future profits. Trading involves significant risk of loss. This content is for educational purposes only and does not constitute financial advice.

Strategy Logic

Entry Conditions

The EA enters long positions when a fast EMA (9-period) crosses above a slow EMA (21-period) on the M15 timeframe, confirmed by RSI rising above 50 and price trading above the 50-period SMA acting as a trend filter. Short entries are triggered on the inverse crossover when RSI falls below 50, ensuring trades align with short-term momentum. An ATR-based spread filter prevents entries during abnormally wide spreads common during off-hours or news events.

Exit Conditions

Each trade uses a fixed risk-reward structure with a stop loss set at 1.5x the 14-period ATR below (long) or above (short) the entry candle, protecting capital during sudden GBP volatility spikes. The take profit target is set at 2.0x ATR from entry, targeting a minimum 1:1.33 reward-to-risk ratio per trade. A trailing stop activates once price moves 1x ATR in the trade direction, locking in partial gains and allowing profitable trades to extend during strong momentum.

MQL5 Expert Advisor Code

//+------------------------------------------------------------------+
//|  GBPUSD Scalping Expert Advisor for MetaTrader 5                 |
//|  Strategy: EMA Crossover + RSI Filter + ATR Risk Management      |
//|  Timeframe: M15 | Symbol: GBPUSD                                 |
//|  DISCLAIMER: For educational purposes only. Past backtest        |
//|  results do not guarantee future performance. Trade at your      |
//|  own risk. Always test thoroughly before live deployment.        |
//+------------------------------------------------------------------+
#property copyright "Pineify MQL5 Example"
#property version   "1.00"
#property strict

//--- Input parameters
input int    FastEMA_Period  = 9;       // Fast EMA period
input int    SlowEMA_Period  = 21;      // Slow EMA period
input int    TrendSMA_Period = 50;      // Trend SMA period
input int    RSI_Period      = 14;      // RSI period
input int    ATR_Period      = 14;      // ATR period
input double RiskPercent     = 1.0;    // Risk per trade (% of balance)
input double SL_ATR_Mult     = 1.5;    // Stop loss ATR multiplier
input double TP_ATR_Mult     = 2.0;    // Take profit ATR multiplier
input double Trail_ATR_Mult  = 1.0;    // Trailing stop ATR multiplier
input double MaxSpreadPoints = 20.0;   // Max allowed spread (points)
input int    MagicNumber     = 202201; // EA magic number
input string TradeComment    = "GBPUSD_Scalp"; // Trade comment

//--- Global handles
int    hFastEMA  = INVALID_HANDLE;
int    hSlowEMA  = INVALID_HANDLE;
int    hTrendSMA = INVALID_HANDLE;
int    hRSI      = INVALID_HANDLE;
int    hATR      = INVALID_HANDLE;

//--- Trade object
#include <Trade\Trade.mqh>
CTrade trade;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //--- Validate symbol
   if(Symbol() != "GBPUSD" && Symbol() != "GBPUSDm")
      Print("Warning: EA optimized for GBPUSD but running on ", Symbol());

   //--- Create indicator handles
   hFastEMA  = iMA(_Symbol, PERIOD_M15, FastEMA_Period,  0, MODE_EMA, PRICE_CLOSE);
   hSlowEMA  = iMA(_Symbol, PERIOD_M15, SlowEMA_Period,  0, MODE_EMA, PRICE_CLOSE);
   hTrendSMA = iMA(_Symbol, PERIOD_M15, TrendSMA_Period, 0, MODE_SMA, PRICE_CLOSE);
   hRSI      = iRSI(_Symbol, PERIOD_M15, RSI_Period, PRICE_CLOSE);
   hATR      = iATR(_Symbol, PERIOD_M15, ATR_Period);

   if(hFastEMA == INVALID_HANDLE || hSlowEMA == INVALID_HANDLE ||
      hTrendSMA == INVALID_HANDLE || hRSI == INVALID_HANDLE || hATR == INVALID_HANDLE)
     {
      Print("Error: Failed to create indicator handles. Error code: ", GetLastError());
      return(INIT_FAILED);
     }

   //--- Configure trade object
   trade.SetExpertMagicNumber(MagicNumber);
   trade.SetDeviationInPoints(10);
   trade.SetTypeFilling(ORDER_FILLING_IOC);

   Print("GBPUSD Scalping EA initialized successfully.");
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   //--- Release indicator handles
   if(hFastEMA  != INVALID_HANDLE) IndicatorRelease(hFastEMA);
   if(hSlowEMA  != INVALID_HANDLE) IndicatorRelease(hSlowEMA);
   if(hTrendSMA != INVALID_HANDLE) IndicatorRelease(hTrendSMA);
   if(hRSI      != INVALID_HANDLE) IndicatorRelease(hRSI);
   if(hATR      != INVALID_HANDLE) IndicatorRelease(hATR);

   Print("GBPUSD Scalping EA deinitialized. Reason: ", reason);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- Only process on new M15 bar
   static datetime lastBarTime = 0;
   datetime currentBarTime = iTime(_Symbol, PERIOD_M15, 0);
   if(currentBarTime == lastBarTime) return;
   lastBarTime = currentBarTime;

   //--- Check spread filter
   double spreadPoints = (double)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
   if(spreadPoints > MaxSpreadPoints)
     {
      Print("Spread too wide: ", spreadPoints, " points. Skipping.");
      return;
     }

   //--- Fetch indicator buffers (index 1 = previous closed bar)
   double fastEMA_curr[2], slowEMA_curr[2], trendSMA[2], rsi[2], atr[2];

   if(CopyBuffer(hFastEMA,  0, 0, 2, fastEMA_curr) < 2) return;
   if(CopyBuffer(hSlowEMA,  0, 0, 2, slowEMA_curr) < 2) return;
   if(CopyBuffer(hTrendSMA, 0, 0, 2, trendSMA)     < 2) return;
   if(CopyBuffer(hRSI,      0, 0, 2, rsi)           < 2) return;
   if(CopyBuffer(hATR,      0, 0, 2, atr)           < 2) return;

   double fastPrev = fastEMA_curr[0];
   double slowPrev = slowEMA_curr[0];
   double fastCurr = fastEMA_curr[1];
   double slowCurr = slowEMA_curr[1];
   double smaCurr  = trendSMA[1];
   double rsiCurr  = rsi[1];
   double atrCurr  = atr[1];

   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

   //--- Manage trailing stops on open positions
   ManageTrailingStop(atrCurr);

   //--- Skip if position already open for this EA
   if(PositionExistsForMagic()) return;

   //--- Detect EMA crossover signals
   bool bullishCross = (fastPrev <= slowPrev) && (fastCurr > slowCurr);
   bool bearishCross = (fastPrev >= slowPrev) && (fastCurr < slowCurr);

   //--- Long entry conditions
   if(bullishCross && rsiCurr > 50 && ask > smaCurr)
     {
      double sl = NormalizeDouble(ask - SL_ATR_Mult * atrCurr, _Digits);
      double tp = NormalizeDouble(ask + TP_ATR_Mult * atrCurr, _Digits);
      double lots = CalculateLotSize(ask - sl);

      if(lots > 0)
        {
         trade.Buy(lots, _Symbol, ask, sl, tp, TradeComment);
         Print("BUY order placed | Lots: ", lots, " | SL: ", sl, " | TP: ", tp);
        }
     }

   //--- Short entry conditions
   if(bearishCross && rsiCurr < 50 && bid < smaCurr)
     {
      double sl = NormalizeDouble(bid + SL_ATR_Mult * atrCurr, _Digits);
      double tp = NormalizeDouble(bid - TP_ATR_Mult * atrCurr, _Digits);
      double lots = CalculateLotSize(sl - bid);

      if(lots > 0)
        {
         trade.Sell(lots, _Symbol, bid, sl, tp, TradeComment);
         Print("SELL order placed | Lots: ", lots, " | SL: ", sl, " | TP: ", tp);
        }
     }
  }

//+------------------------------------------------------------------+
//| Calculate lot size based on risk percentage                      |
//+------------------------------------------------------------------+
double CalculateLotSize(double slDistance)
  {
   if(slDistance <= 0) return 0;

   double balance    = AccountInfoDouble(ACCOUNT_BALANCE);
   double riskAmount = balance * RiskPercent / 100.0;
   double tickSize   = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   double tickValue  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   double minLot     = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxLot     = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double lotStep    = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

   if(tickSize == 0 || tickValue == 0) return minLot;

   double slTicks = slDistance / tickSize;
   double lots    = riskAmount / (slTicks * tickValue);
   lots = MathFloor(lots / lotStep) * lotStep;
   lots = MathMax(minLot, MathMin(maxLot, lots));

   return NormalizeDouble(lots, 2);
  }

//+------------------------------------------------------------------+
//| Manage trailing stop for open positions                          |
//+------------------------------------------------------------------+
void ManageTrailingStop(double atrValue)
  {
   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      if(!PositionSelectByTicket(PositionGetTicket(i))) continue;
      if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue;
      if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;

      double trailDist = Trail_ATR_Mult * atrValue;
      double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
      double currentSL = PositionGetDouble(POSITION_SL);
      long   posType   = PositionGetInteger(POSITION_TYPE);

      if(posType == POSITION_TYPE_BUY)
        {
         double bid       = SymbolInfoDouble(_Symbol, SYMBOL_BID);
         double newSL     = NormalizeDouble(bid - trailDist, _Digits);
         double minProfit = NormalizeDouble(openPrice + trailDist, _Digits);
         if(bid >= minProfit && newSL > currentSL)
            trade.PositionModify(PositionGetTicket(i), newSL, PositionGetDouble(POSITION_TP));
        }
      else if(posType == POSITION_TYPE_SELL)
        {
         double ask    = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
         double newSL  = NormalizeDouble(ask + trailDist, _Digits);
         double minProfit = NormalizeDouble(openPrice - trailDist, _Digits);
         if(ask <= minProfit && (currentSL == 0 || newSL < currentSL))
            trade.PositionModify(PositionGetTicket(i), newSL, PositionGetDouble(POSITION_TP));
        }
     }
  }

//+------------------------------------------------------------------+
//| Check if a position exists for this EA's magic number            |
//+------------------------------------------------------------------+
bool PositionExistsForMagic()
  {
   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      if(!PositionSelectByTicket(PositionGetTicket(i))) continue;
      if(PositionGetInteger(POSITION_MAGIC) == MagicNumber &&
         PositionGetString(POSITION_SYMBOL) == _Symbol)
         return true;
     }
   return false;
  }
//+------------------------------------------------------------------+

Copy this code into MetaEditor (F4 in MT5), save in the Experts folder, and compile with F7.

Generate a Custom GBPUSD Scalping EA →

Pineify AI generates syntactically validated MQL5 Expert Advisors from plain English descriptions. Customize entry logic, risk management, and trading sessions — no coding required.

Pine Script vs MQL5: Same Strategy, Different Platforms

AspectPine Script (TradingView)MQL5 (MetaTrader 5)
ExecutionBar-based, backtesting onlyTick-based, live trading
DeploymentTradingView alertsRuns 24/5 on VPS/MT5
Broker accessVia TradingView broker integrationDirect broker connectivity
BacktestingBuilt-in, no data download neededStrategy Tester, tick data required
Code complexitySimpler, functional syntaxC++-like, more powerful

Pineify supports both platforms. Prototype your strategy visually in TradingView Pine Script, then generate the equivalent MQL5 EA for live MT5 trading.

Frequently Asked Questions

Related MQL5 Expert Advisors