Complete .mq5 source code

Gold Scalping EA MT5: XAUUSD M5 Code and Testing Guide

Read an educational MQL5 EA using an M5 candle-body/EMA condition, initial ATR stops and spread/session entry filters. The example has no news-calendar filter or trailing stop. Compile and test its order handling and broker-specific gold contract settings; no verified backtest results are supplied.

Strategy logic

Entry conditions

On a completed M5 candle, request a buy when its open is below EMA 20 and close is above that same completed-bar EMA; reverse for a sell. This is a candle-body test, not a comparison of two consecutive closes. Check quoted ask-minus-bid spread in broker points, separately from ATR. Session hours use broker server time, with the default 08:00–17:00 interval; they are not automatically London or New York hours. One evaluated entry attempt is allowed per M5 bar.

Exit conditions

Request initial SL at 1 ATR and TP at 1.5 ATR from the entry quote using the completed M5 ATR. The example does not trail stops, close at session end, or detect and exit before news. Existing broker-side stops remain subject to execution and gaps. Fixed lots do not keep monetary risk constant. IOC support, volume/tick grids, stops/freeze levels and account-mode exposure must be checked before use.

MQL5 Expert Advisor Code

//+------------------------------------------------------------------+
//| Gold Scalping EA - XAUUSD M5                                     |
//| Generated by Pineify AI | pineify.app                           |
//+------------------------------------------------------------------+
#property copyright "Pineify.app"
#property version   "1.00"
#property strict

// Input parameters
input int    MagicNumber  = 123456;
input double Lots         = 0.01;
input int    ATR_Period   = 14;
input double ATR_SL_Mult  = 1.0;
input double ATR_TP_Mult  = 1.5;
input int    MaxSpread    = 30;   // Max spread in points
input int    SessionStart = 8;    // Hour (server time)
input int    SessionEnd   = 17;   // Hour (server time)

int    emaHandle=INVALID_HANDLE;
int    atrHandle=INVALID_HANDLE;
double emaBuffer[];
double atrBuffer[];

int OnInit() {
   if(MagicNumber<0 || Lots<=0 || ATR_Period<1 || ATR_SL_Mult<=0 || ATR_TP_Mult<=0 || MaxSpread<0 ||
      SessionStart<0 || SessionStart>23 || SessionEnd<0 || SessionEnd>23 || SessionStart==SessionEnd)
      return INIT_PARAMETERS_INCORRECT;
   emaHandle = iMA(_Symbol, PERIOD_M5, 20, 0, MODE_EMA, PRICE_CLOSE);
   atrHandle = iATR(_Symbol, PERIOD_M5, ATR_Period);
   if (emaHandle == INVALID_HANDLE || atrHandle == INVALID_HANDLE) return INIT_FAILED;
   ArraySetAsSeries(emaBuffer, true);
   ArraySetAsSeries(atrBuffer, true);
   return INIT_SUCCEEDED;
}

void OnDeinit(const int reason) {
   if(emaHandle!=INVALID_HANDLE) IndicatorRelease(emaHandle);
   if(atrHandle!=INVALID_HANDLE) IndicatorRelease(atrHandle);
}

