This article provides a complete, compilable MQL4 EA source code based on the classic moving average crossover strategy. The EA generates buy/sell signals when a fast MA crosses above or below a slow MA. Suitable for trend-following on any timeframe and symbol.
Strategy Logic:
Parameters Explanation:
MQL4 Source Code:
```mql4
//+------------------------------------------------------------------+
//| MovingAverageCrossoverEA.mq4 |
//| |
//| 自主编译 / Self-compiled |
//+------------------------------------------------------------------+
#property copyright "Forex Trading Tools"
#property link ""
#property version "1.00"
#property strict
//--- input parameters
input int FastMAPeriod = 5;
input int SlowMAPeriod = 21;
input int MA_Method = 1; // 0=SMA,1=EMA,2=SMMA,3=LWMA
input int Apply_Price = 0; // 0=Close,1=Open,2=High,3=Low,4=Median,5=Typical,6=Weighted
input double LotSize = 0.1;
input int StopLoss = 50;
input int TakeProfit = 100;
input int TrailingStop = 30;
input int MagicNumber = 202410;
double fastMA, slowMA;
int ticket;
bool isTrailing = false;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(FastMAPeriod >= SlowMAPeriod)
{
Print("Error: Fast MA period must be less than Slow MA period");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Calculate MA values
fastMA = iMA(_Symbol,0,FastMAPeriod,0,MA_Method,Apply_Price,1);
slowMA = iMA(_Symbol,0,SlowMAPeriod,0,MA_Method,Apply_Price,1);
double fastMA_prev = iMA(_Symbol,0,FastMAPeriod,0,MA_Method,Apply_Price,2);
double slowMA_prev = iMA(_Symbol,0,SlowMAPeriod,0,MA_Method,Apply_Price,2);
// Trailing stop
if(TrailingStop > 0)
{
Trailing();
}
// Check for open positions
if(CountOpenOrders() == 0)
{
// Buy signal
if(fastMA_prev <= slowMA_prev && fastMA > slowMA)
{
OpenOrder(OP_BUY);
}
// Sell signal
else if(fastMA_prev >= slowMA_prev && fastMA < slowMA)
{
OpenOrder(OP_SELL);
}
}
}
//+------------------------------------------------------------------+
//| Open order function |
//+------------------------------------------------------------------+
void OpenOrder(int cmd)
{
double price, sl, tp;
if(cmd == OP_BUY)
{
price = Ask;
if(StopLoss > 0) sl = price - StopLoss * _Point * 10;
if(TakeProfit > 0) tp = price + TakeProfit * _Point * 10;
}
else
{
price = Bid;
if(StopLoss > 0) sl = price + StopLoss * _Point * 10;
if(TakeProfit > 0) tp = price - TakeProfit * _Point * 10;
}
ticket = OrderSend(_Symbol,cmd,LotSize,price,3,sl,tp,"MA Crossover EA",MagicNumber,0,clrNONE);
if(ticket < 0)
{
Print("OrderSend failed: ",GetLastError());
}
}
//+------------------------------------------------------------------+
//| Count open orders by MagicNumber |
//+------------------------------------------------------------------+
int CountOpenOrders()
{
int count = 0;
for(int i=0; i
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Symbol)
count++;
}
}
return count;
}
//+------------------------------------------------------------------+
//| Trailing stop function |
//+------------------------------------------------------------------+
void Trailing()
{
for(int i=0; i
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Symbol)
{
if(OrderType() == OP_BUY)
{
double newSL = Bid - TrailingStop * _Point * 10;
if(newSL > OrderStopLoss())
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),newSL,OrderTakeProfit(),0,clrNONE))
Print("Trailing stop updated for buy #",OrderTicket());
}
}
else if(OrderType() == OP_SELL)
{
double newSL = Ask + TrailingStop * _Point * 10;
if(newSL < OrderStopLoss() || OrderStopLoss() == 0)
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),newSL,OrderTakeProfit(),0,clrNONE))
Print("Trailing stop updated for sell #",OrderTicket());
}
}
}
}
}
}
//+------------------------------------------------------------------+
```
Compilation & Usage Guide:
1. Copy the code into MetaEditor (F4 in MT4)
2. Click Compile (F7) – ensure no errors
3. Attach EA to a chart, adjust parameters in Inputs tab
4. Enable AutoTrading (green button)
5. Recommended to test first on a demo account
Reference: 自主编译 / Self-compiled based on public domain trading logic.
For more advanced EAs with multi-strategy integration, money management, and news filters, consider subscribing to our premium EA packages.