Create MQL5 Expert Advisor Without Coding: Beginner's Complete Guide
This beginner's guide walks you through every method available to create a fully functional MQL5 Expert Advisor without writing a single line of code — from visual EA builders and AI code generators to MetaEditor's built-in wizard. By the end you will have a working EA deployed on MetaTrader 5 and understand how to customise its parameters without touching raw MQL5 syntax.
Strategy Logic
Entry Conditions
N/A — this is a tutorial/indicator reference page.
Exit Conditions
N/A — this is a tutorial/indicator reference page.
MQL5 Expert Advisor Code
//+------------------------------------------------------------------+
//| NoCodeStarterEA.mq5 |
//| Teaching example — generated by Pineify AI MQL5 Generator |
//| Demonstrates the classic Moving-Average crossover pattern that |
//| most visual EA builders produce under the hood. |
//+------------------------------------------------------------------+
#property copyright "Pineify.app"
#property link "https://pineify.app"
#property version "1.00"
#property strict
//--- Input parameters (the "settings" users tweak without coding)
input int FastPeriod = 9; // Fast MA period
input int SlowPeriod = 21; // Slow MA period
input int MAPeriod = 200; // Trend filter MA period
input double LotSize = 0.10; // Trade volume in lots
input int StopLossPips = 40; // Stop loss in pips
input int TakeProfitPips = 80; // Take profit in pips
input int MagicNumber = 202600; // Unique EA identifier
input string TradeComment = "NoCodeEA"; // Order comment
//--- Indicator handles
int handleFast;
int handleSlow;
int handleTrend;
//--- Buffers
double fastBuf[];
double slowBuf[];
double trendBuf[];
//+------------------------------------------------------------------+
//| Expert initialisation — runs once when EA is attached |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Create indicator handles
handleFast = iMA(_Symbol, PERIOD_CURRENT, FastPeriod, 0, MODE_EMA, PRICE_CLOSE);
handleSlow = iMA(_Symbol, PERIOD_CURRENT, SlowPeriod, 0, MODE_EMA, PRICE_CLOSE);
handleTrend = iMA(_Symbol, PERIOD_CURRENT, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);
if(handleFast == INVALID_HANDLE || handleSlow == INVALID_HANDLE || handleTrend == INVALID_HANDLE)
{
Print("ERROR: Failed to create indicator handles.");
return INIT_FAILED;
}
//--- Set buffer as series (newest value at index 0)
ArraySetAsSeries(fastBuf, true);
ArraySetAsSeries(slowBuf, true);
ArraySetAsSeries(trendBuf, true);
Print("NoCodeStarterEA initialised on ", _Symbol,
" | Fast=", FastPeriod, " Slow=", SlowPeriod);
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| Expert deinitialization — runs once when EA is removed |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- Release indicator handles to free memory
if(handleFast != INVALID_HANDLE) IndicatorRelease(handleFast);
if(handleSlow != INVALID_HANDLE) IndicatorRelease(handleSlow);
if(handleTrend != INVALID_HANDLE) IndicatorRelease(handleTrend);
Print("NoCodeStarterEA removed. Reason code: ", reason);
}
//+------------------------------------------------------------------+
//| Helper — count open positions for this EA on this symbol |
//+------------------------------------------------------------------+
int CountPositions(ENUM_POSITION_TYPE posType)
{
int count = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0) continue;
if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
PositionGetInteger(POSITION_MAGIC) == MagicNumber &&
PositionGetInteger(POSITION_TYPE) == posType)
count++;
}
return count;
}
//+------------------------------------------------------------------+
//| Helper — send a market order |
//+------------------------------------------------------------------+
bool SendOrder(ENUM_ORDER_TYPE orderType, double volume)
{
MqlTradeRequest request = {};
MqlTradeResult result = {};
double price = (orderType == ORDER_TYPE_BUY)
? SymbolInfoDouble(_Symbol, SYMBOL_ASK)
: SymbolInfoDouble(_Symbol, SYMBOL_BID);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
double slDist = StopLossPips * 10 * point;
double tpDist = TakeProfitPips * 10 * point;
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = volume;
request.type = orderType;
request.price = NormalizeDouble(price, digits);
request.deviation = 5;
request.magic = MagicNumber;
request.comment = TradeComment;
if(orderType == ORDER_TYPE_BUY)
{
request.sl = NormalizeDouble(price - slDist, digits);
request.tp = NormalizeDouble(price + tpDist, digits);
}
else
{
request.sl = NormalizeDouble(price + slDist, digits);
request.tp = NormalizeDouble(price - tpDist, digits);
}
bool sent = OrderSend(request, result);
if(!sent || result.retcode != TRADE_RETCODE_DONE)
Print("OrderSend failed. Retcode=", result.retcode, " Comment=", result.comment);
return sent;
}
//+------------------------------------------------------------------+
//| Main tick function — EA logic runs here on every price tick |
//+------------------------------------------------------------------+
void OnTick()
{
//--- Only act on a newly closed bar (once per bar logic)
static datetime lastBarTime = 0;
datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
if(currentBarTime == lastBarTime) return;
lastBarTime = currentBarTime;
//--- Copy latest two values from each indicator buffer
if(CopyBuffer(handleFast, 0, 0, 3, fastBuf) < 3) return;
if(CopyBuffer(handleSlow, 0, 0, 3, slowBuf) < 3) return;
if(CopyBuffer(handleTrend, 0, 0, 3, trendBuf) < 3) return;
//--- Current and previous bar values
double fastNow = fastBuf[1];
double fastPrev = fastBuf[2];
double slowNow = slowBuf[1];
double slowPrev = slowBuf[2];
double trendNow = trendBuf[1];
double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
//--- Bullish crossover: fast crosses above slow while price above trend MA
bool bullCross = (fastPrev <= slowPrev) && (fastNow > slowNow) && (askPrice > trendNow);
//--- Bearish crossover: fast crosses below slow while price below trend MA
bool bearCross = (fastPrev >= slowPrev) && (fastNow < slowNow) && (bidPrice < trendNow);
//--- Enter long if no existing buy
if(bullCross && CountPositions(POSITION_TYPE_BUY) == 0)
{
Print("BUY signal: Fast=", fastNow, " Slow=", slowNow, " Trend=", trendNow);
SendOrder(ORDER_TYPE_BUY, LotSize);
}
//--- Enter short if no existing sell
if(bearCross && CountPositions(POSITION_TYPE_SELL) == 0)
{
Print("SELL signal: Fast=", fastNow, " Slow=", slowNow, " Trend=", trendNow);
SendOrder(ORDER_TYPE_SELL, LotSize);
}
}
//+------------------------------------------------------------------+Copy this code into MetaEditor (F4 in MT5), save in the Experts folder, and compile with F7.
Generate a Custom Multi-pair Educational 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
| Aspect | Pine Script (TradingView) | MQL5 (MetaTrader 5) |
|---|---|---|
| Execution | Bar-based, backtesting only | Tick-based, live trading |
| Deployment | TradingView alerts | Runs 24/5 on VPS/MT5 |
| Broker access | Via TradingView broker integration | Direct broker connectivity |
| Backtesting | Built-in, no data download needed | Strategy Tester, tick data required |
| Code complexity | Simpler, functional syntax | C++-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.