Necesito ayuda para detectar un pequeño error. - página 2

 
Si alguien se anima a echar una mano, por favor .....
 

Parte del problema es la forma en que escribiste ese código con grandes y largas condiciones "if" llenas de &&, ||, y llamadas a funciones tras llamadas a funciones, lo que hace que sea difícil de depurar, tendrías suerte de encontrar a alguien con tiempo para desentrañar ese lío. Deberías mirar los ejemplos de codificación en los documentos para ver cómo el código debería ser formateado en líneas mucho más cortas y comentadas.

 

" Hace que sea difícil de depurar "?? :( Nunca he oído hablar de estos, es este real ....

El compilador también tiene dificultades para depurar mi código :( ?

Si esa es la razón significa que tuve que repensar toda mi idea de codificación para esta parte? Entonces se convertirá en una cosa totalmente diferente ...... :( :(

 

Sí, es difícil de depurar, por ejemplo, mira este código para el trailing stop. Es fácil ver lo que hace cada línea, por lo que es fácil detectar errores.

   int total=OrdersTotal();
   
   for(int cnt=0; cnt<total; cnt++)
   {if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
    {if(OrderType()==OP_BUY)
     {if(TrailingStop>0)
      {if(Bid-OrderOpenPrice()>Point*TrailingStop)
       {if(OrderStopLoss()<Bid-Point*TrailingStop)
        {if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
         {Print("OrderModify error ",GetLastError());
          return;
   }}}}}}}
 
Intenté quitar la condición && y ponerlos como una declaración if como después de .... Pero aún así no funcionó todo el tiempo, a veces sólo movió el stop loss una vez, a veces funcionó bien tanto para órdenes de compra como de venta.
 
SDC: Sí, es difícil de depurar, por ejemplo, mira este código para el trailing stop. Es fácil ver lo que hace cada línea y por lo tanto es fácil detectar errores.
   int total=OrdersTotal();
   
   for(int cnt=0; cnt<total; cnt++)
   {if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
    {if(OrderType()==OP_BUY)
     {if(TrailingStop>0)
      {if(Bid-OrderOpenPrice()>Point*TrailingStop)
       {if(OrderStopLoss()<Bid-Point*TrailingStop)
        {if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
         {Print("OrderModify error ",GetLastError());
          return;
   }}}}}}}
  1. Debes contar hacia abajo al cerrar/borrar en presencia de múltiples órdenes. Piense en el EA en otros gráficos. Adquiera el hábito.
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       {if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
        {if(OrderType()==OP_BUY)
         {if(TrailingStop>0)
          {if(Bid-OrderOpenPrice()>Point*TrailingStop)
           {if(OrderStopLoss()<Bid-Point*TrailingStop)
            {if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
             {Print("OrderModify error ",GetLastError());
              return;
       }}}}}}}
    También prefiera ++x sobre x++ (especialmente cuando se trata de clases)
  2. El lenguaje es una sentencia for(), una sentencia if(), por lo que no tiene mucho sentido poner llaves alrededor de una sola sentencia.
    No se escribiría
    sino
    { i = 1 + 2; }
    { if(i == 3) { Print(i); } }
    i = 1 + 2;
    if(i == 3) Print(i);
    Así que simplifique
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       if(OrderType()==OP_BUY)
       if(TrailingStop>0)
       if(Bid-OrderOpenPrice()>Point*TrailingStop)
       if(OrderStopLoss()<Bid-Point*TrailingStop)
       if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
  3. Ahora que "&&" (y "||") son operadores de circuito corto no encadene ifs
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY)
       && TrailingStop>0)
       && Bid-OrderOpenPrice()>Point*TrailingStop)
       && OrderStopLoss()<Bid-Point*TrailingStop)
       && !OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
  4. ¿Quiere modificar el orden cuando el order select ha fallado?
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(O rderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY)
       && TrailingStop>0)
       && Bid-OrderOpenPrice()>Point*TrailingStop)
       && OrderStopLoss()<Bid-Point*TrailingStop)
       && !OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
  5. Elimine todas las pruebas que no cambien fuera del bucle.
    if TrailingStop>0){
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY)
       && Bid-OrderOpenPrice()>Point*TrailingStop)
       && OrderStopLoss()<Bid-Point*TrailingStop)
       && !OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
    }
  6. No siga calculando lo mismo.
       if(Bid-OrderOpenPrice()>Point*TrailingStop)
       if(OrderStopLoss()<Bid-Point*TrailingStop)
       if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,O...
    Averigüe qué quiere hacer y si debe hacerlo
    if TrailingStop>0){
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY){
          double SL = Bid - Point*TrailingStop;
          if(SL > OrderOpenPrice()    // Start trailing above open price
          && SL > OrderStopLoss()     // And it moves up ONLY
          && !OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Green))
          {  Print("OrderModify error ",GetLastError());
             return;
          }
       }
    }
  7. ¿Qué pasa con los otros casos? ¿Qué pasa con otros gráficos y EAs?
    if TrailingStop>0){
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)
       && OrderMagicNumber() == MyExternal
       && OrderSymbol()      == Symbol()  
       ){  
          if(OrderType()==OP_BUY)
          {
             double SL = Bid - Point*TrailingStop;
             if(SL > OrderOpenPrice()    // Start trailing above open price
             && SL > OrderStopLoss()     // And it moves up ONLY
             && !OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Green))
             {  Print("OrderModify error ",GetLastError());
                return;
             }
          }  // OP_BUY
          else // OP_SELL (or pending)
          { ...                       
          }                           
       }  // OrderSelect
    }  // Trailing

 
