Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 755

 

Olá. Eu não consigo entender o que está errado.

Existem dois pedidos com volumes menores e maiores e diferentes tipos de lucro. O pedido com o volume menor é aberto primeiro, depois o pedido com o volume maior. Precisamos encontrar um Take Profit para o pedido com maior 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();
         }
      }
   }
} 

Tudo parece estar correto, mas por alguma razão, obtemos valores de lucro do pedido com um volume menor (ele foi aberto primeiro). O que está errado?

P.S. total = EncomendasTotal()

 
Youri Lazurenko:

Olá. Eu não consigo entender o que está errado.

Existem dois pedidos com volumes menores e maiores e diferentes tipos de lucro. O pedido com o volume menor é aberto primeiro, depois o pedido com o volume maior. Precisamos encontrar um Take Profit para o pedido com maior volume.

Tudo parece estar correto, mas por alguma razão, obtemos valores de lucro do pedido com um volume menor (ele foi aberto primeiro). O que está errado?

P.S. Total = EncomendasTotal()

Parece que a função MaxLotBuy() contém sua própria busca de ordem e outra ordem parece ser selecionada após retornar a esta função. Evite a recuperação de pedidos fora de algum ciclo de recuperação de pedidos. Eu não entendo o que eu disse. Mas é verdade.

Nesta situação, é melhor declarar uma variável antes do loop e atribuir a ela o valor OrderLots() desde que o novo valor seja maior do que o anterior.

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:

A função MaxLotBuy() parece ter seu próprio loop de ordem e outra ordem é selecionada ao retornar a esta função. Você deve evitar passar pela ordem fora de qualquer ciclo de pedidos. Eu não entendo o que eu disse. Mas é verdade.

Nesta situação, é melhor declarar uma variável antes do loop e atribuir-lhe o valor OrderLots() desde que o novo valor seja maior do que o anterior.

Obrigado. Sim,MaxLotBuy() tem sua própria enumeração de pedidos, mas o valor de retorno é o máximo (eu lhe darei o código).

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

Mas eu entendi sua idéia, obrigado. Vou tentar agora.

 
Konstantin Nikitin:
Esse é provavelmente o caminho certo a ser seguido.

Obrigado, isso parece melhor.

 
Konstantin Nikitin:
Eu acho que a coisa certa a fazer seria

Obrigado. Não é apenas quando você escreve para si mesmo que você tem que ter cuidado.

Embora isso seja exatamente o que diz em palavras.

declarar uma variável antes do laço


 

Pessoal, muito obrigado; funciona como deve ser. Acabamos de acrescentar também um reset à posição original.

   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:

Pessoal, muito obrigado; funciona como deve ser. Acabamos de acrescentar também um reset à posição original.

Bem, sim. Meu exemplo não está completo. Acabei de corrigi-la, complementei-a e minha correção coincidiu com sua mensagem no tempo.
 
Alexey Viktorov:
Bem, sim. Meu exemplo não está completo. Acabei de corrigi-la, complementei-a e minha correção coincidiu com sua mensagem no tempo.

Não importa que não esteja completo, o que importa é a idéia correta, a abordagem correta. Mais uma vez obrigado a todos vocês.

 
Youri Lazurenko:

Não importa que não esteja completo, o que importa é a idéia correta, a abordagem correta. Mais uma vez, obrigado a todos vocês.

Então é assim

   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:

Então parece assim

Basicamente eu não afixei todo o código, mas apenas uma parte de encontrar o lucro do take do pedido com o lote mais alto. A questão é a seguinte - quando o preço se inverte, uma ordem pendente com um lote maior é colocada. Se funcionar, um stop loss é colocado na ordem oposta para que quando a ordem com grande lote for fechada no Take Profit, a ordem com lucro negativo no stop loss também seja fechada. O código completo de modificação com a definição de um stop loss se parece com isto

// 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 os testes, há tantas nuances que precisam ser "explicadas" ao Consultor Especialista quanto a como ele deve se comportar em certos casos.

Razão: