Como puedo saber si una posicion ya ha sido cerrada?

 
Necesito ayuda para saber si es posible ejecutar la siguiente accion con un AE en MQL5: cuando se cierre una posición de venta con un ID especifico busque una posición de compra con un ID correspondiente y modifique ese take profit de la posición de compra solo si anteriormente se ha cerrado la posición de venta
 
Maria Camila Lozada Betancourth:

Le confirmo que es posible.

 
Miguel Angel Vico Alba # : Le confirmo que es posible.

Este es mi AE, manda una orden de venta y una orden de compra a un minuto especifico y van con un ID en un paquete, y ambas se guardan dentro del mismo paquete, como podría hacer, para que cuando se cierre la orden de venta del paquete 1, busque la operación de compra que se abrió junto con ese mismo paquete #1 y modifique el Take Profit solo para esa compra que pertenece a ese paquete 1 y haga lo mismo para cada paquete de envío.

En mi EA se vende y se cierra la orden y el EA no identifica que se ha cerrado la operación, actúa como si siguiera activa.

Necesito una guía para saber como podría hacer funcionar correctamente el AE

¡Gracias!

//+------------------------------------------------------------------+
//|                           Combined_VerticalLinesAndOrders.mq5    |
//|                        Copyright 2024, MetaQuotes Software Corp. |
//+------------------------------------------------------------------+
#property strict

#include <Trade\Trade.mqh>
CTrade trade;

// Estructura para almacenar el ticket, el precio de cierre y el paquete
struct TicketCloseSell
  {
   int                ticket;         // Ticket de la operación
   double             closeSell;   // Precio de cierre calculado (precio de apertura - 180 pips)
   int                packageID;       // Identificador del paquete (para asociar cada operación)
   bool               mensajeImpreso;   // Bandera para asegurarse de que el mensaje se imprima solo una vez
   bool               mensajeVentaAbierta; // Nueva bandera para asegurar que el mensaje de "venta abierta" se imprima solo una vez
  };
  
   // Estructura para almacenar el ticket, el precio de apertura y el paquete de la compra
struct TicketOpenBuy
{
   int           ticket;           // Ticket de la operación de compra
   double        openBuy;       // Precio de apertura de la compra
   int           packageID;         // Identificador del paquete (para asociar cada operación)
};

// Arrays para almacenar los valores de closeSell y openBuy por paquete
TicketCloseSell closeSells[];
TicketOpenBuy openBuys[];


// Parámetros de la operación
input double TamañoLote = 0.01 ;   // Tamaño de cada lote de operación
input double StopLoss = 0 ;         // Stop Loss en puntos
input double TakeProfit = 100 ;     // Take Profit en puntos para sell
input double TakeProfitBuy = 0 ;     // Take Profit específico para Buy

// Variables globales
datetime lastDrawTime = 0 ;
datetime tiempoUltimaVela = 0 ;
string eaObjectPrefix = "EA_Object_" ;