void OnTick() {
   MqlTick tick;
   if (!SymbolInfoTick(_Symbol, tick)) return;

   // Session filter
   MqlDateTime dt;
   if(!TimeToStruct(tick.time, dt)) return;
   bool inSession = SessionStart<SessionEnd ? (dt.hour>=SessionStart && dt.hour<SessionEnd)
                                           : (dt.hour>=SessionStart || dt.hour<SessionEnd);
   if(!inSession) return;

   // Spread filter
   double spread = (tick.ask - tick.bid) / _Point;
   if (spread<0 || spread > MaxSpread) return;
   static datetime lastBar=0;
   datetime currentBar=iTime(_Symbol, PERIOD_M5, 0);
   if(currentBar<=0 || currentBar==lastBar) return;

   // Get indicator values
   if (CopyBuffer(emaHandle, 0, 0, 3, emaBuffer) < 3) return;
   if (CopyBuffer(atrHandle, 0, 0, 3, atrBuffer) < 3) return;

   double atr = atrBuffer[1];
   double ema = emaBuffer[1];
   double prevClose = iClose(_Symbol, PERIOD_M5, 1);
   double prevOpen  = iOpen(_Symbol, PERIOD_M5, 1);

   if(atr<=0 || !MathIsValidNumber(atr) || prevOpen<=0 || prevClose<=0) return;
   lastBar=currentBar;

   // Count open positions
   int pos = CountPositions(MagicNumber);
   if (pos > 0) return;

   double sl = atr * ATR_SL_Mult;
   double tp = atr * ATR_TP_Mult;

   // Long entry: close crosses above EMA
   if (prevClose > ema && prevOpen < ema) {
      OpenTrade(ORDER_TYPE_BUY, Lots, sl, tp, MagicNumber);
   }
   // Short entry: close crosses below EMA
   else if (prevClose < ema && prevOpen > ema) {
      OpenTrade(ORDER_TYPE_SELL, Lots, sl, tp, MagicNumber);
   }
}

int CountPositions(int magic) {
   int count = 0;
   for (int i = PositionsTotal() - 1; i >= 0; i--) {
      ulong ticket = PositionGetTicket(i);
      if (PositionSelectByTicket(ticket) &&
          PositionGetString(POSITION_SYMBOL) == _Symbol &&
          (int)PositionGetInteger(POSITION_MAGIC) == magic) count++;
   }
   return count;
}

void OpenTrade(ENUM_ORDER_TYPE type, double lots, double sl, double tp, int magic) {
   MqlTradeRequest req = {};
   MqlTradeResult  res = {};
   req.action    = TRADE_ACTION_DEAL;
   req.symbol    = _Symbol;
   req.volume    = lots;
   req.type      = type;
   req.price     = (type == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK)
                                             : SymbolInfoDouble(_Symbol, SYMBOL_BID);
   req.sl        = (type == ORDER_TYPE_BUY) ? req.price - sl : req.price + sl;
   req.tp        = (type == ORDER_TYPE_BUY) ? req.price + tp : req.price - tp;
   req.magic     = magic;
   req.comment   = "Pineify Gold Scalper";
   req.type_filling = ORDER_FILLING_IOC;
   req.sl=NormalizeDouble(req.sl,_Digits);
   req.tp=NormalizeDouble(req.tp,_Digits);
   if(!OrderSend(req,res) || (res.retcode!=TRADE_RETCODE_DONE && res.retcode!=TRADE_RETCODE_DONE_PARTIAL))
      PrintFormat("Gold scalper request failed: %u %s",res.retcode,res.comment);
}

Copy this code into MetaEditor, save it in the MQL5/Experts folder, and compile with F7.

Generate a custom XAUUSD scalping EA

Describe the entry, exit, position, order, and risk rules you want. Pineify generates editable MQL5 source code that you can inspect and compile in MetaEditor.

Pine Script vs MQL5: Same Strategy, Different Platforms

AspectPine Script (TradingView)MQL5 (MetaTrader 5)
ExecutionSeries evaluated on chart updatesEvent handlers with explicit buffers
DeploymentRuns in TradingView with alertsRuns in the MT5 terminal or on a VPS
Broker accessStrategy orders are simulated; live automation needs a separate integrationDirect broker connectivity
BacktestingStrategy Tester for strategy scriptsStrategy Tester for Expert Advisors
Code complexitySimpler, functional syntaxC++-like, more powerful

The calculation can be implemented on either platform, but the runtime model and buffer APIs differ.

Frequently Asked Questions

Related MQL5 pages

Technical references

Risk and testing note

These educational examples require independent compilation and testing. A compile pass or an illustrative setting does not establish execution correctness or profitability. Any reported performance must be supported by reproducible data and test settings; past results do not predict future returns. Trading involves significant risk of loss. This content is not financial advice.