Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 755

 

Salve. Non riesco a capire cosa c'è di sbagliato.

Ci sono due ordini con volume più piccolo e più grande e diversi take profit. L'ordine con il volume minore viene aperto per primo, poi l'ordine con il volume maggiore. Dobbiamo trovare un Take Profit per l'ordine con volume maggiore.

//MaxLotBuy() - функция находит ордер с наибольшим объемом (в Comment("") показывает правильные значения)
//buyTpL - в глобальных переменных
//---------------------------------------------
for(i = total-1; i >= 0; i--)
{
   if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
   {
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
      { 
         if(OrderType() == OP_BUY)
         { 
            if(OrderLots() == MaxLotBuy())
               buyTpL = OrderTakeProfit();
         }
      }
   }
} 

Tutto sembra essere corretto, ma per qualche motivo, otteniamo valori di take profit dell'ordine con un volume minore (è stato aperto per primo). Cosa c'è che non va?

P.S. totale = OrdiniTotali()

 
Youri Lazurenko:

Salve. Non riesco a capire cosa c'è di sbagliato.

Ci sono due ordini con volume più piccolo e più grande e diversi take profit. L'ordine con il volume minore viene aperto per primo, poi l'ordine con il volume maggiore. Dobbiamo trovare un Take Profit per l'ordine con volume maggiore.

Tutto sembra essere corretto, ma per qualche motivo, otteniamo valori di take profit dell'ordine con un volume minore (è stato aperto per primo). Cosa c'è che non va?

P.S. Totale = OrdiniTotali()

Sembra che la funzione MaxLotBuy() contenga una propria ricerca dell'ordine e un altro ordine sembra essere selezionato quando si ritorna a questa funzione. Evitare il rimbalzo degli ordini al di fuori di qualche ciclo di rimbalzo degli ordini. Non capisco cosa ho detto. Ma è vero.

In questa situazione, è meglio dichiarare una variabile prima del ciclo e assegnarle il valore di OrderLots() a condizione che il nuovo valore sia più grande del precedente.

double orderLot = 0;
for(i = total-1; i >= 0; i--)
{
  if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
   {
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
      { 
         if(OrderType() == OP_BUY)
         { 
            if(OrderLots() > orderLot)
             {
              orderLot = OrderLots();
              buyTpL = OrderTakeProfit();
             }
         }
      }
   }
} 
 
Alexey Viktorov:

La funzione MaxLotBuy() sembra avere un proprio ciclo di ordini e un altro ordine viene selezionato quando si ritorna a questa funzione. Si dovrebbe evitare di passare l'ordine al di fuori di qualsiasi ciclo dell'ordine. Non capisco cosa ho detto. Ma è vero.

In questa situazione, è meglio dichiarare una variabile prima del ciclo e assegnarle il valore di OrderLots() a condizione che il nuovo valore sia più grande del precedente.

Grazie. Sì,MaxLotBuy() ha la sua enumerazione di ordini, ma il valore di ritorno è quello massimo (ti do il codice).

//  GetLots() - функция мани менеджмента
//------------------------
double MaxLotBuy()
{
   int    i;
   int    total  = OrdersTotal();
   double lot    = GetLots();
   
   if(CountBuy() == 0)
      lot = GetLots();
   
   if(CountBuy() >= 1)
   {   
      for(i = total-1; i >= 0; i--)
      {
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         {
            if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
            {
               if(OrderType() == OP_BUY) 
               {
                  if(lot < OrderLots())
                     lot = OrderLots();
               }
            }
         }
      }
   }
   return(lot);
}

Ma ho capito la tua idea, grazie. Lo proverò ora.

 
Konstantin Nikitin:
Questo è probabilmente il modo giusto di procedere.

Grazie, sembra meglio.

 
Konstantin Nikitin:
Penso che la cosa giusta da fare sarebbe

Grazie. Non è solo quando si scrive a se stessi che bisogna fare attenzione.

Anche se è esattamente quello che dice a parole.

dichiarare una variabile prima del ciclo


 

