Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
In MetaTrader 4, you don’t have to sit in front of the chart all day, watching every candle and moving your stop loss by hand. With a simple Expert Advisor (EA), you can make the platform move your stop loss to break even, trail your stop behind price, and protect your profit automatically.
If you’ve ever wondered how to code break even and trailing stop in mql4, you’re basically asking, “How do I teach my EA to manage trades like a disciplined trader?” That’s exactly what we’ll cover here.
In this guide, you’ll learn:
You don’t need to be a pro programmer. If you understand basic MT4 usage and can follow simple logic, you’ll be able to adapt the code to your own trading strategy.
Before we write any code, you need to understand the basic trade management concepts your EA will use.
In MQL4, you set or change it with OrderSend() and OrderModify().
Your break-even and trailing stop usually work together with SL and TP for complete risk management.
Moving stop loss to break even means:
Example idea for a buy:
A trailing stop moves your SL automatically as price moves in your favor.
Simple fixed trailing stop idea:
Trailing stops help you let profits run while still protecting part of your unrealized profit.
To implement all this, you’ll work in MetaEditor, which is part of MetaTrader 4.
F4.BreakEvenTrailingEA.start() as the main tick function: int start() { // Your trade management code will go here return(0); }https://docs.mql4.comOnce everything’s set up, you’re ready to write the actual break-even and trailing stop logic.
Many new coders get confused by pips and points. Your break-even and trailing-distance logic must be precise, or you’ll move stops to the wrong place.
Digits is the number of decimal places of the symbol.
Point is the smallest price step.
If you want to work in pips, you can define a helper like:
double PipValue()
{
if (Digits == 3 || Digits == 5)
return(Point * 10);
return(Point);
}
Then, a 20-pip distance is:
double distance = 20 * PipValue();
Using a helper like this keeps your EA working on both 4- and 5-digit brokers.
Now we’ll implement the core break-even logic that moves stop loss to entry (plus an optional small buffer).
First, define external parameters at the top of your EA:
extern int BreakEvenTriggerPips = 20; // distance in pips before BE
extern int BreakEvenOffsetPips = 2; // extra pips to lock profit
extern int MagicNumber = 12345;
Inside start(), you’ll loop through open orders:
int start()
{
ManageBreakEven();
return(0);
}
void ManageBreakEven()
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
continue;
if(OrderSymbol() != Symbol())
continue;
if(OrderMagicNumber() != MagicNumber)
continue;
// Only manage market orders
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
ApplyBreakEvenToOrder();
}
}
This pattern ensures:
Now let’s write ApplyBreakEvenToOrder() to handle buys:
void ApplyBreakEvenToOrder()
{
double pip = PipValue();
double triggerDistance = BreakEvenTriggerPips * pip;
double offset = BreakEvenOffsetPips * pip;
// For BUY trades
if(OrderType() == OP_BUY)
{
double currentPrice = Bid;
double entryPrice = OrderOpenPrice();
double sl = OrderStopLoss();
// Price must have moved enough in profit
if(currentPrice - entryPrice >= triggerDistance)
{
double newSL = entryPrice + offset;
// Only move SL forward (never backward)
if(sl < newSL)
{
newSL = NormalizeDouble(newSL, Digits);
bool modified = OrderModify(
OrderTicket(),
OrderOpenPrice(),
newSL,
OrderTakeProfit(),
0,
clrNONE
);
if(!modified)
Print("BreakEven BUY failed. Error: ", GetLastError());
}
}
}
// SELL logic will follow
}
Key points:
BreakEvenTriggerPips.entryPrice + offset for a buy.Now add the sell part inside the same function:
// For SELL trades
if(OrderType() == OP_SELL)
{
double currentPrice = Ask;
double entryPrice = OrderOpenPrice();
double sl = OrderStopLoss();
if(entryPrice - currentPrice >= triggerDistance)
{
double newSL = entryPrice - offset;
// For SELL, a "better" SL is lower (closer to price in profit)
if(sl == 0 || sl > newSL)
{
newSL = NormalizeDouble(newSL, Digits);
bool modified = OrderModify(
OrderTicket(),
OrderOpenPrice(),
newSL,
OrderTakeProfit(),
0,
clrNONE
);
if(!modified)
Print("BreakEven SELL failed. Error: ", GetLastError());
}
}
}
Now you have a working break-even manager for both buy and sell orders.
Next, we’ll create a fixed trailing stop. This will keep your stop loss a set distance from the current price once the trade is in profit.
Add these external inputs:
extern int TrailingStopPips = 30; // distance from price
extern int TrailingStepPips = 5; // minimum step to move SL
Then, add a new function:
void ManageTrailingStop()
{
double pip = PipValue();
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
continue;
if(OrderSymbol() != Symbol())
continue;
if(OrderMagicNumber() != MagicNumber)
continue;
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
ApplyTrailingToOrder();
}
}
And don’t forget to call it inside start() along with the break-even logic:
int start()
{
ManageBreakEven();
ManageTrailingStop();
return(0);
}
Inside ApplyTrailingToOrder(), handle buys like this:
void ApplyTrailingToOrder()
{
double pip = PipValue();
double tsDistance = TrailingStopPips * pip;
double tsStep = TrailingStepPips * pip;
if(OrderType() == OP_BUY)
{
double currentPrice = Bid;
double newSL = currentPrice - tsDistance;
double oldSL = OrderStopLoss();
// Only trail if trade is already in profit beyond trailing distance
if(currentPrice - OrderOpenPrice() > tsDistance)
{
// Only move SL if we are at least tsStep ahead of old SL
if(oldSL < newSL - tsStep || oldSL == 0)
{
newSL = NormalizeDouble(newSL, Digits);
bool modified = OrderModify(
OrderTicket(),
OrderOpenPrice(),
newSL,
OrderTakeProfit(),
0,
clrNONE
);
if(!modified)
Print("Trailing BUY failed. Error: ", GetLastError());
}
}
}
This code:
For sell orders:
if(OrderType() == OP_SELL)
{
double currentPrice = Ask;
double newSL = currentPrice + tsDistance;
double oldSL = OrderStopLoss();
if(OrderOpenPrice() - currentPrice > tsDistance)
{
// For SELL, SL must move downward (closer to current price)
if(oldSL > newSL + tsStep || oldSL == 0)
{
newSL = NormalizeDouble(newSL, Digits);
bool modified = OrderModify(
OrderTicket(),
OrderOpenPrice(),
newSL,
OrderTakeProfit(),
0,
clrNONE
);
if(!modified)
Print("Trailing SELL failed. Error: ", GetLastError());
}
}
}
}
Now you have a basic trailing stop engine for both directions.
Usually, you want both behaviors:
A simple way to combine them:
We already did that by calling both functions in start():
int start()
{
ManageBreakEven(); // Step 1: secure the trade
ManageTrailingStop(); // Step 2: trail profits
return(0);
}
If you want stricter control, you can:
ManageTrailingStop() to ensure SL is not moved backwards by mistake.This gives your EA a clear and logical trade-management flow.
Even if your code compiles, it doesn’t mean it works as you imagine. You must test and debug it.
Watch the trade list and confirm:
In the Strategy Tester, check the Journal:
BreakEven BUY failed. Error: 1.You can cross-check error codes in the official docs: https://docs.mql4.com/constants/errors.
Use Strategy Tester’s Optimization:
BreakEvenTriggerPipsBreakEvenOffsetPipsTrailingStopPipsTrailingStepPipsTry to find a balance where:
Here are some typical problems people face while figuring out how to code break even and trailing stop in mql4:
Point directly on 5-digit brokers and expecting pip values.PipValue() helper.ERR_INVALID_STOPS.TrailingStepPips to move SL only when progress is big enough.MagicNumber.OrderMagicNumber().OrderModify().GetLastError().By avoiding these mistakes, your EA will be more stable and easier to maintain.
No. You can put both break-even and trailing-stop logic into the same EA. Just keep the logic organized in separate functions like ManageBreakEven() and ManageTrailingStop(), and call them from start().
Common practice is:
“Invalid stops” usually means:
Check:
Yes, the logic is not tied to a specific symbol or timeframe. However:
BreakEvenTriggerPips and TrailingStopPips) for indices, metals, or crypto versus major forex pairs.Always test each symbol separately in Strategy Tester.
If you remove or adjust the MagicNumber filter, the EA can manage manual trades too. For example:
MagicNumber = 0 and handle orders where OrderMagicNumber() == 0.For continuous management (break even and trailing stops), an EA is usually better because:
Scripts are good for one-time actions; indicators are for visual signals. For ongoing stop management, EA is the right tool.
You’ve now seen the full process of how to code break even and trailing stop in mql4:
From here, you can:
https://docs.mql4.com.With this foundation, you’re no longer just a button-click trader—you’re a trader who can teach the platform exactly how to manage risk and protect profits.