// Variable para el identificador de paquete
int packageCounter = 0 ;
double spreadEnPips;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
  {
// Inicializar la última hora de dibujo
   lastDrawTime = TimeCurrent ();

// Imprimir mensaje de inicialización
   Print ( "EA iniciado correctamente." );

// Establecer temporizador a 1 segundo para verificar el cierre de nuevas velas
   EventSetTimer ( 1 );
   return ( INIT_SUCCEEDED );
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
  {
// Eliminar temporizador
   EventKillTimer ();
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick ()
  {
  
  VerificacionOrdenSell();
 // Llamar a la función LlegoAlPrecio cada vez que haya un nuevo tick
   }
//+------------------------------------------------------------------+
//| Expert timer function                                           |
//+------------------------------------------------------------------+
void OnTimer ()
  {
// Verificar si la vela actual se ha cerrado
   MqlRates InfoPrecios[];
   ArraySetAsSeries (InfoPrecios, true );
   int DatosPrecios = CopyRates ( _Symbol , _Period , 0 , 2 , InfoPrecios);

   if (DatosPrecios > 1 )
     {
       datetime tiempoVelaActual = InfoPrecios[ 1 ].time;

       // Ejecutar órdenes solo si el tiempo de la última vela cerrada es diferente al actual
       if (tiempoVelaActual != tiempoUltimaVela)
        {
         // Actualizar el tiempo de la última vela
         tiempoUltimaVela = tiempoVelaActual;

         // Verificar si es la hora con 26 minutos para enviar órdenes
         MqlDateTime dt;
         TimeToStruct (tiempoVelaActual, dt);

         // Verificar si el minuto es 26
         if (dt.min == 21 || dt.min == 22 || dt.min == 23 || dt.min == 24 || dt.min == 25 )
           {
             // Incrementar el contador de paquetes
            packageCounter++;

             // Obtener los precios actuales de Ask y Bid
             double Ask = NormalizeDouble ( SymbolInfoDouble ( _Symbol , SYMBOL_ASK ), _Digits );
             double Bid = NormalizeDouble ( SymbolInfoDouble ( _Symbol , SYMBOL_BID ), _Digits );

             // Inicializar niveles de Stop Loss y Take Profit con valores predeterminados
             double nivelStopLossCompra = 0 ;
             double nivelTakeProfitCompra = 0 ;
             double nivelStopLossVenta = 0 ;
             double nivelTakeProfitVenta = 0 ;

             // Calcular niveles de Stop Loss y Take Profit si no son cero
             if (StopLoss > 0 )
              {
               nivelStopLossCompra = Ask - StopLoss * _Point ;
               nivelStopLossVenta = Bid + StopLoss * _Point ;
              }

             if (TakeProfit > 0 )
              {
               nivelTakeProfitCompra = Ask + TakeProfitBuy * _Point ;
               nivelTakeProfitVenta = Bid - TakeProfit * _Point ;
              }

             if (TakeProfitBuy > 0 )
              {
               nivelTakeProfitCompra = Ask + TakeProfitBuy * _Point ;
               nivelTakeProfitVenta = Bid - TakeProfit * _Point ;
              }

             // Asignar el identificador del paquete a cada orden
             string packageLabel = "Package_" + IntegerToString (packageCounter);

             // Abrir una orden de compra
             bool buyResult = trade.Buy(TamañoLote, NULL , Ask,
                                       (StopLoss > 0 ) ? nivelStopLossCompra : 0 ,
                                       (TakeProfitBuy > 0 ) ? nivelTakeProfitCompra : 0 ,
                                       packageLabel);

             // Incrementar el contador de órdenes de compra y reiniciar si llega a 10
             if (buyResult)
              {
              
               // Registrar la compra
              RegistrarCompra(trade.ResultOrder(), packageCounter, Ask);
               Print ( "Orden de compra ejecutada, Paquete: " , packageLabel);
              }

             // Abrir una orden de venta
             bool sellResult = trade.Sell(TamañoLote, NULL , Bid,
                                         (StopLoss > 0 ) ? nivelStopLossVenta : 0 ,
                                         (TakeProfit > 0 ) ? nivelTakeProfitVenta : 0 ,
                                         packageLabel);

             if (sellResult)
              {
               Print ( "Orden de venta ejecutada, Paquete: " , packageLabel);

               // Obtener el ticket de la operación de venta
               int ticket = trade.ResultOrder();

               // Calcular y almacenar el precio de cierre de la venta
               double closeSell = Bid - 140 * _Point ; // Cerrar 180 pips por debajo del precio de apertura de la venta

               // Almacenar los detalles de la operación en el array closeSells
               ArrayResize (closeSells, ArraySize (closeSells) + 1 );
               closeSells[ ArraySize (closeSells) - 1 ].ticket = ticket;
               closeSells[ ArraySize (closeSells) - 1 ].closeSell = closeSell;
               closeSells[ ArraySize (closeSells) - 1 ].packageID = packageCounter;

               //Print("Precio de cierre calculado y guardado para el ticket ", ticket, ": ","CloseSell", closeSell);
              }

             // Imprimir resultados de la apertura de órdenes
             if (buyResult && sellResult)
              {
               // Print("Las órdenes de compra y venta se ejecutaron correctamente. Paquete: ", packageLabel);
              }
             else
              {
               Print ( "Error al ejecutar las órdenes. Compra: " , buyResult, ", Venta: " , sellResult, "error: " , GetLastError ());
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Funcion Registrar Compra                                         |
//+------------------------------------------------------------------+
   // Función para registrar la operación de compra
void RegistrarCompra( int ticketCompra, int packageID, double precioCompra)
{
   //Print("entro a registrar compra");
     ArrayResize (openBuys, ArraySize (openBuys) + 1 );
    openBuys[ ArraySize (openBuys) - 1 ].ticket = ticketCompra;
    openBuys[ ArraySize (openBuys) - 1 ].packageID = packageID;
    openBuys[ ArraySize (openBuys) - 1 ].openBuy = precioCompra;
     //Print("Compra registrada, Paquete: ", packageID, ", Ticket de compra: ", ticketCompra, ", Precio de apertura: ", precioCompra);
}
//+------------------------------------------------------------------+
//| funcion NewTakeProfit                                            |
//+------------------------------------------------------------------+
// Función que se llama después de imprimir "Operación cerrada con éxito para el paquete ..."
void NewTakeProfitBuy( int packageID)
{
     // Iterar a través de todas las operaciones de compra para encontrar la posición de compra del paquete
     for ( int i = 0 ; i < ArraySize (openBuys); i++)
    {
         if (openBuys[i].packageID == packageID)
        {
             // Obtener el ticket de la compra
             int buyTicket = openBuys[i].ticket;
             double buyOpenPrice = openBuys[i].openBuy;   // Obtener el precio de apertura de la compra

             // Imprimir el precio de apertura de la operación de compra
             //Print("Posición de compra del paquete ", packageID, " precio de apertura: ", buyOpenPrice, "buy Ticket: ", buyTicket);
            
             // Calcular el nuevo TakeProfit para la orden de compra
             double nuevoTakeProfit = buyOpenPrice + 350 * _Point ; // 400 pips de TakeProfit

             // Intentar modificar el TakeProfit de la orden de compra
             if ( PositionSelectByTicket (buyTicket))
            {
                 // Cambiar el TakeProfit de la orden de compra
                 if (trade.PositionModify(buyTicket, 0 , nuevoTakeProfit))
                {
                     // Imprimir mensaje de éxito
                     Print ( "TakeProfit actualizado con éxito para el paquete " , packageID, ", Nuevo TakeProfit: " , nuevoTakeProfit, "Ticked Buy: " ,buyTicket);
                }
                 else
                {
                     // Imprimir error si no se puede modificar el TakeProfit
                     Print ( "Error al modificar el TakeProfit para el paquete " , packageID, ", error: " , GetLastError ());
                }
            }
             else
            {
                 // Si no se puede seleccionar la posición
                 Print ( "No se pudo seleccionar la posición con ticket " , buyTicket);
            }
            
             break ; // Detener el ciclo una vez encontrado el paquete
        }
    }
}

//+------------------------------------------------------------------+
//| Verificación de si las órdenes de venta están cerradas           |
//+------------------------------------------------------------------+
void VerificacionOrdenSell()
{
   // Iterar a través de todos los paquetes en el array closeSells
   for ( int i = 0 ; i < ArraySize (closeSells); i++)
   {
       // Obtener el ticket de la operación de venta
       int ticketSell = closeSells[i].ticket;

       // Intentar seleccionar la posición de venta por ticket
       bool isPositionSelected = PositionSelectByTicket (ticketSell);

       // Si no se puede seleccionar la posición (la operación fue cerrada)
       if (!isPositionSelected)
      { Print (isPositionSelected);
         // Si no se ha impreso el mensaje de cierre para este paquete, lo hacemos ahora
         if (!closeSells[i].mensajeImpreso)
         { 
             // Imprimir el paquete que se cerró
             Print ( "La orden de venta con ticket " , ticketSell, " se ha cerrado para el paquete " , closeSells[i].packageID);

             // Marcar la operación como cerrada e imprimir el mensaje de cierre
            closeSells[i].mensajeImpreso = true ;
         }
      }
       else
      {

      }
   }
}