Gold Expert Advisor MT5: Free MQL5 Source and Testing Steps
Copy and inspect an H1 gold EA example using EMA 50/200 alignment, a close/EMA pullback condition and RSI. ATR determines initial stop and target distances and a risk-size estimate; it is not an entry volatility threshold. The source has no verified backtest and must be compiled and tested for the chosen broker.
Strategy logic
Entry conditions
Once per new H1 bar, use completed values: buy when EMA 50 is above EMA 200, close is at or below EMA 50 and RSI 14 is below 50. Reverse these inequalities for a sell. This is a level-based pullback definition, not an EMA crossover or proof of a trend. No minimum ATR, spread, session or news filter is implemented. Only one matching symbol-and-magic position is intended at a time.
Exit conditions
Request an initial stop one ATR from the entry quote and a target two ATR away. The example has no trailing stop or opposite-signal exit. Requested size estimates a percentage of balance from stop distance and tick properties, rounds down and skips if below broker minimum. It does not guarantee that realized loss stays within that percentage. Test fills, costs, tick/volume grids, stop levels and account-mode ownership.
MQL5 Expert Advisor Code
//+------------------------------------------------------------------+
//| Gold Trend EA - XAUUSD H1 (Free Version) |
//| Pineify.app — generate custom EAs at pineify.app/mql5 |
//+------------------------------------------------------------------+
#property copyright "Pineify.app"
#property version "1.00"
input int MagicNumber = 234567;
input double RiskPercent = 1.0;
input int ATR_Period = 14;
input double ATR_SL_Mult = 1.0;
input double ATR_TP_Mult = 2.0;
int ema50Handle=INVALID_HANDLE, ema200Handle=INVALID_HANDLE, atrHandle=INVALID_HANDLE, rsiHandle=INVALID_HANDLE;
double ema50[], ema200[], atr[], rsi[];
int OnInit() {
if(MagicNumber<0 || RiskPercent<=0 || ATR_Period<1 || ATR_SL_Mult<=0 || ATR_TP_Mult<=0) return INIT_PARAMETERS_INCORRECT;
ema50Handle = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_EMA, PRICE_CLOSE);
ema200Handle = iMA(_Symbol, PERIOD_H1, 200, 0, MODE_EMA, PRICE_CLOSE);
atrHandle = iATR(_Symbol, PERIOD_H1, ATR_Period);
rsiHandle = iRSI(_Symbol, PERIOD_H1, 14, PRICE_CLOSE);
if(ema50Handle==INVALID_HANDLE || ema200Handle==INVALID_HANDLE || atrHandle==INVALID_HANDLE || rsiHandle==INVALID_HANDLE) return INIT_FAILED;
ArraySetAsSeries(ema50, true); ArraySetAsSeries(ema200, true);
ArraySetAsSeries(atr, true); ArraySetAsSeries(rsi, true);
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason) {
if(ema50Handle!=INVALID_HANDLE) IndicatorRelease(ema50Handle);
if(ema200Handle!=INVALID_HANDLE) IndicatorRelease(ema200Handle);
if(atrHandle!=INVALID_HANDLE) IndicatorRelease(atrHandle);
if(rsiHandle!=INVALID_HANDLE) IndicatorRelease(rsiHandle);
}
void OnTick() {
if(CopyBuffer(ema50Handle, 0, 0, 3, ema50)!=3) return;
if(CopyBuffer(ema200Handle, 0, 0, 3, ema200)!=3) return;
if(CopyBuffer(atrHandle, 0, 0, 3, atr)!=3) return;
if(CopyBuffer(rsiHandle, 0, 0, 3, rsi)!=3) return;
if(atr[1]<=0 || !MathIsValidNumber(atr[1])) return;
if(!IsNewBar(PERIOD_H1) || CountPositions(MagicNumber)>0) return;
double lots = CalcLots(atr[1] * ATR_SL_Mult);
if(lots<=0) return;
bool upTrend = ema50[1] > ema200[1];
bool downTrend = ema50[1] < ema200[1];
double close1 = iClose(_Symbol, PERIOD_H1, 1);
if (upTrend && close1 <= ema50[1] && rsi[1] < 50)
OpenTrade(ORDER_TYPE_BUY, lots, atr[1] * ATR_SL_Mult, atr[1] * ATR_TP_Mult, MagicNumber);
else if (downTrend && close1 >= ema50[1] && rsi[1] > 50)
OpenTrade(ORDER_TYPE_SELL, lots, atr[1] * ATR_SL_Mult, atr[1] * ATR_TP_Mult, MagicNumber);
}
bool IsNewBar(ENUM_TIMEFRAMES tf) {
static datetime lastBar = 0;
datetime current = iTime(_Symbol, tf, 0);
if (current>0 && current != lastBar) { lastBar = current; return true; }
return false;
}
double CalcLots(double slPoints) {
double tickVal = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double tickSz = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double risk = balance * RiskPercent / 100.0;
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
if(slPoints<=0 || tickSz<=0 || tickVal<=0 || step<=0 || minLot<=0 || maxLot<minLot || risk<=0) return 0;
double lots=risk/(slPoints/tickSz*tickVal);
lots=NormalizeDouble(MathFloor(MathMin(lots,maxLot)/step)*step,8);
return lots>=minLot ? lots : 0;
}
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 EA";
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 example 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 trend-following 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
| Aspect | Pine Script (TradingView) | MQL5 (MetaTrader 5) |
|---|---|---|
| Execution | Series evaluated on chart updates | Event handlers with explicit buffers |
| Deployment | Runs in TradingView with alerts | Runs in the MT5 terminal or on a VPS |
| Broker access | Strategy orders are simulated; live automation needs a separate integration | Direct broker connectivity |
| Backtesting | Strategy Tester for strategy scripts | Strategy Tester for Expert Advisors |
| Code complexity | Simpler, functional syntax | C++-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.