EURUSD Trend Stabilizer EA is engineered for stable trend-following operations on EURUSD. The EA employs the Supertrend indicator as the primary trend direction signal, combined with ADX (Average Directional Index) to ensure only trades with sufficient trend strength are taken. An ATR-based dynamic stop loss adapts to market volatility, while a breakeven mechanism protects capital once price moves favorably. The EA trades only one position at a time and includes daily loss protection.
Recommended Timeframe: H1
Trading Logic:
``
mql4
//+------------------------------------------------------------------+
//| EURUSDTrendStabilizerEA.mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""
#property version "1.00"
#property strict
//--- input parameters with comments
input double LotSize = 0.01; // Fixed lot size (0.01 per trade)
input int ATRPeriod = 10; // ATR period for Supertrend and stop loss
input double SupertrendMultiplier = 3.0; // Supertrend multiplier factor
input int ADXPeriod = 14; // ADX period for trend strength filter
input int ADXThreshold = 25; // Minimum ADX value to allow trading
input double ATRStopMultiplier = 2.0; // Stop loss as multiple of ATR
input double ATRTakeMultiplier = 3.5; // Take profit as multiple of ATR
input double BreakevenTrigger = 1.5; // Breakeven trigger in ATR multiples
input int MagicNumber = 202416; // Unique EA identifier
input int MaxSpread = 25; // Maximum allowed spread in points
input double DailyLossLimit = 5.0; // Daily loss limit as percentage of balance
input bool UseFridayClose = true; // Close trades before Friday 21:00 GMT
//--- global variables
double dailyStartBalance = 0;
datetime lastBarTime = 0;
bool fridayCloseExecuted = false;
bool breakevenApplied = false;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
dailyStartBalance = AccountBalance();
lastBarTime = 0;
fridayCloseExecuted = false;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}
//+------------------------------------------------------------------+
//| Calculate Supertrend value |
//+------------------------------------------------------------------+
double CalculateSupertrend(int shift, int &direction)
{
double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, shift);
double hl2 = (iHigh(Symbol(), PERIOD_H1, shift) + iLow(Symbol(), PERIOD_H1, shift)) / 2;
double upperBand = hl2 + (SupertrendMultiplier atr);
double lowerBand = hl2 - (SupertrendMultiplier atr);
static double prevUpperBand = 0;
static double prevLowerBand = 0;
static int prevDirection = 0;
if(shift == 1)
{
prevUpperBand = 0;
prevLowerBand = 0;
prevDirection = 0;
}
int newDirection = 0;
double supertrend = 0;
if(shift == 1)
{
newDirection = 1;
supertrend = lowerBand;
}
else
{
if(prevDirection == 1)
{
if(iClose(Symbol(), PERIOD_H1, shift) > prevLowerBand)
{
newDirection = 1;
supertrend = (lowerBand > prevLowerBand) ? lowerBand : prevLowerBand;
}
else
{
newDirection = -1;
supertrend = (upperBand < prevUpperBand) ? upperBand : prevUpperBand;
}
}
else if(prevDirection == -1)
{
if(iClose(Symbol(), PERIOD_H1, shift) < prevUpperBand)
{
newDirection = -1;
supertrend = (upperBand < prevUpperBand) ? upperBand : prevUpperBand;
}
else
{
newDirection = 1;
supertrend = (lowerBand > prevLowerBand) ? lowerBand : prevLowerBand;
}
}
else
{
newDirection = 1;
supertrend = lowerBand;
}
}
prevUpperBand = upperBand;
prevLowerBand = lowerBand;
prevDirection = newDirection;
direction = newDirection;
return supertrend;
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Daily equity protection
double currentEquity = AccountEquity();
double lossPercent = (dailyStartBalance - currentEquity) / dailyStartBalance 100;
if(lossPercent >= DailyLossLimit)
{
Comment("Daily loss limit reached. No new trades.");
return;
}
// Friday close before weekend
if(UseFridayClose && !fridayCloseExecuted)
{
datetime currentTime = TimeCurrent();
if(TimeDayOfWeek(currentTime) == 5 && TimeHour(currentTime) >= 21)
{
CloseAllOrders();
fridayCloseExecuted = true;
return;
}
if(TimeDayOfWeek(currentTime) != 5)
fridayCloseExecuted = false;
}
// Spread filter
if(MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread)
{
Comment("Spread too high: ", MarketInfo(Symbol(), MODE_SPREAD));
return;
}
// New bar logic (H1)
if(Time[0] == lastBarTime)
return;
lastBarTime = Time[0];
// Check existing position and manage breakeven
int posCount = CountPositions();
if(posCount > 0)
{
ManageBreakeven();
return;
}
breakevenApplied = false;
// Calculate indicators on closed bar
int supertrendDir = 0;
double supertrend = CalculateSupertrend(1, supertrendDir);
double adx = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);
double close1 = iClose(Symbol(), PERIOD_H1, 1);
double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
if(atr <= 0) atr = 150 Point;
if(adx < ADXThreshold)
{
Comment("ADX below threshold: ", adx);
return;
}
int cmd = -1;
double sl = 0, tp = 0;
double ask = Ask;
double bid = Bid;
// Buy signal: Supertrend bullish (direction = 1) and price above Supertrend line
if(supertrendDir == 1 && close1 > supertrend)
{
cmd = OP_BUY;
sl = bid - (atr ATRStopMultiplier);
tp = bid + (atr ATRTakeMultiplier);
}
// Sell signal: Supertrend bearish (direction = -1) and price below Supertrend line
else if(supertrendDir == -1 && close1 < supertrend)
{
cmd = OP_SELL;
sl = ask + (atr ATRStopMultiplier);
tp = ask - (atr ATRTakeMultiplier);
}
if(cmd != -1)
{
int ticket = OrderSend(Symbol(), cmd, LotSize, (cmd==OP_BUY?ask:bid), 3, sl, tp, "EURUSD Trend EA", MagicNumber, 0, clrNONE);
if(ticket < 0)
Print("OrderSend failed: ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Manage breakeven stop loss for open position |
//+------------------------------------------------------------------+
void ManageBreakeven()
{
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
if(breakevenApplied) break;
double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
if(atr <= 0) atr = 150 Point;
double breakevenLevel = atr BreakevenTrigger;
if(OrderType() == OP_BUY)
{
double profitPoints = (Bid - OrderOpenPrice()) / Point;
if(profitPoints >= breakevenLevel / Point && OrderStopLoss() < OrderOpenPrice())
{
if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), OrderTakeProfit(), 0, clrNONE))
{
breakevenApplied = true;
Print("Breakeven applied for BUY #", OrderTicket());
}
}
}
else if(OrderType() == OP_SELL)
{
double profitPoints = (OrderOpenPrice() - Ask) / Point;
if(profitPoints >= breakevenLevel / Point && (OrderStopLoss() > OrderOpenPrice() || OrderStopLoss() == 0))
{
if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), OrderTakeProfit(), 0, clrNONE))
{
breakevenApplied = true;
Print("Breakeven applied for SELL #", OrderTicket());
}
}
}
break;
}
}
}
}
//+------------------------------------------------------------------+
//| Count open positions with this MagicNumber |
//+------------------------------------------------------------------+
int CountPositions()
{
int count = 0;
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
count++;
}
}
return count;
}
//+------------------------------------------------------------------+
//| Close all orders for this symbol and magic |
//+------------------------------------------------------------------+
void CloseAllOrders()
{
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
if(OrderType() == OP_BUY)
OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrNONE);
else if(OrderType() == OP_SELL)
OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrNONE);
}
}
}
}
//+------------------------------------------------------------------+
``Reference: Original MQL4 code for educational purposes.
Disclaimer: Forex trading involves significant risk of loss. This EA is provided as-is without any guarantee of profitability. Always test on a demo account before live deployment. Past performance does not guarantee future results.