MetaTrader MT4 MT5 MQL Expert Advisor Guide
Complete Guide to MetaTrader 4 & 5 (MQL): Build Expert Advisors & Custom Indicators
Brokerlytic TeamApril 10, 2026
Key Takeaways:Master MQL4 and MQL5 programming β learn to build Expert Advisors (EAs), custom indicators, and automated trading systems on MetaTrader platforms.
What is MQL (MetaQuotes Language)?
MQL is the programming language behind MetaTrader 4 (MQL4) and MetaTrader 5 (MQL5). It allows traders to create:
- Expert Advisors (EAs) β fully automated trading robots
- Custom Indicators β technical analysis tools beyond built-in ones
- Scripts β one-time execution programs for batch operations
- Libraries β reusable code modules
MT4 vs MT5: Which to Choose?
| Feature | MT4 (MQL4) | MT5 (MQL5) |
|---|---|---|
| Language | C-like procedural | C++ object-oriented |
| Backtesting | Single-threaded | Multi-threaded (faster) |
| Order System | Simple (OrderSend) | Position-based (CTrade) |
| Timeframes | 9 timeframes | 21 timeframes |
| Market Types | Forex focus | Multi-asset (Stocks, Futures) |
| Hedging | Default | Optional (Hedging + Netting) |
| Community | Massive legacy codebase | Growing, modern |
Recommendation: Start with MT5/MQL5 for new projects. Use MT4 only if your broker doesn't support MT5.
Chapter 1: Setting Up Your Development Environment
MetaEditor
- Open MetaTrader 4 or 5
- Press F4 or click "MetaEditor" icon
- File β New β Expert Advisor (or Indicator)
- Name your project and click "Finish"
File Structure
MQL5/
βββ Experts/ β Expert Advisors (.ex5)
βββ Indicators/ β Custom Indicators (.ex5)
βββ Scripts/ β One-shot Scripts (.ex5)
βββ Include/ β Header files (.mqh)
βββ Libraries/ β Shared libraries (.ex5)
Chapter 2: Your First Expert Advisor (MQL5)
Simple Moving Average Crossover EA
//+------------------------------------------------------------------+
//| SMA_Crossover_EA.mq5 |
//+------------------------------------------------------------------+
#property copyright "Brokerlytic"
#property version "1.00"
#include <Trade/Trade.mqh>
input int FastPeriod = 10; // Fast MA Period
input int SlowPeriod = 30; // Slow MA Period
input double LotSize = 0.1; // Trade Volume
input int StopLoss = 100; // Stop Loss in points
input int TakeProfit = 200; // Take Profit in points
CTrade trade;
int fastHandle, slowHandle;
int OnInit()
{
fastHandle = iMA(_Symbol, PERIOD_CURRENT, FastPeriod, 0, MODE_SMA, PRICE_CLOSE);
slowHandle = iMA(_Symbol, PERIOD_CURRENT, SlowPeriod, 0, MODE_SMA, PRICE_CLOSE);
if(fastHandle == INVALID_HANDLE || slowHandle == INVALID_HANDLE)
{
Print("Failed to create indicator handles");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
IndicatorRelease(fastHandle);
IndicatorRelease(slowHandle);
}
void OnTick()
{
// Only trade on new bar
static datetime lastBar = 0;
datetime currentBar = iTime(_Symbol, PERIOD_CURRENT, 0);
if(currentBar == lastBar) return;
lastBar = currentBar;
// Get MA values
double fastMA[2], slowMA[2];
CopyBuffer(fastHandle, 0, 1, 2, fastMA);
CopyBuffer(slowHandle, 0, 1, 2, slowMA);
// Check for crossover
bool bullishCross = fastMA[1] > slowMA[1] && fastMA[0] <= slowMA[0];
bool bearishCross = fastMA[1] < slowMA[1] && fastMA[0] >= slowMA[0];
// Check if we have open positions
bool hasPosition = PositionSelect(_Symbol);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(bullishCross && !hasPosition)
{
double sl = ask - StopLoss * point;
double tp = ask + TakeProfit * point;
trade.Buy(LotSize, _Symbol, ask, sl, tp, "SMA Cross Buy");
}
if(bearishCross && hasPosition)
{
trade.PositionClose(_Symbol);
}
}
Chapter 3: Building Custom Indicators
RSI with Signal Arrows
//+------------------------------------------------------------------+
//| RSI_Signals.mq5 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots 3
#property indicator_label1 "RSI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_width1 2
#property indicator_label2 "Buy Signal"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrLime
#property indicator_label3 "Sell Signal"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrRed
input int RSI_Period = 14;
input int Oversold = 30;
input int Overbought = 70;
double rsiBuffer[], buyBuffer[], sellBuffer[];
int rsiHandle;
int OnInit()
{
SetIndexBuffer(0, rsiBuffer, INDICATOR_DATA);
SetIndexBuffer(1, buyBuffer, INDICATOR_DATA);
SetIndexBuffer(2, sellBuffer, INDICATOR_DATA);
PlotIndexSetInteger(1, PLOT_ARROW, 233); // Up arrow
PlotIndexSetInteger(2, PLOT_ARROW, 234); // Down arrow
rsiHandle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE);
IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, Overbought);
IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, Oversold);
return(INIT_SUCCEEDED);
}
int OnCalculate(const int rates_total, const int prev_calculated,
const datetime &time[], const double &open[],
const double &high[], const double &low[],
const double &close[], const long &tick_volume[],
const long &volume[], const int &spread[])
{
int start = prev_calculated > 0 ? prev_calculated - 1 : 0;
double rsi[];
CopyBuffer(rsiHandle, 0, 0, rates_total, rsi);
for(int i = start; i < rates_total; i++)
{
rsiBuffer[i] = rsi[i];
buyBuffer[i] = EMPTY_VALUE;
sellBuffer[i] = EMPTY_VALUE;
if(i > 0)
{
if(rsi[i-1] < Oversold && rsi[i] >= Oversold)
buyBuffer[i] = rsi[i];
if(rsi[i-1] > Overbought && rsi[i] <= Overbought)
sellBuffer[i] = rsi[i];
}
}
return(rates_total);
}
Chapter 4: Risk Management in EAs
Position Sizing Based on Account Risk
double CalculateLotSize(double riskPercent, double stopLossPoints)
{
double accountBalance = AccountInfoDouble(ACCOUNT_BALANCE);
double riskAmount = accountBalance * riskPercent / 100.0;
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double pipValue = tickValue * (point / tickSize);
double lotSize = riskAmount / (stopLossPoints * pipValue);
// Normalize to broker's lot step
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
lotSize = MathFloor(lotSize / lotStep) * lotStep;
lotSize = MathMax(minLot, MathMin(maxLot, lotSize));
return lotSize;
}
Trailing Stop Implementation
void TrailingStop(int trailPoints)
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PositionGetSymbol(i) != _Symbol) continue;
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentSL = PositionGetDouble(POSITION_SL);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
long ticket = PositionGetInteger(POSITION_TICKET);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double newSL = bid - trailPoints * point;
if(newSL > currentSL && newSL > openPrice)
trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP));
}
else
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double newSL = ask + trailPoints * point;
if(newSL < currentSL && newSL < openPrice)
trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP));
}
}
}
Chapter 5: Backtesting & Optimization
Strategy Tester Setup
- Open Strategy Tester (Ctrl+R in MT5)
- Select your EA from the dropdown
- Choose symbol and timeframe
- Set date range for testing
- Choose modeling mode:
- Every tick β most accurate, slowest
- 1 Minute OHLC β good balance
- Open prices only β fastest, least accurate
Optimization Tips
- Use Genetic Algorithm for faster optimization
- Avoid over-fitting: test on out-of-sample data
- Forward-test on demo accounts before going live
- Monitor key metrics: Profit Factor > 1.5, Max Drawdown < 20%, Win Rate > 40%
Summary
MetaTrader with MQL is the industry standard for automated Forex trading. Key takeaways:
- Start with MT5/MQL5 for modern features
- Use the CTrade class for cleaner order management
- Always implement risk management (position sizing, stops)
- Backtest extensively before live trading
- Join the MQL5 community for support and shared code
Ready to start? Download MetaTrader 5 and begin building your first EA today.
Frequently Asked Questions
What is the main concept of to MetaTrader 4 & 5 (MQL): Build Expert Advisors & Custom Indicators?
Master MQL4 and MQL5 programming β learn to build Expert Advisors (EAs), custom indicators, and automated trading systems on MetaTrader platforms.
Who should read this guide?
This guide is perfect for both beginners looking to understand the basics and experienced traders wanting to refine their strategies in MetaTrader.