Ho bisogno di aiuto per individuare qualche piccolo errore. - pagina 2

 
A qualcuno dispiace dare una mano per favore .....
 

Parte del problema è il modo in cui hai scritto quel codice con grandi e lunghe condizioni if piene di &&, ||, e una chiamata di funzione dopo l'altra rende difficile il debug, saresti fortunato a trovare qualcuno che abbia il tempo di sbrogliare quel casino. Dovresti guardare gli esempi di codifica nella documentazione per vedere come il codice dovrebbe essere formattato in linee molto più corte e commentate.

 

" Rende difficile il debug"? :( Mai sentito parlare di questi però, è vero ....

Il compilatore ha anche difficoltà a eseguire il debug del mio codice :(?

Se questa è la ragione significa che ho dovuto ripensare tutta la mia idea di codifica per questa parte ?? Allora verrà fuori una cosa totalmente diversa ...... :( :(

 

Sì, è difficile fare il debug, per esempio guarda questo codice per il trailing stop. È facile vedere cosa fa ogni linea, quindi è facile individuare gli errori.

   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;
   }}}}}}}
 
Ho provato a rimuovere la condizione && e a metterla come dichiarazione if dopo .... Ma ancora non ha funzionato sempre, a volte ha solo spostato lo stop loss una volta, a volte ha funzionato bene sia per gli ordini di acquisto che di vendita.
 
SDC: Sì, è difficile fare il debug, per esempio guarda questo codice per il trailing stop. È facile vedere cosa fa ogni linea, quindi è facile individuare gli errori.
   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. Si DEVE fare il conto alla rovescia quando si chiude/cancella in presenza di ordini multipli. Pensa all'EA su altri grafici. Prendi l'abitudine.
       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;
       }}}}}}}
    Preferisci anche ++x a x++ (soprattutto quando si tratta di classi)
  2. Il linguaggio è for() statement, if() statement, quindi ha poco senso mettere delle parentesi attorno ad un singolo statement.
    Non scrivereste
    ma
    { i = 1 + 2; }
    { if(i == 3) { Print(i); } }
    i = 1 + 2;
    if(i == 3) Print(i);
    Quindi semplificare
       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. Ora che "&&" (e "||") sono operatori di cortocircuito non concatenare gli if
       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. Vuoi modificare l'ordine quando l'order select è fallito?
       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. Rimuovi tutti i test che non cambiano fuori dal ciclo.
    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. Non continuare a calcolare la stessa cosa.
       if(Bid-OrderOpenPrice()>Point*TrailingStop)
       if(OrderStopLoss()<Bid-Point*TrailingStop)
       if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,O...
    Cerca di capire cosa vuoi fare e se dovresti
    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. E gli altri casi? E gli altri grafici e gli EA?
    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. Si DEVE fare il conto alla rovescia quando si chiude/cancella in presenza di ordini multipli. Pensate all'EA su altri grafici. Preferite anche ++x a x++ (soprattutto quando si tratta di classi).
  2. Il linguaggio è for() statement, if() statement, quindi ha poco senso mettere le parentesi graffe attorno ad un singolo statement.
    Non scrivereste
    ma
    Quindi semplificare
  3. Ora che "&&" (e "||") sono operatori di corto circuito non concatenare gli if
  4. Volete modificare l'ordine quando l'order select è fallito?
  5. Rimuovete tutti i test che non cambiano fuori dal ciclo.
  6. Non continuare a calcolare la stessa cosa. Cerca di capire cosa vuoi fare e se dovresti
  7. E gli altri casi? E gli altri grafici e gli EA?

Ho postato quel codice solo come esempio di codice facile da leggere, non voleva essere un esempio di una funzione stand alone completa.

E' la sezione degli ordini di acquisto del codice di trailing stop dell'esempio di MetaQuotes MACD EA incluso in MT4.

1) Non è vero, si può contare su o giù, il ciclo è più efficiente, OrdersTotal() viene chiamato una volta e assegnato a una var locale.

 
SDC: Ho postato quel codice solo come esempio o
Ho postato solo un ingrandimento del soggetto.
 

Grazie DSC. Grazie per i suggerimenti anche WHRoeder. E' utile.

Ho provato a scambiare OrderClosePrice() con quello di MarketInfo nel codice precedente e l'ho modificato (rimuovendo la condizione && e mettendoli in una dichiarazione if come dopo, quella nel 2° ciclo for), ma il risultato è ancora a volte funzionante a volte non funzionante.

Il ciclo for per il conteggio degli ordini totali nel pool uso il ciclo count down ma con x-- . Non capisco perché suggerisci --x però.

Ho cercato su Google "operatori di cortocircuito" ma non ho capito bene cosa significa in mql4, ti dispiace spiegarmi un po' ^_^? Perché è male concatenare 'if'?

A proposito, il codice di cui sopra che SDC ha suggerito, non è il codice che sto usando >.< .

 

Non è male concatenare gli if. Gli sviluppatori del linguaggio MQL4 hanno scritto il codice che ho postato sopra. È un po' di codice che ho tagliato dal loro EA campione macd come esempio.

WHR si riferiva a un recente cambiamento nel modo in cui vengono valutate le condizioni && || che ora le rende altrettanto efficienti delle condizioni if concatenate. In precedenza erano meno efficienti. Potete usare entrambi i metodi. Gli if concatenati sono utili quando ci sono divergenze nel codice in modo da poter usare 'else'.

Lunghe linee di condizioni if( && || ) possono creare confusione di parentesi che rende più difficile trovare gli errori, ecco perché non mi piace farlo. Inoltre c'è uno standard accettato per la codifica che dice che non dovrebbe essere più di 80 caratteri. Molti codificatori non si preoccupano però di aderire a questo standard, e gli sviluppatori di MQL4 continuano a creare identificatori enumerati con grandi nomi lunghi da usare nelle loro chiamate a funzioni con nomi altrettanto grandi, il che non aiuta molto la formattazione del codice.

Motivazione: