Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 755

 

Bonjour. Je n'arrive pas à comprendre ce qui ne va pas.

Il y a deux ordres avec un volume plus petit et plus grand et un take profit différent. L'ordre avec le plus petit volume est ouvert en premier, puis l'ordre avec le plus grand volume. Nous devons trouver un Take Profit pour l'ordre avec un plus grand volume.

//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();
         }
      }
   }
} 

Tout semble correct, mais pour une raison quelconque, nous obtenons les valeurs de prise de bénéfices de l'ordre avec un volume plus faible (il a été ouvert en premier). Qu'est-ce qui ne va pas ?

P.S. total = OrdersTotal()

 
Youri Lazurenko:

Bonjour. Je n'arrive pas à comprendre ce qui ne va pas.

Il y a deux ordres avec un volume plus petit et plus grand et un take profit différent. L'ordre avec le plus petit volume est ouvert en premier, puis l'ordre avec le plus grand volume. Nous devons trouver un Take Profit pour l'ordre avec un plus grand volume.

Tout semble correct, mais pour une raison quelconque, nous obtenons les valeurs de prise de bénéfices de l'ordre avec un volume plus faible (il a été ouvert en premier). Qu'est-ce qui ne va pas ?

P.S. Total = OrdersTotal()

Il semble que la fonction MaxLotBuy() contienne sa propre recherche d'ordre et qu'un autre ordre soit sélectionné lorsque nous revenons à cette fonction. Évitez le rebond des ordres en dehors de certains cycles de rebond des ordres. Je ne comprends pas ce que j'ai dit. Mais c'est vrai.

Dans cette situation, il vaut mieux déclarer une variable avant la boucle et lui attribuer la valeur OrderLots() à condition que la nouvelle valeur soit plus grande que la précédente.

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 fonction MaxLotBuy() semble avoir sa propre boucle de commande et une autre commande est sélectionnée lors du retour à cette fonction. Vous devez éviter de passer par la commande en dehors de toute boucle de commande. Je ne comprends pas ce que j'ai dit. Mais c'est vrai.

Dans cette situation, il vaut mieux déclarer une variable avant la boucle et lui attribuer la valeur OrderLots() à condition que la nouvelle valeur soit plus grande que la précédente.

Merci. Oui,MaxLotBuy() a sa propre énumération d'ordres, mais la valeur de retour est la valeur maximale (je vais vous donner le code).

//  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);
}

Mais j'ai compris votre idée, merci. Je vais l'essayer maintenant.

 
Konstantin Nikitin:
C'est probablement la bonne façon de faire.

Merci, cela semble mieux.

 
Konstantin Nikitin:
Je pense que la bonne chose à faire serait

Merci. Ce n'est pas seulement lorsque vous vous écrivez à vous-même que vous devez faire attention.

Bien que ce soit exactement ce que disent les mots.

déclarer une variable avant la boucle


 

Les gars, merci beaucoup, ça marche comme il faut. J'ai également ajouté une réinitialisation à la position 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:

Les gars, merci beaucoup, ça marche comme il faut. J'ai également ajouté une réinitialisation à la position originale.

Eh bien, oui. Mon exemple n'est pas complet. Je l'ai juste corrigé, complété et ma correction a coïncidé avec votre message dans le temps.
 
Alexey Viktorov:
Eh bien, oui. Mon exemple n'est pas complet. Je l'ai juste corrigé, complété et ma correction a coïncidé avec votre message dans le temps.

Peu importe qu'il ne soit pas complet, ce qui compte c'est la bonne idée, la bonne approche. Merci encore à tous.

 
Youri Lazurenko:

Peu importe qu'il ne soit pas complet, ce qui compte c'est la bonne idée, la bonne approche. Je vous remercie tous une fois de plus.

Ensuite, c'est comme ça

   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:

Ensuite, cela ressemble à ceci

En fait, je n'ai pas posté tout le code, mais seulement une partie permettant de trouver le take profit de l'ordre avec le lot le plus élevé. Le principe est le suivant : lorsque le prix s'inverse, un ordre en attente avec un lot plus important est placé. Si cela fonctionne, un stop loss est fixé sur l'ordre opposé de sorte que lorsque l'ordre avec un gros lot est fermé au niveau du Take Profit, l'ordre avec un profit négatif au niveau du stop loss est également fermé. Le code complet de modification avec fixation d'un stop loss ressemble à ceci

// 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. Pendant les tests, il y a tellement de nuances qui doivent être "expliquées" au conseiller expert pour savoir comment il doit se comporter dans certains cas.

Raison: