Problema con la cantidad total de órdenes abiertas

 

Hola a todos. He probado todos los consejos que he encontrado en este foro, pero ninguno parece funcionar. Alguien podría ayudarme. Creo que el problema radica en mi función OrderTotal. Estoy operando con 10 pares de divisas, es decir, tengo el EA abierto en 10 gráficos. Se trata de una simple estrategia de cobertura. Quiero que el EA abra una operación (larga o corta) dependiendo de las señales. Si la operación va en mi dirección, Trailingstop o Take profit. Si, por el contrario, la operación va en mi contra, quiero que abra una operación en la dirección opuesta. El código que estoy utilizando parece funcionar pero a veces se queda atascado, es decir, ya no abre ninguna operación. Además, cuando hay una o dos operaciones abiertas en un par, no parece querer abrir ninguna operación en otros pares.

Este es mi código

int start()
{
     {
     if (OrdersTotal() == 0)
     if(Close[1]>Close[2])
         result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*0.0001, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());
         }

  for(int i=OrdersTotal()-1; i>=0; i--) 
  {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
      if (OrderSymbol()==Symbol())
      //Calculate the point value in case there are extra digits in the quotes
      if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;
      else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.0001) PointValue = 0.01;
      else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01;
      else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);

//calculate new lotsize of hedge based on lotsize of current open trade*Multiplier
      double lots = NormalizeDouble(OrderLots() * Multiplier, 2); 
      
     if (OrderType() == OP_BUY) 
      {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *PointValue,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *PointValue,Digits))
            {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *PointValue,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
              }
            }
            else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*PointValue,Digits))
            if(OrdersTotal() == 1)
            result=OrderSend(Symbol(), OP_SELL, lots, Bid, 3,  Bid + Stoploss*PointValue, 0, "Hedge", 0, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
          }
 
  1. Hay que filtrar los oficios.
          if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
          if (OrderSymbol()==Symbol())
          if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;  // These
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.0001) PointValue = 0.01;// four
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01; // lines
          else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);                    // Execute only on Symbol orders.
    
          double lots = NormalizeDouble(OrderLots() * Multiplier, 2);  // This and below are always executed
          if (OrderType() == OP_BUY)                                   // Symbol is irrelevant.             
    
    Con corchetes.
          if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
          if (OrderSymbol()==Symbol())
    {                                                                   // Rest of code executes only on Symbol orders.
          if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.0001) PointValue = 0.01;
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01;
          else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);
    
          double lots = NormalizeDouble(OrderLots() * Multiplier, 2); 
          
          if (OrderType() == OP_BUY) 
             :
    }

  2. En un corredor de 4 dígitos, punto = 0,0001
          if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.0001) PointValue = 0.01;
          else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01;
          else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);
    
    Fijo y simplificado.
    PointValue = MarketInfo(OrderSymbol(), MODE_POINT);
    if(MarketInfo(OrderSymbol(), MODE_DIGITS) % 2 = 1) PointValue *= 10;

  3. Como todo lo que está dentro de las llaves es Symbol(), cada MarketInfo puede ser reemplazado por variables predefinidas
  4. No codifique los números con fuerza.
    Compruebe sus códigos de retorno¿Qué son los valores de retorno de las funciones? ¿Cómo los utilizo? -Foro MQL4 y Errores comunes en los programas MQL4 y como evitarlos - Artículos MQL4
    result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*0.0001, 0, "Original", magicNumber, 0, Blue);
 

1. Muchas gracias por su ayuda. He añadido una abrazadera como se sugiere, pero el EA todavía sólo se abre un comercio en un par de divisas. No se abrirá un comercio en cualquiera de los otros gráficos a pesar de que la condición de compra se han cumplido. He estado atascado en esto durante semanas, por favor, eche otro vistazo.

2. EDIT: Ya no es necesario

3. Mi código ahora se ve así

