Generate code in 3 minutes
Enter your idea and AI generates runnable code.
Here is a complete, fully functional Expert Advisor (EA) for MetaTrader 4 based on Bill Williams' Alligator indicator.
This EA uses the classic Alligator trend-following logic:
Lips > Teeth AND Teeth > Jaws.Lips < Teeth AND Teeth < Jaws.//+------------------------------------------------------------------+
//| AlligatorTrader.mq4 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative AI"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- Input Parameters
input double InpLots = 0.1; // Lot size
input int InpStopLoss = 50; // Stop Loss in points (0 = no SL)
input int InpTakeProfit = 100; // Take Profit in points (0 = no TP)
input int InpMagicNumber = 12345; // Magic Number to identify orders
input int InpSlippage = 3; // Maximum slippage in points
//--- Alligator Settings
input int InpJawPeriod = 13; // Jaws Period
input int InpJawShift = 8; // Jaws Shift
input int InpTeethPeriod = 8; // Teeth Period
input int InpTeethShift = 5; // Teeth Shift
input int InpLipsPeriod = 5; // Lips Period
input int InpLipsShift = 3; // Lips Shift
input ENUM_MA_METHOD InpMethod = MODE_SMMA; // Smoothing Method
input ENUM_APPLIED_PRICE InpPrice = PRICE_MEDIAN; // Applied Price
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Check if inputs are valid
if(InpLots <= 0) {
Alert("Lot size must be greater than 0");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Clean up if necessary
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 1. Check if we already have an open trade for this symbol/magic number
if(CountOpenTrades() > 0) return;
// 2. Define Shift (1 = Closed Bar, 0 = Current Bar)
// We use 1 to ensure the signal is confirmed and won't repaint
int shift = 1;
// 3. Get Alligator Values
double jaw = iAlligator(Symbol(), Period(), InpJawPeriod, InpJawShift, InpTeethPeriod, InpTeethShift, InpLipsPeriod, InpLipsShift, InpMethod, InpPrice, MODE_GATORJAW, shift);
double teeth = iAlligator(Symbol(), Period(), InpJawPeriod, InpJawShift, InpTeethPeriod, InpTeethShift, InpLipsPeriod, InpLipsShift, InpMethod, InpPrice, MODE_GATORTEETH, shift);
double lips = iAlligator(Symbol(), Period(), InpJawPeriod, InpJawShift, InpTeethPeriod, InpTeethShift, InpLipsPeriod, InpLipsShift, InpMethod, InpPrice, MODE_GATORLIPS, shift);
// 4. Check for Buy Signal (Lips > Teeth > Jaws)
if(lips > teeth && teeth > jaw)
{
OpenBuy();
}
// 5. Check for Sell Signal (Lips < Teeth < Jaws)
else if(lips < teeth && teeth < jaw)
{
OpenSell();
}
}
//+------------------------------------------------------------------+
//| Function to Open a Buy Order |
//+------------------------------------------------------------------+
void OpenBuy()
{
double sl = 0, tp = 0;
// Calculate SL and TP based on points
if(InpStopLoss > 0) sl = Ask - InpStopLoss * Point;
if(InpTakeProfit > 0) tp = Ask + InpTakeProfit * Point;
// Normalize prices
sl = NormalizeDouble(sl, Digits);
tp = NormalizeDouble(tp, Digits);
int ticket = OrderSend(Symbol(), OP_BUY, InpLots, Ask, InpSlippage, sl, tp, "Alligator Buy", InpMagicNumber, 0, clrGreen);
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Function to Open a Sell Order |
//+------------------------------------------------------------------+
void OpenSell()
{
double sl = 0, tp = 0;
// Calculate SL and TP based on points
if(InpStopLoss > 0) sl = Bid + InpStopLoss * Point;
if(InpTakeProfit > 0) tp = Bid - InpTakeProfit * Point;
// Normalize prices
sl = NormalizeDouble(sl, Digits);
tp = NormalizeDouble(tp, Digits);
int ticket = OrderSend(Symbol(), OP_SELL, InpLots, Bid, InpSlippage, sl, tp, "Alligator Sell", InpMagicNumber, 0, clrRed);
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Helper: Count open trades for this EA |
//+------------------------------------------------------------------+
int CountOpenTrades()
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagicNumber)
{
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
Q: Why does the EA use shift = 1 instead of 0?
A: Shift 0 refers to the current, forming candle. The Alligator lines move as the price ticks up and down. If we trade on shift 0, the signal might appear and disappear within the same candle (repainting). Using shift 1 ensures we only trade when the candle has closed and the Alligator alignment is confirmed.
Q: How does the EA handle exits?
A: This version uses a fixed Stop Loss and Take Profit (defined in the inputs). It does not close the trade based on the Alligator lines crossing back (sleeping phase). This is generally safer for basic testing to ensure risk is managed mathematically rather than relying on lagging indicators for exits.
Q: Can I trade multiple pairs with this?
A: Yes. You can attach this EA to EURUSD, GBPUSD, etc., simultaneously. The InpMagicNumber ensures the EA manages each chart's trades independently. However, if you run it on multiple charts of the same pair (e.g., two EURUSD charts), you must change the Magic Number on the second chart to avoid conflicts.