Trang chủ Kiến thức Close Position trong MQL5: Đóng Lệnh
Knowledge

Close Position trong MQL5: Đóng Lệnh

14 tháng 11, 2025

Close open positions - partial close, close by ticket, close all positions.

Close Position Functions

Close Single Position

bool ClosePosition(ulong ticket) {
    if(!PositionSelectByTicket(ticket)) {
        Print("Position not found: ", ticket);
        return false;
    }
    
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    request.action = TRADE_ACTION_DEAL;
    request.position = ticket;
    request.symbol = PositionGetString(POSITION_SYMBOL);
    request.volume = PositionGetDouble(POSITION_VOLUME);
    request.deviation = 10;
    
    // Opposite order type
    ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
    request.type = (posType == POSITION_TYPE_BUY) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
    
    // Get close price
    if(request.type == ORDER_TYPE_SELL) {
        request.price = SymbolInfoDouble(request.symbol, SYMBOL_BID);
    } else {
        request.price = SymbolInfoDouble(request.symbol, SYMBOL_ASK);
    }
    
    bool success = OrderSend(request, result);
    
    if(success && result.retcode == TRADE_RETCODE_DONE) {
        Print("✅ Position closed: ", ticket);
        return true;
    } else {
        Print("❌ Close failed: ", result.retcode);
        return false;
    }
}

Close All Positions

int CloseAllPositions(long magic = 0) {
    int closedCount = 0;
    
    // Loop backward (important!)
    for(int i = PositionsTotal() - 1; i >= 0; i--) {
        ulong ticket = PositionGetTicket(i);
        if(ticket == 0) continue;
        
        // Check magic number
        if(magic > 0 && PositionGetInteger(POSITION_MAGIC) != magic)
            continue;
        
        if(ClosePosition(ticket)) {
            closedCount++;
        }
    }
    
    Print("Closed ", closedCount, " positions");
    return closedCount;
}

Partial Close

bool PartialClose(ulong ticket, double volumeToClose) {
    if(!PositionSelectByTicket(ticket)) return false;
    
    double currentVolume = PositionGetDouble(POSITION_VOLUME);
    
    // Validate volume
    if(volumeToClose >= currentVolume) {
        return ClosePosition(ticket);  // Close entire position
    }
    
    double minVol = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
    if(volumeToClose < minVol) {
        Print("Volume too small");
        return false;
    }
    
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    request.action = TRADE_ACTION_DEAL;
    request.position = ticket;
    request.symbol = PositionGetString(POSITION_SYMBOL);
    request.volume = NormalizeDouble(volumeToClose, 2);
    request.deviation = 10;
    
    ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
    request.type = (posType == POSITION_TYPE_BUY) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
    
    if(request.type == ORDER_TYPE_SELL) {
        request.price = SymbolInfoDouble(request.symbol, SYMBOL_BID);
    } else {
        request.price = SymbolInfoDouble(request.symbol, SYMBOL_ASK);
    }
    
    return OrderSend(request, result);
}

// Usage: Close 50% of position
double currentVol = PositionGetDouble(POSITION_VOLUME);
PartialClose(ticket, currentVol * 0.5);