Complete .mq5 source code

EURUSD Scalping EA MT5: M5 EMA Example & Test Guide

Inspect a complete educational M5 EMA-crossover EA with broker-server-hour and spread filters. It uses fixed lots and point-based SL/TP, with no ATR filter or trailing stop. The page supplies no verified backtest or optimum settings.

Strategy logic

Entry conditions

Once per available M5 bar, compare completed bars 2 and 1 for a strict 9/21 EMA crossover. Entries require the configured server-hour window and spread limit. The example defaults to 07:00–12:00 broker time; this is not automatically London time or DST-adjusted. Position checks use the symbol and magic number; account mode still matters.

Exit conditions

The default stop and target are 100 and 150 SYMBOL_POINT units. These correspond to 10 and 15 conventional EURUSD pips only for a five-decimal quote. Outside the server-hour window, the EA attempts to close its own symbol/magic positions when ticks arrive. It does not guarantee an exact noon exit, and it has no trailing stop. IOC filling, tick grid, volume steps and stop distances require broker verification.

MQL5 Expert Advisor Code

//+------------------------------------------------------------------+
//| EURUSD Scalping EA - London Session M5                          |
//| Pineify.app                                                      |
//+------------------------------------------------------------------+
#property copyright "Pineify.app"
#property version   "1.00"

input int    MagicNumber   = 567890;
input double Lots          = 0.01;
input int    EMA_Fast      = 9;
input int    EMA_Slow      = 21;
input int    MaxSpread     = 15;    // Max spread in points
input double TP_Points     = 150;
input double SL_Points     = 100;
input int    SessionStart  = 7;
input int    SessionEnd    = 12;

int emaFastH=INVALID_HANDLE, emaSlowH=INVALID_HANDLE;
datetime lastSignalBar=0;
double emaFast[], emaSlow[];

int OnInit() {
   if(EMA_Fast<1 || EMA_Slow<=EMA_Fast || Lots<=0 || SL_Points<=0 || TP_Points<=0 || MaxSpread<0 || SessionStart<0 || SessionEnd>24 || SessionStart>=SessionEnd) return INIT_PARAMETERS_INCORRECT;
   emaFastH = iMA(_Symbol, PERIOD_M5, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE);
   emaSlowH = iMA(_Symbol, PERIOD_M5, EMA_Slow, 0, MODE_EMA, PRICE_CLOSE);
   if(emaFastH==INVALID_HANDLE || emaSlowH==INVALID_HANDLE) return INIT_FAILED;
   ArraySetAsSeries(emaFast, true); ArraySetAsSeries(emaSlow, true);
   return INIT_SUCCEEDED;
}

void OnDeinit(const int reason) {
   if(emaFastH!=INVALID_HANDLE) IndicatorRelease(emaFastH);
   if(emaSlowH!=INVALID_HANDLE) IndicatorRelease(emaSlowH);
}

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

   MqlDateTime dt; if(!TimeToStruct(tick.time, dt)) return;
   if (dt.hour < SessionStart || dt.hour >= SessionEnd) {
      CloseAllPositions(MagicNumber); return;
   }

   double spread = (tick.ask - tick.bid) / _Point;
   if (spread > MaxSpread) return;

   if (CopyBuffer(emaFastH, 0, 0, 3, emaFast) < 3) return;
   if (CopyBuffer(emaSlowH, 0, 0, 3, emaSlow) < 3) return;

   datetime bar=iTime(_Symbol,PERIOD_M5,0);
   if(bar==0 || bar==lastSignalBar) return;
   lastSignalBar=bar;
   if (CountPositions(MagicNumber) > 0) return;

   bool bullCross = emaFast[2] < emaSlow[2] && emaFast[1] > emaSlow[1];
   bool bearCross = emaFast[2] > emaSlow[2] && emaFast[1] < emaSlow[1];

   if (bullCross) OpenTrade(ORDER_TYPE_BUY,  Lots, SL_Points * _Point, TP_Points * _Point, MagicNumber);
   if (bearCross) OpenTrade(ORDER_TYPE_SELL, Lots, SL_Points * _Point, TP_Points * _Point, MagicNumber);
}

void CloseAllPositions(int magic) {
   for (int i = PositionsTotal()-1; i >= 0; i--) {
      ulong t = PositionGetTicket(i);
      if (!PositionSelectByTicket(t)) continue;
      if ((int)PositionGetInteger(POSITION_MAGIC) != magic || PositionGetString(POSITION_SYMBOL)!=_Symbol) continue;
      MqlTradeRequest req={}; MqlTradeResult res={};
      req.action=TRADE_ACTION_DEAL; req.position=t; req.symbol=_Symbol;
      req.volume=PositionGetDouble(POSITION_VOLUME);
      req.type=(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)?ORDER_TYPE_SELL:ORDER_TYPE_BUY;
      req.price=(req.type==ORDER_TYPE_SELL)?SymbolInfoDouble(_Symbol,SYMBOL_BID):SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      req.type_filling=ORDER_FILLING_IOC;
      if(!OrderSend(req,res) || res.retcode!=TRADE_RETCODE_DONE) Print("Close request: ",res.retcode," ",res.comment);
   }
}

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

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 EURUSD"; req.type_filling=ORDER_FILLING_IOC;
   if(!OrderSend(req,res) || res.retcode!=TRADE_RETCODE_DONE) Print("Entry request: ",res.retcode," ",res.comment);
}

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

Generate a custom EURUSD 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

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.