Meta Description: Learn how to build your first MetaTrader Expert Advisor from scratch. This beginner-friendly guide covers setup, EA structure, sample code in MQL4 & MQL5, backtesting, optimization, and deployment.
Why build an EA?
Automated trading lets you execute rules 24/5 without emotions. An Expert Advisor (EA) codifies your strategy so it can place orders, manage risk, and exit automatically. In this quick guide, you’ll build a simple moving‑average (MA) crossover EA for both MT4 (MQL4) and MT5 (MQL5), test it, and run it on a chart.
Prerequisites
• MetaTrader 4 or MetaTrader 5 installed from your broker.
• A demo account (never test new EAs on live first).
• Basic idea of your entry/exit rules. We’ll use MA crossover.
Part A — MT4: Build a Simple MA Crossover EA (MQL4)
1) Open MetaEditor: MT4 → Tools → MetaQuotes Language Editor → New → Expert Advisor (template). Name it e.g., SimpleMACross_EA.
2) Replace the template code with the snippet below and press Compile (F7).
//+——————————————————————+
//| SimpleMACross_EA.mq4|
//| Example for education (use on demo first) |
//+——————————————————————+
#property strict
extern int FastMAPeriod = 10;
extern int SlowMAPeriod = 20;
extern double Lots = 0.10;
extern int Slippage = 3;
extern int StopLoss = 200; // points
extern int TakeProfit = 400; // points
extern bool OneTradePerDirection = true;
// Helper: count open trades by type
int CountOpen(int type){
int c = 0;
for(int i=OrdersTotal()-1; i>=0; i–){
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol()==_Symbol && OrderMagicNumber()==12345){
if(OrderType()==type) c++;
}
}
return c;
}
int OnInit(){
Print(“SimpleMACross_EA initialized on “, _Symbol);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason){}
void OnTick(){
// Safety: only on a new bar
static datetime lastTime=0;
datetime t = iTime(_Symbol, PERIOD_CURRENT, 0);
if(t==lastTime) return;
lastTime=t;
double fastPrev = iMA(_Symbol, PERIOD_CURRENT, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
double fastNow = iMA(_Symbol, PERIOD_CURRENT, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);
double slowPrev = iMA(_Symbol, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
double slowNow = iMA(_Symbol, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
bool bullCross = (fastPrev <= slowPrev && fastNow > slowNow);
bool bearCross = (fastPrev >= slowPrev && fastNow < slowNow);
double ask = NormalizeDouble(Ask, _Digits);
double bid = NormalizeDouble(Bid, _Digits);
// Buy on bullish cross
if(bullCross && (!OneTradePerDirection || CountOpen(OP_BUY)==0)){
double sl = StopLoss>0 ? bid – StopLoss*_Point : 0;
double tp = TakeProfit>0 ? bid + TakeProfit*_Point : 0;
int tk = OrderSend(_Symbol, OP_BUY, Lots, ask, Slippage, sl, tp, “MA Buy”, 12345, 0, clrBlue);
if(tk<0) Print(“Buy failed. Error: “, GetLastError());
}
// Sell on bearish cross
if(bearCross && (!OneTradePerDirection || CountOpen(OP_SELL)==0)){
double sl = StopLoss>0 ? ask + StopLoss*_Point : 0;
double tp = TakeProfit>0 ? ask – TakeProfit*_Point : 0;
int tk = OrderSend(_Symbol, OP_SELL, Lots, bid, Slippage, sl, tp, “MA Sell”, 12345, 0, clrRed);
if(tk<0) Print(“Sell failed. Error: “, GetLastError());
}
}
3) Attach the compiled EA to a chart (Navigator → Expert Advisors → drag to chart).
Part B — MT5: Build the Same EA in MQL5
1) In MT5, open MetaEditor → New → Expert Advisor (template). Name it SimpleMACross_EA.mq5.
2) Paste the code below and Compile (F7).
Below is a compact MQL5 version using built‑in indicators and trade classes:
#property strict
#include <Trade/Trade.mqh>
CTrade trade;
input int FastMAPeriod = 10;
input int SlowMAPeriod = 20;
input double Lots = 0.10;
input int StopLoss = 200; // points
input int TakeProfit = 400; // points
input bool OneTradePerDirection = true;
int fastHandle, slowHandle;
int OnInit(){
fastHandle = iMA(_Symbol, PERIOD_CURRENT, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
slowHandle = iMA(_Symbol, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
if(fastHandle==INVALID_HANDLE || slowHandle==INVALID_HANDLE) return(INIT_FAILED);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason){
if(fastHandle) IndicatorRelease(fastHandle);
if(slowHandle) IndicatorRelease(slowHandle);
}
void OnTick(){
static datetime lastBar=0;
datetime t = iTime(_Symbol, PERIOD_CURRENT, 0);
if(t==lastBar) return;
lastBar=t;
double f[2], s[2];
if(CopyBuffer(fastHandle,0,0,2,f)<2) return;
if(CopyBuffer(slowHandle,0,0,2,s)<2) return;
bool bullCross = (f[1] <= s[1] && f[0] > s[0]);
bool bearCross = (f[1] >= s[1] && f[0] < s[0]);
double priceAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double priceBid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// Count open positions on this symbol
int buys=0, sells=0;
for(int i=PositionsTotal()-1;i>=0;i–){
if(PositionSelectByTicket(PositionGetTicket(i)) && PositionGetString(POSITION_SYMBOL)==_Symbol){
long type = PositionGetInteger(POSITION_TYPE);
if(type==POSITION_TYPE_BUY) buys++;
if(type==POSITION_TYPE_SELL) sells++;
}
}
if(bullCross && (!OneTradePerDirection || buys==0)){
double sl = StopLoss>0 ? priceBid – StopLoss*point : 0.0;
double tp = TakeProfit>0 ? priceBid + TakeProfit*point : 0.0;
trade.Buy(Lots, NULL, priceAsk, sl, tp, “MA Buy”);
}
if(bearCross && (!OneTradePerDirection || sells==0)){
double sl = StopLoss>0 ? priceAsk + StopLoss*point : 0.0;
double tp = TakeProfit>0 ? priceAsk – TakeProfit*point : 0.0;
trade.Sell(Lots, NULL, priceBid, sl, tp, “MA Sell”);
}
}
Backtest Your EA (Strategy Tester)
MT4: View → Strategy Tester → Choose your EA → Symbol & timeframe → Model: Open prices only (fast) or Every tick (accurate) → Start.
MT5: View → Strategy Tester → Single/Optimization → Select EA → Symbol, timeframe, deposit & leverage → Start.
Tips: Use a date range, start with small lot sizes, and check the Journal tab for errors.
Optimize Safely
• Optimize only a few inputs at a time (e.g., Fast/Slow MA).
• Avoid curve‑fitting: validate on out‑of‑sample dates.
• Record settings that work consistently across symbols/timeframes.
Go Live (Carefully)
• Switch to a demo forward test for 2–4 weeks with VPS uptime.
• When moving to live, start with micro lots and strict risk (1% per trade).
• Monitor broker execution, slippage, and spreads during news.
Common Errors & Fixes
• Trade is not opening: check Experts/Journal for error codes; in MT4 confirm AutoTrading is enabled; in MT5 confirm algo trading is allowed for the EA.
• Wrong lot size on symbols with high minimums: query SYMBOL_VOLUME_MIN and SYMBOL_VOLUME_STEP (MT5).
• Indicator handles invalid (MT5): ensure CopyBuffer returns >= requested bars.
Need a Custom EA?
If you want this logic tailored to your strategy (multi‑timeframe filters, partial closes, smart trailing, news filters, etc.), I can help build a professional MT4/MT5 EA. Contact me to discuss your rules and get a quote.