Mql4 dilinin özellikleri, incelikleri ve çalışma yöntemleri - sayfa 34

 
Böyle tatsız bir sorun fark edildi, eğer betik çalışıyorsa ve çöküyorsa (platformu kapatır), o zaman günlük dosyası betiğin çalışması sırasında kayıtları kaydetmez ve bu, koddaki bir hatayı tanımlamayı oldukça zorlaştırır. Ondan önce, bir şekilde böyle bir sorun fark etmedim. Bu her zaman olmuştur (kayıtları kaydetmez) ?
 

Görünüşe göre MT4'te hesaptaki alım satım kaldıracındaki bir değişikliği (yeniden bağlanmadan) öğrenmenin bir yolu yok.

 
fxsaber # :

Görünüşe göre MT4'te hesaptaki alım satım kaldıracındaki bir değişikliği (yeniden bağlanmadan) öğrenmenin bir yolu yok.

Beş yıl önce yaptı. Müşterinin kaldıracı belirli saatlerde düşürüldü ve AccountInfoInteger(ACCOUNT_LEVERAGE) değişkeninde değişmedi. Ve bunu bilmesi gerekiyordu.

Ne kadar bilimsel olarak bilmiyorum, ama kendi kendime, nadiren değişen, ancak günde birkaç kez değiştirilebilen bir sembolle bir kaldıraç olduğuna karar verdim.
Kontrolü şu şekilde yaptım:

 //+------------------------------------------------------------------------------------------------------------------+
//| Проверяет изменение плеча и сообщает если это было
//+------------------------------------------------------------------------------------------------------------------+
void leverageCheck()
{
   if (MarketInfo( Symbol (), MODE_MARGINREQUIRED) == 0 ) return ;

   // --- получаем текущее плечо из маржинальных требований, стоимости пункта, тек.котировки
   double leverageSymb = MarketInfo( Symbol (),MODE_TICKVALUE) * Bid / MarketInfo( Symbol (),MODE_MARGINREQUIRED) / Point ;
  leverageSymb = int ( MathRound (leverageSymb));
  
   // --- если плечо по символу стало меньше на 10% плеча по счету отметим это
   if (leverageSymb < percVar( AccountInfoInteger ( ACCOUNT_LEVERAGE ), - 10 ))
  {
     string txt = TimeToString ( TimeCurrent ()) + " Leverage is reduced 1:" + ( string )leverageSymb;
     Print (txt, " but account leverage = " + ( string ) AccountInfoInteger ( ACCOUNT_LEVERAGE ));

     // --- вывод информации на график
  }
}

//+-------------------------------------------------------------------------------------------------------------------+
//| Получает переменную, увеличивает или уменьшает его на переданный процент и возвращает новое значение
//| Чтобы уменьшить, нужно передать percent с минусом
//+-------------------------------------------------------------------------------------------------------------------+
double percVar( double var, double percent)
{
   return var*( 1 + percent/ 100 );
}


Bazen kaldıraçSymb sembolü için mevcut hesaplanan kaldıraç 200 yerine 199, 198 verebilir (kaldıraç 1:200 olduğunda) Bu nedenle standart kaldıraçtan belirli bir yüzde çıkarılıp bu değerle karşılaştırılması gerekiyordu. Yukarıdaki çözüm daha sonra yardımcı oldu, kullanışlı olabilir.

 
Vasiliy Pushkaryov # :

Beş yıl önce yaptı. Müşterinin kaldıracı belirli saatlerde düşürüldü ve AccountInfoInteger(ACCOUNT_LEVERAGE) değişkeninde değişmedi. Ve bunu bilmesi gerekiyordu.

Ne kadar bilimsel olarak bilmiyorum ama hesapta nadiren değişen bir kaldıraç olduğuna kendim karar verdim, ancak günde birkaç kez değiştirilebilen bir kaldıraç var.
Kontrolü şu şekilde yaptım:


Bazen kaldıraçSymb sembolü için mevcut hesaplanan kaldıraç 200 yerine 199, 198 verebilir (kaldıraç 1:200 olduğunda) Bu nedenle standart kaldıraçtan belirli bir yüzde çıkarılıp bu değerle karşılaştırılması gerekiyordu. Yukarıdaki çözüm daha sonra yardımcı oldu, kullanışlı olabilir.

Evet, takip sembolü marj gereksinimleri sorun değil. ACCOUNT_LEVERAGE - yalnızca yeniden bağlanın.

 

Bilet listesinde gerekli emirleri saklayarak işlem geçmişini filtrelemek çok yaygın bir uygulamadır. Ve sonra bu liste üzerinde SELECT_BY_TICKET.

Bir bileti değil, bir pozisyonu hatırlama seçeneğini hiç görmedim. Aşağıda bir performans karşılaştırması var.

 #include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006
#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