int start()
{
  {
    if (OrdersTotal() == 0)
    if(Close[1]>Close[2])
         result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*Point*10, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());
  }       

  for(int i=OrdersTotal()-1; i>=0; i--) 
    {
      //calculate new lotsize of hedge based on lotsize of current open trade*Multiplier
      double lots = NormalizeDouble(OrderLots() * Multiplier, 2);
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true)
      if (OrderSymbol()==Symbol())
    { 
     if (OrderType() == OP_BUY) 
       {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *Point*10,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *Point*10,Digits))
           {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *Point*10,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
           }
         }
            else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits))
            if(OrdersTotal() == 1)
            result=OrderSend(Symbol(), OP_SELL, lots, Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", 0, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
       }
 
    if (OrdersTotal() == 0)
    if(Close[1]>Close[2])
         result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*PointValue, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());
Si una orden está abierta en cualquier par, no abrirá otra orden hasta que OrdersTotal()==0 de nuevo
 
GumRai:
Si una orden está abierta en cualquier par, no abrirá otra orden hasta que OrdersTotal()==0 de nuevo

Gracias por su ayuda. Necesito limitar la primera orden original a una sola operación. No quiero que el EA continúe abriendo órdenes cuando se cumpla la condición de compra. Así que añadí el Orderstotal para limitar esto. Este código, sin embargo, parece interferir con el código aquí

else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits))
            if(OrdersTotal() == 1) //<----------
            result=OrderSend(Symbol(), OP_SELL, lots, Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", 0, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());

Aquí sólo quiero que el EA abra una cobertura por operación abierta, por lo tanto OrderTotal ==1

Entonces, ¿cuál es la mejor manera de limitar el número de operaciones, es decir, una operación original y una operación de cobertura? Gracias

 
Trader3000: Entonces, ¿cuál es la mejor manera de limitar el número de operaciones, es decir, una operación original y una operación de cobertura?
  1. Así que cuenta el número de órdenes que están abiertas en el gráfico actual. OrdersTotal devuelve el número de órdenes que están abiertas en todos los gráficos.
  2. El hecho de no filtrar por número mágico hace que el EA sea incompatible con todos los demás (incluido él mismo en otros TFs,) y el comercio manual El símbolo no es igual al símbolo de la orden cuando se añade otra moneda a otro gráfico separado . - Foro MQL4
 

Muchas gracias por la ayuda de todos. He resuelto el problema y el EA ahora abrirá una operación en todos los gráficos cuando se cumpla la condición de compra, sin embargo, nada por debajo de esto está funcionando ahora. El EA no está llamando a las funciones Trailingstop o Hedge. Podría alguien echar un vistazo y decirme qué hice mal porque soy incapaz de averiguarlo.

int start()
{ 
   double Lots = NormalizeDouble(AccountEquity()*Percentage*Lotsize/100, 2);
   double lots = NormalizeDouble(OrderLots() * Multiplier, 2);
   total=0;
   for(i = OrdersTotal()-1; i >= 0 ; i--)
   if ( OrderSelect(i, SELECT_BY_POS)                
    &&  OrderMagicNumber()  == magicNumber            
    &&  OrderSymbol()       == Symbol())
    {             
      total++;
    }
    {
    if(total==0 )
    if(Close[1]>Close[2])
    {
         result=OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, Ask - StopLoss*Point*10, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());     
    }
    
     if (OrderType() == OP_BUY) 
       {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *Point*10,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *Point*10,Digits))
           {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *Point*10,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
           }
         }
 else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits))
            if(total == 1)
            result=OrderSend(Symbol(), OP_SELL, lots, Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", magicNumber, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
       }
 
   double Lots = NormalizeDouble(AccountEquity()*Percentage*Lotsize/100, 2);
   double lots = NormalizeDouble(OrderLots() * Multiplier, 2);

No sé exactamente lo que estás haciendo, pero te sugiero que evites nombrar 2 variables con la única diferencia de una letra mayúscula. Es fácil confundir las 2, sobre todo cuando otros que están leyendo su código bien puede haber adoptado la convención de que las variables que comienzan con una letra mayúscula son Globalscope.

No se ha seleccionado ningún orden, por lo que OrderLots() podría ser cualquier cosa


    
     if (OrderType() == OP_BUY) 

Esto utilizaría los valores del último pedido seleccionado en el bucle anterior, puede no ser el número o símbolo mágico correcto.

 

Gracias por su respuesta. Lo que estoy tratando de hacer es que el EA abra la primera operación original donde el tamaño del lote es un porcentaje de mi capital. Si la operación va en contra