Ragazzi, grazie mille; funziona come dovrebbe. Ho appena aggiunto anche un reset alla posizione originale.

   int    i;     
   int    total       = OrdersTotal();
   double orderLotBuy = GetLots();

   if(CountBuy() == 0)
      orderLotBuy = GetLots();

   for(i = total-1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
         { 
            if(OrderType() == OP_BUY)
            { 
               if(OrderLots() > orderLotBuy)
               {
                  buyTpL      = OrderTakeProfit();
                  orderLotBuy = OrderLots();
               }
            }
         }
      }
   } 
   
 
Youri Lazurenko:

Ragazzi, grazie mille; funziona come dovrebbe. Ho appena aggiunto anche un reset alla posizione originale.

Beh, sì. Il mio esempio non è completo. L'ho appena corretto, integrato e la mia correzione ha coinciso con il tuo messaggio in tempo.
 
Alexey Viktorov:
Beh, sì. Il mio esempio non è completo. L'ho appena corretto, integrato e la mia correzione ha coinciso con il tuo messaggio in tempo.

Non importa che non sia completo, ciò che conta è l'idea giusta, l'approccio giusto. Grazie ancora a tutti voi.

 
Youri Lazurenko:

Non importa che non sia completo, ciò che conta è l'idea giusta, l'approccio giusto. Grazie a tutti ancora una volta.

Poi va così

   int    total       = OrdersTotal();
   double orderLotBuy = GetLots();

   if(CountBuy() > 0)
      for(i = total-1; i >= 0; i--)
      {
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         {
            if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
            { 
               if(OrderType() == OP_BUY)
               { 
                  if(OrderLots() > orderLotBuy)
                  {
                     buyTpL      = OrderTakeProfit();
                     orderLotBuy = OrderLots();
                  }
               }
            }
         }
      } 
 
Konstantin Nikitin:

Poi appare così

Fondamentalmente non ho postato tutto il codice, ma solo una parte per trovare il take profit dell'ordine con il lotto più alto. Il punto è il seguente: quando il prezzo si inverte, viene piazzato un ordine pendente con un lotto più grande. Se funziona, viene impostato uno stop loss sull'ordine opposto in modo che quando l'ordine con lotto grande viene chiuso al Take Profit, viene chiuso anche l'ordine con profitto negativo allo stop loss. Il codice completo di modifica con l'impostazione di uno stop loss assomiglia a questo

// sp            - величина спреда
// FirstOrderBuy - дабы избежать error1
//----------------------------------------------- 
     int i;
      
      int    total        = OrdersTotal();
      double orderLotBuy  = GetLots();     
   
      static int FirstOrderBuy  = 0;     

      if(CountBuy() < FirstOrderBuy)
         FirstOrderBuy = 0; 
         
      if(CountBuy() == 0)
         orderLotBuy = GetLots();
      
      if(CountSell() >= 1 && CountBuy() > FirstOrderBuy && MaxLotBuy() > MaxLotSell())
      {
         for(i = total-1; i >= 0; i--)
         {
            if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            {
               if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
               { 
                  if(OrderType() == OP_BUY)
                  { 
                     if(OrderLots() > orderLotBuy)
                     {
                        buyTpL      = OrderTakeProfit();
                        orderLotBuy = OrderLots();
                     }
                  }
               }
            }
         } 
                        
         for(i = total-1; i >= 0; i--)
         {
            if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            {
               if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
               { 
                  if(OrderType() == OP_SELL)  
                  {               
                     if(OrderStopLoss() == 0 || (OrderStopLoss() != 0 && OrderStopLoss() > OrderOpenPrice()))
                     {
                        slSell = NormalizeDouble(buyTpL + sp*point, Digits);
                        
                        OrderModifyX(OrderTicket(), OrderOpenPrice(), slSell, OrderTakeProfit(), 0, 0);
                     }
                  }    
               }
            }
         }
         FirstOrderBuy = CountBuy();
      }

P.S. Durante i test, ci sono tante sfumature che devono essere "spiegate" all'Expert Advisor su come dovrebbe comportarsi in certi casi.