Modify existing positions - update SL/TP, trailing stop, breakeven implementation.
bool ModifyPosition(ulong ticket, double newSL, double newTP) {
MqlTradeRequest request = {};
MqlTradeResult result = {};
request.action = TRADE_ACTION_SLTP;
request.position = ticket;
request.sl = NormalizeDouble(newSL, _Digits);
request.tp = NormalizeDouble(newTP, _Digits);
bool success = OrderSend(request, result);
if(success && result.retcode == TRADE_RETCODE_DONE) {
Print("✅ Position modified");
return true;
}
return false;
}
void ApplyTrailingStop(ulong ticket, int trailingPips) {
if(!PositionSelectByTicket(ticket)) return;
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
double currentSL = PositionGetDouble(POSITION_SL);
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double trailingDistance = trailingPips * point;
double newSL = 0;
if(type == POSITION_TYPE_BUY) {
newSL = currentPrice - trailingDistance;
// Only move SL up, never down
if(newSL > currentSL) {
ModifyPosition(ticket, newSL, PositionGetDouble(POSITION_TP));
}
} else { // SELL
newSL = currentPrice + trailingDistance;
// Only move SL down, never up
if(newSL < currentSL || currentSL == 0) {
ModifyPosition(ticket, newSL, PositionGetDouble(POSITION_TP));
}
}
}
bool MoveToBreakeven(ulong ticket, int triggerPips, int beOffsetPips = 0) {
if(!PositionSelectByTicket(ticket)) return false;
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
double currentSL = PositionGetDouble(POSITION_SL);
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double pips = MathAbs(currentPrice - openPrice) / point;
// Check if profit reached trigger level
if(pips < triggerPips) return false;
double newSL = openPrice + beOffsetPips * point;
if(type == POSITION_TYPE_BUY) {
// Only move if not already at breakeven or better
if(currentSL < openPrice) {
return ModifyPosition(ticket, newSL, PositionGetDouble(POSITION_TP));
}
} else { // SELL
if(currentSL > openPrice || currentSL == 0) {
return ModifyPosition(ticket, newSL, PositionGetDouble(POSITION_TP));
}
}
return false;
}
// Usage: Move to BE after 50 pips profit
MoveToBreakeven(ticket, 50, 5); // BE + 5 pips