WHRoeder:
  1. Usted DEBE contar hacia abajo al cerrar/borrar en presencia de múltiples órdenes. Piensa en el EA en otros gráficos. Acostúmbrese. También prefiera ++x en lugar de x++ (especialmente cuando se trata de clases)
  2. El lenguaje es declaración for(), declaración if(), por lo que tiene poco sentido poner llaves alrededor de una sola declaración.
    No escribas
    sino
    Así que simplifica
  3. Ahora que "&&" (y "||") son operadores de cortocircuito no encadene ifs
  4. ¿Quiere modificar el orden cuando el order select ha fallado?
  5. Elimine todas las pruebas que no cambien fuera del bucle.
  6. No siga calculando lo mismo. Averigua qué quieres hacer y si debes
  7. ¿Qué pasa con los otros casos? ¿Qué pasa con otros gráficos y EAs?

Publiqué ese código sólo como un ejemplo de código fácil de leer, no pretendía ser un ejemplo de una función independiente completa.

Es la sección de órdenes de compra del código de trailing stop del EA de ejemplo de MetaQuotes MACD incluido en MT4.

1) No es cierto, se puede contar hacia arriba o hacia abajo, el bucle es más eficiente, OrdersTotal() se llama una vez y se asigna a una var local.

 
SDC: He publicado ese código sólo como un ejemplo o
He publicado sólo una ampliación del tema.
 

Gracias COSUDE . Gracias por los consejos también WHRoeder . Es útil .

Intenté cambiar OrderClosePrice() por MarketInfo en el código anterior y el editado (quitando la condición && y poniéndolos como una sentencia if como después, la del segundo bucle for), pero el resultado sigue siendo que a veces funciona y a veces no.

El bucle for para contar el total de pedidos en el pool lo uso como bucle de cuenta atrás pero con x-- . No entiendo por qué sugieres --x .

He buscado en google "operadores de cortocircuito" pero no entiendo muy bien lo que significa en mql4, ¿te importaría explicarlo un poco ^_^ ? ¿Por qué es malo encadenar 'if'?

Por cierto , el código anterior que SDC sugirió , ese no es el código que estoy usando >.< .

 

No está mal encadenar ifs. Los desarrolladores del lenguaje MQL4 escribieron el código que publiqué arriba. Es un código que corté de su ejemplo de EA macd como un ejemplo.

WHR se refería a un cambio reciente en la forma de evaluar las condiciones && || que ahora las hace tan eficientes como las condiciones if encadenadas. Antes eran menos eficientes. Se puede utilizar cualquiera de los dos métodos. Los if encadenados son útiles cuando hay divergencias en el código para poder usar 'else'.

Las líneas largas de condiciones if( && || ) pueden crear una confusión de paréntesis que hace más difícil encontrar errores, por eso no me gusta hacerlo. También hay un estándar aceptado para la codificación que dice que no debe tener más de 80 caracteres. Muchos codificadores no se molestan en adherirse a esa norma, sin embargo, y los desarrolladores de MQL4 siguen creando identificadores enumerados con grandes nombres largos para ser utilizados en sus llamadas a funciones con nombres igualmente largos, lo que no ayuda con el formato del código mucho.

Razón de la queja: