MQL4 ve MQL5 ile ilgili herhangi bir acemi sorusu, algoritmalar ve kodlar hakkında yardım ve tartışma - sayfa 755

 

Merhaba. Neyin yanlış olduğunu anlayamıyorum.

Daha küçük ve daha büyük hacimli ve farklı kazanç sağlayan iki sipariş vardır. Önce daha küçük hacimli bir sipariş, ardından daha büyük bir sipariş açılır. Büyük hacimli bir kar al emri bulmanız gerekiyor.

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

Her şey doğru gibi görünüyor, ancak sonuç olarak, nedense, daha küçük hacimli kar al değerleri görüntüleniyor (önce açılıyor). Sorun nedir?

PS toplamı = Sipariş Toplamı()

 
Youri Lazurenko :

Merhaba. Neyin yanlış olduğunu anlayamıyorum.

Daha küçük ve daha büyük hacimli ve farklı kazanç sağlayan iki sipariş vardır. Önce daha küçük hacimli bir sipariş, ardından daha büyük bir sipariş açılır. Büyük hacimli bir kar al emri bulmanız gerekiyor.

Her şey doğru gibi görünüyor, ancak sonuç olarak, nedense, daha küçük hacimli kar al değerleri görüntüleniyor (önce açılıyor). Sorun nedir?

PS toplamı = Sipariş Toplamı()

Görünüşe göre, MaxLotBuy() işlevi kendi sipariş numaralandırmasından geçer ve bu işleve geri dönerken başka bir sipariş seçilir. Bir tür sipariş yineleme döngüsünün dışında siparişleri yinelemekten kaçının. Ne dediğini anlamadı. Öyle ama.

Bu durum için, yeni değerin öncekinden daha büyük olması koşuluyla, döngüden önce bir değişken bildirmek ve ona OrderLots() değerini atamak daha iyidir.

 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 :

Görünüşe göre, MaxLotBuy() işlevi kendi sipariş numaralandırmasından geçer ve bu işleve geri dönerken başka bir sipariş seçilir. Bir tür sipariş yineleme döngüsünün dışında siparişleri yinelemekten kaçının. Ne dediğini anlamadı. Öyle ama.

Bu durum için, yeni değerin öncekinden daha büyük olması koşuluyla, döngüden önce bir değişken bildirmek ve ona OrderLots() değerini atamak daha iyidir.

Teşekkür ederim. Evet, MaxLotBuy() kendi sipariş numaralandırmasına sahiptir, ancak döndürülen değer maksimum değerdir (kodu versem iyi olur)

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

Ama fikrini aldım, teşekkürler. Şimdi deneyeceğim.

 
Konstantin Nikitin :
Muhtemelen daha iyi olurdu

Teşekkürler, bu daha iyi gibi.

 
Konstantin Nikitin :
Muhtemelen daha iyi olurdu

Teşekkür ederim. Sadece kendinize yazarken değil, daha dikkatli olmanız gerekir.

Tam olarak böyle söylenmesine rağmen.

döngüden önce bir değişken bildir


 

Arkadaşlar, çok teşekkür ederim; olması gerektiği gibi çalışır. Sadece orijinal konumuna bir sıfırlama eklendi.

   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 :

Arkadaşlar, çok teşekkür ederim; olması gerektiği gibi çalışır. Sadece orijinal konumuna bir sıfırlama eklendi.

İyi evet. Örneğim tamamlanmadı. Az önce düzelttim, ekledim ve düzeltmem zamanında mesajınızla çakıştı.
 
Alexey Viktorov :
İyi evet. Örneğim tamamlanmadı. Az önce düzelttim, ekledim ve düzeltmem zamanında mesajınızla çakıştı.

Tamamlanmaması önemli değil, asıl şey doğru fikir, yaklaşım. Hepinize tekrar teşekkürler.

 
Youri Lazurenko :

Tamamlanmaması önemli değil, asıl şey doğru fikir, yaklaşım. Hepinize tekrar teşekkürler.

Sonra bu yüzden

   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 :

Sonra bu yüzden

Prensip olarak, kodun tamamını göndermedim, ancak yalnızca en büyük lotlu siparişin kârını almanın bir kısmını gönderdim. Tam öz aşağıdaki gibidir - fiyat tersine döndüğünde, büyük lotlu bekleyen bir emir verilir. Çalışırsa, karşı siparişe bir zararı durdur emri yerleştirilir, böylece büyük bir kâr al emri kapatıldığında, zararı durdur ile negatif kârlı emir de kapatılır. Tam kod, durdurma kaybı ayarındaki değişiklikler şöyle görünür:

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

PS Test süreci sırasında, danışmana bu veya bu durumda nasıl davranacağını "açıklanması" gereken pek çok nüans ortaya çıkıyor.