Generate code in 3 minutes
Enter your idea and AI generates runnable code.
Here is a complete, fully functional trading strategy based on the Bill Williams Gator Oscillator for MetaTrader 4.
This strategy attempts to capture trends when the Gator Oscillator is in its "Eating" phase (expansion) and the price confirms the direction relative to the Alligator lines.
Indicators Used:
Entry Conditions:
Exit Conditions:
//+------------------------------------------------------------------+
//| GatorStrategy.mq4 |
//| Copyright 2023, MetaQuotes |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative AI Assistant"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- Input Parameters
input string _ = "--- Trade Settings ---";
input double LotSize = 0.1; // Fixed Lot Size
input int MagicNumber = 123456; // Magic Number ID
input int Slippage = 3; // Max Slippage in pips
input string __ = "--- Risk Management ---";
input int StopLoss = 50; // Stop Loss in pips (0 = None)
input int TakeProfit = 100; // Take Profit in pips (0 = None)
input bool UseTrailing = true; // Enable Trailing Stop based on Alligator Jaw
input string ___ = "--- Alligator Settings ---";
input int JawPeriod = 13; // Blue Line Period
input int JawShift = 8; // Blue Line Shift
input int TeethPeriod = 8; // Red Line Period
input int TeethShift = 5; // Red Line Shift
input int LipsPeriod = 5; // Green Line Period
input int LipsShift = 3; // Green Line Shift
input ENUM_MA_METHOD MaMethod = MODE_SMMA;// MA Method
input ENUM_APPLIED_PRICE AppliedPrice = PRICE_MEDIAN; // Applied Price
//--- Global Variables
double g_point;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Normalize point value for 3/5 digit brokers
if(Digits == 3 || Digits == 5) g_point = Point * 10;
else g_point = Point;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Clean up if necessary
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 1. Check for Open Positions
if(OrdersTotal() > 0)
{
ManageOpenPositions();
}
// 2. Check for New Bar (Entry logic runs once per bar close)
static datetime lastBarTime = 0;
if(Time[0] == lastBarTime) return;
lastBarTime = Time[0];
// 3. Check Entry Conditions if no orders are open for this symbol/magic
if(CountOrders() == 0)
{
CheckEntrySignals();
}
}
//+------------------------------------------------------------------+
//| Check for Entry Signals |
//+------------------------------------------------------------------+
void CheckEntrySignals()
{
// --- Get Gator Oscillator Values (Bar 1 and Bar 2) ---
// MODE_UPPER = 1, MODE_LOWER = 2
double gatorUp1 = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MaMethod, AppliedPrice, MODE_UPPER, 1);
double gatorUp2 = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MaMethod, AppliedPrice, MODE_UPPER, 2);
double gatorLow1 = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MaMethod, AppliedPrice, MODE_LOWER, 1);
double gatorLow2 = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MaMethod, AppliedPrice, MODE_LOWER, 2);
// --- Determine Gator Colors (Green = Expansion, Red = Contraction) ---
// Green means current value > previous value (absolute values)
bool isUpGreen = (gatorUp1 > gatorUp2);
bool isLowGreen = (gatorLow1 > gatorLow2);
// "Eating" Phase: Both bars are Green
bool isGatorEating = isUpGreen && isLowGreen;
// --- Get Alligator Teeth (Red Line) for Trend Confirmation ---
double teeth = iAlligator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MaMethod, AppliedPrice, MODE_GATORTEETH, 1);
double closePrice = iClose(NULL, 0, 1);
// --- Execution Logic ---
if(isGatorEating)
{
// Buy Signal: Gator Eating + Price Closed Above Teeth
if(closePrice > teeth)
{
double sl = (StopLoss > 0) ? Ask - StopLoss * g_point : 0;
double tp = (TakeProfit > 0) ? Ask + TakeProfit * g_point : 0;
int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, sl, tp, "Gator Buy", MagicNumber, 0, clrGreen);
if(ticket < 0) Print("OrderSend Failed: ", GetLastError());
}
// Sell Signal: Gator Eating + Price Closed Below Teeth
else if(closePrice < teeth)
{
double sl = (StopLoss > 0) ? Bid + StopLoss * g_point : 0;
double tp = (TakeProfit > 0) ? Bid - TakeProfit * g_point : 0;
int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, sl, tp, "Gator Sell", MagicNumber, 0, clrRed);
if(ticket < 0) Print("OrderSend Failed: ", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| Manage Open Positions (Trailing Stop) |
//+------------------------------------------------------------------+
void ManageOpenPositions()
{
if(!UseTrailing) return;
// Get Alligator Jaw (Blue Line) value for trailing
// We use shift 1 (previous closed bar) to ensure the line value is fixed
double jaw = iAlligator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MaMethod, AppliedPrice, MODE_GATORJAW, 1);
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
// Trailing for Buy
if(OrderType() == OP_BUY)
{
// Ensure Jaw is above open price (in profit) or just trail strictly
// Here we trail if Jaw is higher than current SL
if(jaw > OrderStopLoss() && jaw < Bid)
{
// Keep a minimum distance of 1 spread or 5 points to avoid stop hunting
double minStop = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
if(Bid - jaw > minStop)
{
if(!OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(jaw, Digits), OrderTakeProfit(), 0, clrBlue))
Print("Trailing Buy Failed: ", GetLastError());
}
}
}
// Trailing for Sell
if(OrderType() == OP_SELL)
{
// Trail if Jaw is lower than current SL (or SL is 0)
if((jaw < OrderStopLoss() || OrderStopLoss() == 0) && jaw > Ask)
{
double minStop = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
if(jaw - Ask > minStop)
{
if(!OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(jaw, Digits), OrderTakeProfit(), 0, clrRed))
Print("Trailing Sell Failed: ", GetLastError());
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| Count Open Orders for this EA |
//+------------------------------------------------------------------+
int CountOrders()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
count++;
}
}
return count;
}
//+------------------------------------------------------------------+
F4.New -> Expert Advisor (template) -> Name it "GatorStrategy".F7. Ensure there are no errors in the "Errors" tab at the bottom.Ctrl+R to open the Strategy Tester. Select "GatorStrategy", choose a symbol (e.g., EURUSD), a timeframe (H1 or H4 is recommended for Bill Williams strategies), and click Start.iGator for the previous bar (index 1) and the bar before that (index 2). If the value at index 1 is greater than index 2, the bar is considered "Green". We require both the Upper and Lower histograms to be Green to confirm strong momentum.Q: Why do you use MODE_GATORTEETH for the trend filter?
A: In Bill Williams' theory, the Teeth (Red Line) represents the "Balance Line" for the current timeframe. Price closing above/below it is a standard confirmation that the immediate trend is valid.
Q: Can I use this on M1 or M5 timeframes?
A: While the code will run, Gator and Alligator strategies are momentum-based and typically perform poorly on very low timeframes due to noise and spread costs. H1, H4, and Daily charts usually yield better results with this logic.
Q: What does g_point do?
A: This variable automatically adjusts the pip calculations for 5-digit brokers (where 1 pip = 10 points) and 4-digit brokers, ensuring that a 50 pip Stop Loss is actually 50 pips, not 5.