int Filter( TICKET_TYPE &Tickets[], int &Pos[] )
{
   const int Total = OrdersHistoryTotal();            

   ArrayResize (Tickets, Total);
   ArrayResize (Pos, Total);
  
   int Amount = 0 ;

   for ( int i = 0 ; i < Total; i++)
     if ( OrderSelect (i, SELECT_BY_POS, MODE_HISTORY) && (OrderProfit() > 0 ))
    {
      Tickets[Amount] = OrderTicket();
      Pos[Amount] = i;
      
      Amount++;
    }
    
   ArrayResize (Tickets, Amount);
   ArrayResize (Pos, Amount);
  
   return (Amount);
}

template < typename T>
double Func1( int TypeSelect, const T &Array[] )
{
   double Res = 0 ;
   const int Total = ArraySize (Array);
  
   for ( int i = 0 ; i < Total; i++)
     if ( OrderSelect (Array[i], TypeSelect, MODE_HISTORY))
      Res += OrderProfit();
      
   return (Res);
}

void OnStart ()
{   
  TICKET_TYPE Tickets[];
   int Pos[];

   Print (Filter(Tickets, Pos));
  
   const double Res1 = _B(Func1(SELECT_BY_TICKET, Tickets), 1 ); // Так делают почти все.
   const double Res2 = _B(Func1(SELECT_BY_POS, Pos), 1 );         // Не встречал.
  
   Print (Res1);
   Print (Res2);
}


 2021.10 . 11 01 : 37 : 08.254 Test19 EURUSD.rann,M1: 561002.61
2021.10 . 11 01 : 37 : 08.254 Test19 EURUSD.rann,M1: 561002.61
2021.10 . 11 01 : 37 : 08.254 Test19 EURUSD.rann,M1: Alert : Bench_Stack = 0 , 1 <= Time[Test19.mq4 49 in OnStart : Func1(SELECT_BY_POS,Pos)] = 2827 mcs.
2021.10 . 11 01 : 37 : 08.251 Test19 EURUSD.rann,M1: Alert : Bench_Stack = 0 , 1 <= Time[Test19.mq4 48 in OnStart : Func1(SELECT_BY_TICKET,Tickets)] = 7460 mcs.
2021.10 . 11 01 : 37 : 08.244 Test19 EURUSD.rann,M1: 35936

Biletli seçeneğin performansta neredeyse üç kat kaybettiği görülebilir.

 
fxsaber # :

Biletli seçeneğin performansta neredeyse üç kat kaybettiği görülebilir.

bir pozisyon kapatılırsa/açılırsa, biletle mantık bozulmaz, pozisyonla mantık bozulabilir.

 
TheXpert # :

bir pozisyon kapatılırsa/açılırsa, biletle mantık bozulmaz, pozisyonla mantık bozulabilir.

Bu sadece MODE_HISTORY modu ile ilgilidir.

 

Bu kodun , işlev çağrısından ÖNCE ve SONRA var olan bir sırayı atlamasının teorik bir olasılığı var mı? Veya iki kez sayın.

 double GetLots()
{
   double Lots = 0 ;
  
   for ( int i = OrdersTotal () - 1 ; i >= 0 ; i--)
     if ( OrderSelect (i, SELECT_BY_POS))
      Lots += OrderLots();
      
   return (Lots);
}

Onlar. Numaralandırma sırasında bir sipariş kaldırıldığında veya göründüğünde indekslemeye ne olur?

 
fxsaber # :

Veya iki kez sayın.

genellikle sıralamaya bağlıdır. varsayılan olarak zamana veya bilete göre sıralamayı kabul edersek, listenin sonunda yeni siparişler görünür ve en eskileri silindiğinde her şeyin değişmesi mantıklıdır.

Bir sipariş listenin başından kaldırıldığında, listeden birinin iki kez dikkate alınabileceği ortaya çıktı. yapmak kolay görünüyor - sadece önceki geçişten bileti hatırlayın ve karşılaştırın (ancak yine de bir garanti vermiyor)

Geri dönüş yolunda nasıl geçilir - gelmedi

 
Andrei Trukhanovich # :

genellikle sıralamaya bağlıdır. varsayılan olarak zamana veya bilete göre sıralamayı kabul edersek, listenin sonunda yeni siparişler görünür, en eskileri silindiğinde her şeyin değişmesi mantıklıdır.

Bir sipariş listenin başından kaldırıldığında, listeden birinin iki kez dikkate alınabileceği ortaya çıktı. yapmak kolay görünüyor - sadece önceki geçişten bileti hatırlayın ve karşılaştırın (ancak yine de bir garanti vermiyor)

Geri dönüş yolunda nasıl geçilir - gelmedi

Detaylı cevap için teşekkürler! Şimdi TÜM siparişleri BİR defada nasıl sıralayacağımı düşünüyorum.

Neden: