How to close positions by symbol and remove pending orders in MQL5?

Hello everyone,

I am working on an MQL5 chart-panel experiment and need clarification about trade handling.

I need two separate functions:

1. Close only positions belonging to the current chart symbol.
2. Close all positions across all symbols and remove all pending orders.

For the current-symbol function, I am considering this filter:

if(PositionGetString(POSITION_SYMBOL) != _Symbol)
   continue;

For the account-wide function, I would remove the symbol filter.

Could experienced MQL5 developers please advise on the following points?

- Is this symbol filter correct for both netting and hedging accounts?
- Is it better to use position tickets when closing positions?
- What is the correct way to remove pending orders by ticket?
- Should OrderSend() or CTrade be preferred for these operations?
- How should partial fills, failed requests and trade retcodes be handled?
- Are there any broker-specific filling-mode or execution checks that should be added?

This is a general programming question. I am not discussing or promoting any Market product.

Thank you.

Muhammad Shoaib:
if(PositionGetString(POSITION_SYMBOL) != _Symbol)
   continue;

Hi Muhammad,

Your symbol filter is correct for both netting and hedging accounts. I recommend using
CTrade with position/order tickets. For pending orders, iterate through the active orders and delete matching tickets. Since the order list can change after deletion, your retry approach is reasonable: re-enumerate after each successful deletion and stop when a full pass makes no progress. Always check ResultRetcode() because a successful method return does not guarantee execution.

#include <Trade/Trade.mqh>

CTrade trade;

// Delete pending orders for the current symbol or the whole account.
int DeletePendingOrders(const bool current_symbol_only = true)
  {
   int deleted = 0;
   int max_passes = OrdersTotal();

   for(int pass = 0; pass < max_passes; pass++)
     {
      bool progress = false;
      int total = OrdersTotal();

      for(int i = total - 1; i >= 0; i--)
        {
         ulong ticket = OrderGetTicket(i);
         if(ticket == 0)
            continue;

         if(current_symbol_only &&
            OrderGetString(ORDER_SYMBOL) != _Symbol)
            continue;

         if(!trade.OrderDelete(ticket))
           {
            PrintFormat("Delete failed #%I64u: %s",
                        ticket, trade.ResultRetcodeDescription());
            continue;
           }

         uint rc = trade.ResultRetcode();
         if(rc == TRADE_RETCODE_DONE)
           {
            deleted++;
            progress = true;
            Sleep(100);
            break; // Refresh the order list on the next pass.
           }

         PrintFormat("Delete rejected #%I64u: %u (%s)",
                     ticket, rc, trade.ResultRetcodeDescription());
        }

      if(!progress)
         break;
     }

   return deleted;
  }
//+------------------------------------------------------------------+
This function deletes pending orders for the current chart symbol, or all symbols if current_symbol_only is false. It follows your retry approach and returns the number of confirmed deletions.