Trang chủ Kiến thức OrderModify() trong MQL5: Chỉnh Sửa Stop Loss và Take Profit
Knowledge

OrderModify() trong MQL5: Chỉnh Sửa Stop Loss và Take Profit

14 tháng 11, 2025

Modify existing positions - update SL/TP, trailing stop, breakeven implementation.

Modify Position SL/TP

Basic Modification

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;
}

Trailing Stop Implementation

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));
        }
    }
}

Move to Breakeven

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