Yo, el EA debe abrir una cobertura en la dirección opuesta, pero aquí el tamaño de los lotes debe ser 3 veces el tamaño original de los lotes (OrderLots).

orden ha sido seleccionada, no parece afectar a la operación. Ahora he colocado los Lots directamente en la función OrderSend, pero ni el trailingstop ni

la cobertura se activa cuando debe. Ambos funcionaban perfectamente antes de que yo añadiera esto

total=0;
   for(i = OrdersTotal()-1; i >= 0 ; i--)
   if ( OrderSelect(i, SELECT_BY_POS)                
    &&  OrderMagicNumber()  == magicNumber            
    &&  OrderSymbol()       == Symbol())
    {             
      total++;
    }

int start()
{ 
   double Lots = NormalizeDouble(AccountEquity()*Percentage*Lotsize/100, 2);
   
   total=0;
   for(i = OrdersTotal()-1; i >= 0 ; i--)
   if ( OrderSelect(i, SELECT_BY_POS)                
    &&  OrderMagicNumber()  == magicNumber            
    &&  OrderSymbol()       == Symbol())
    {             
      total++;
    }
    {
    if(total==0 )
    if(Close[1]>Close[2])
         result=OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, Ask - StopLoss*Point*10, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());     
    }
    {
     if (OrderType() == OP_BUY) 
       {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *Point*10,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *Point*10,Digits))
           {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *Point*10,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
           }
         }
            else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits))
            if(total == 1)
            result=OrderSend(Symbol(), OP_SELL, NormalizeDouble(OrderLots() * Multiplier, 2), Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", magicNumber, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
       }

Creo que mis llaves {} no están en los lugares correctos

 
Ya te lo dije en la segunda parte de mi anterior post
 

Muchas gracias por toda la ayuda que me han dado hasta ahora, estoy progresando y ahora todo parece funcionar como debería, excepto que el EA ignora la condición para abrir una operación de cobertura. A veces (pero no siempre) abre una operación de cobertura incluso cuando las condiciones no se han cumplido. También el TrailingStop no siempre se activa. Creo que todavía me faltan llaves {} en alguna parte. Mi código ahora se ve así. ¿Podría alguien echar un vistazo por mí? Gracias.

int start()
{ 
   total=0;
   for(i = OrdersTotal()-1; i >= 0 ; i--)
   if ( OrderSelect(i, SELECT_BY_POS)                
    &&  OrderMagicNumber()  == magicNumber            
    &&  OrderSymbol()       == Symbol())
    {             
      total++;
    }
    {
    if(total==0 )
    if(Close[1]>Close[2])
    {
         result=OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Ask - StopLoss*Point*10, 0, "Original", magicNumber, 0, Blue);
         Print("Error setting Original order: ",GetLastError());     
    }
     if (OrderType() == OP_BUY) 
       {
        if (Bid - OrderOpenPrice() > NormalizeDouble(TrailingStart *Point*10,Digits))
         {
           if (OrderStopLoss() < Bid - NormalizeDouble(TrailingStop *Point*10,Digits))
           {
              if (OrderModify(OrderTicket(), OrderOpenPrice(), Bid - NormalizeDouble(TrailingStop *Point*10,Digits),
              OrderTakeProfit(), Blue)) 
              Print("Error setting Buy trailing stop: ",GetLastError()); 
           }
         }
            else if (OrderOpenPrice() > Bid + NormalizeDouble(Hedge*Point*10,Digits)) //<------- THIS IS BEING IGNORED SOMETIMES (I THINK)
            if(total == 1)
            {
            result=OrderSend(Symbol(), OP_SELL, NormalizeDouble(OrderLots() * Multiplier, 2), Bid, 3,  Bid + Stoploss*Point*10, 0, "Hedge", magicNumber, 0, Blue);
            Print("Error setting Sell Hedge: ", GetLastError());
            }
       }
      // else if (OrderType() == OP_SELL)
      // ... 

GumRai:

This would use the values from the last order selected in the previous loop, it may not be the correct magic number or symbol.


He intentado arreglar esto cambiando las llaves. ¿Es esa la mejor manera, o tengo que duplicar y añadir la función OrderSelect cada vez antes de OrderSend? Gracias