Mql5 dilinin özellikleri, incelikleri ve çalışma yöntemleri - sayfa 209

 

Daha önce yayınlanmış bir tane daha ( bir ,   bir ticaret sunucusunun GMT ofsetini belirlemenin iki ) yolu.

 #define HOUR 3600
#define DAY ( 24 * HOUR)
#define WEEK 7

bool GetWeekSession( const string Symb, datetime &From, datetime &To )
{
   datetime Tmp;
  
  From = 0 ;
  To = 0 ;
  
   for ( int i = 0 ; i < 7 ; i++)
     if (:: SymbolInfoSessionQuote (Symb, ( ENUM_DAY_OF_WEEK )i, 0 , From, Tmp) && (From != Tmp))
    {
      From += (i + WEEK - 1 ) * DAY;
      
       break ;
    }

   for ( int i = 6 ; i >= 0 ; i--)
     if (:: SymbolInfoSessionQuote (Symb, ( ENUM_DAY_OF_WEEK )i, 0 , Tmp, To) && (To != Tmp))
    {
      To += ((i + WEEK - 1 ) % WEEK) * DAY;
      
       break ;
    }
  
   return (From != To);
}

// Аналог по серверному времени - https://www.mql5.com/ru/docs/dateandtime/timegmtoffset
// Работает для FOREX-символов.
int TimeServerGMTOffset( void )
{
   const datetime Sunday = (WEEK - 1 ) * DAY;
  
   datetime From;
   datetime To;        
  
   return (GetWeekSession( _Symbol , From, To) ? (( int ):: MathRound (( double ):: MathMin (Sunday - DAY - To, Sunday + DAY - From) / HOUR) - 3 ) * HOUR : 0 );
}

Her üç yöntemin ortak yaşamı, doğru sonucu elde etmek için çok yüksek bir olasılık verir.

 

Rollover temasının devamı. M1-geçmişinde rollover süresini belirlemeye çalışıyoruz.

 #define HOUR 3600
#define HOURS 24
#define DAY (HOURS * HOUR)
#define WEEK 7
#define MINUTE 60

ENUM_DAY_OF_WEEK TimeDayOfWeek( const datetime time )
{
   return (( ENUM_DAY_OF_WEEK )((time / DAY + THURSDAY ) % WEEK));
}

datetime GetTimeDayOfWeek( const datetime time, const ENUM_DAY_OF_WEEK Day = SUNDAY )
{
   const datetime Res = time / DAY * DAY;
  
   return (Res - (((WEEK + (TimeDayOfWeek(Res) - Day)) % WEEK)) * DAY);
}

#define GETHOUR(A) ( int )((A.time / HOUR) % HOURS)
#define GETMINUTE(A) ( int )((A.time / MINUTE) % MINUTE)

int GetTimePos( const MqlRates &Rates[], const datetime time )
{
   int Left = 0 ;
   int Right = ArraySize (Rates) - 1 ;  
      
   while (Right > Left)
  {            
     const int Middle = (Left + Right) >> 1 ;  
        
     if (Rates[Middle].time < time)
      Left = Middle + 1 ;
     else
      Right = Middle - 1 ;
  }
  
   return (Left);
}

int GetRolloverInterval( const MqlRates &Rates[], const datetime From, const datetime To, const bool MQL4Method = false )
{
   double Hours[HOURS];  
   ArrayInitialize (Hours, 0 );
        
   const int FromPos = GetTimePos(Rates, From);
   const int ToPos = GetTimePos(Rates, To);
  
   for ( int i = FromPos; i < ToPos; i++)
  {
   const int HourNow = GETHOUR(Rates[i]);
  
   #ifdef __MQL5__
     if (!MQL4Method) // Битые баровые спреды - проблема.
      Hours[HourNow] += (((HourNow != GETHOUR(Rates[i - 1 ])) ? GETMINUTE(Rates[i]) : 0 ) +
                         ((HourNow != GETHOUR(Rates[i + 1 ])) ? MINUTE : GETMINUTE(Rates[i + 1 ])) -
                         GETMINUTE(Rates[i])) * Rates[i].spread;
     else
   #endif // #ifdef __MQL5__
    Hours[HourNow] += (Rates[i].high - Rates[i].low) / Rates[i].tick_volume;            
  }
  
   return ( ArrayMaximum (Hours));
  
}

// Возвращает время ролловера FOREX-символа на указанной неделе (кроме текущей).
datetime RolloverTime( const datetime time, const string Symb = NULL , const bool MQL4Method = false )
{  
   int Hours[HOURS];
   ArrayInitialize (Hours, 0 );  
  
   MqlRates Rates[];    

   datetime From = GetTimeDayOfWeek(time);
   datetime To = GetTimeDayOfWeek(time) + WEEK * DAY - 1 ;

   if ( CopyRates (Symb, PERIOD_M1 , From, To, Rates) > 0 )
  {
   #define OFFSET 3
    From = (Rates[ 0 ].time / HOUR - OFFSET) * HOUR;
    To = From + ((OFFSET << 1 ) - 1 ) * HOUR;
   #undef OFFSET
    
     for ( int Count = 0 ; Count < 4 ; Count++)
      Hours[GetRolloverInterval(Rates, From += DAY, To += DAY, MQL4Method)]++;
  }
                                    
   return ( ArrayMaximum (Hours) * HOUR);
}

#undef GETMINUTE
#undef GETHOUR


Başvuru.

 // Через Тестер выводит по неделям данные по времени ролловера.
const bool Init = EventSetTimer (WEEK * DAY);

void OnTimer ()
{
   const datetime time = TimeTradeServer () - WEEK * DAY;
   const datetime From = GetTimeDayOfWeek(time, MONDAY );
  
   Print (( string ) TimeToString (From, TIME_DATE ) + " - " + ( string ) TimeToString (From + WEEK * DAY - 1 , TIME_DATE ) +
         ": RolloverTime = " + TimeToString ( RolloverTime(time) , TIME_MINUTES ));
}


Sonuç.

 2021.03 . 01 - 2021.03 . 07 : RolloverTime = 00 : 00
2021.03 . 08 - 2021.03 . 14 : RolloverTime = 00 : 00
2021.03 . 15 - 2021.03 . 21 : RolloverTime = 23 : 00
2021.03 . 22 - 2021.03 . 28 : RolloverTime = 23 : 00
2021.03 . 29 - 2021.04 . 04 : RolloverTime = 00 : 00
2021.04 . 05 - 2021.04 . 11 : RolloverTime = 00 : 00
 

Min hesaplamanın özellikleri. çok güzelsin.

 double NormalizeDouble ( const double Value, const double Step )
{
   return ( NormalizeDouble (Step ? ( int )(Value / Step + 0.1 ) * Step : Value, 8 ));
}

// Минимальный лот с учетом требования мин. объема.
double GetMinLot( const string Symb, const double MinValue = 0 )
{
   const double MinLot = SymbolInfoDouble (Symb, SYMBOL_VOLUME_MIN )       ;
   double Res = MinLot;
  
   if (MinValue)
  {
     const double Diff = SymbolInfoDouble (Symb, SYMBOL_ASK ) * SymbolInfoDouble (Symb, SYMBOL_TRADE_TICK_VALUE );
    
    Res = Diff ? MinValue * SymbolInfoDouble (Symb, SYMBOL_TRADE_TICK_SIZE ) / Diff : 0 ;
    
     if (Res <= MinLot)
      Res = MinLot;
     else
    {
       double StepLot = SymbolInfoDouble (Symb, SYMBOL_VOLUME_STEP );      
      
       if (!StepLot)
        StepLot = MinLot;
      
       const double NormRes = NormalizeDouble (Res, StepLot);
      
      Res = (NormRes < Res) ? NormalizeDouble (NormRes + StepLot, 8 ) : NormRes;                                                                  
    }
  }             

   return (Res);
}


Örnek (RannForex -Binance_futures ).

 void OnStart ()
{
   for ( int i = SymbolsTotal ( true ) - 1 ; i >= 0 ; i--)
  {
     const string Symb = SymbolName (i, true );
    
     Print (Symb + ", MinLot =  " + ( string ) GetMinLot(Symb, 5 ) );
  }
}


XMRUSDT.fut, MinLot =   0.019
XRPUSDT.fut, MinLot =   4.7
TRXUSDT.fut, MinLot =   51.0
LTCUSDT.fut, MinLot =   0.027
FTMUSDT.fut, MinLot =   2.0
ETHUSDT.fut, MinLot =   0.002
EOSUSDT.fut, MinLot =   1.1
BNBUSDT.fut, MinLot =   0.02
BCHUSDT.fut, MinLot =   0.008
BTCUSDT.fut, MinLot =   0.001
Спецификации фьючерсных контрактов USDⓈ-Margined | Binance
Спецификации фьючерсных контрактов USDⓈ-Margined | Binance
  • www.binance.com
Фьючерсные контракты USDT-margined не являются инверсными. Это линейные фьючерсные продукты, которые котируются и рассчитываются в BUSD или USDT – стейблкоинах, привязанных к доллару США. Одним из ...
 

Bu MQL5'in bir özelliği mi yoksa bir hata mı?

 void OnStart ()
{     
   uchar ArrayDst1[];
   uchar ArraySrc1[];
  
   ArrayCopy (ArrayDst1, ArraySrc1, 10 );
   Print ( ArraySize (ArrayDst1)); // MQL4 - 10, MQL5 - 0

   uchar ArrayDst2[];
   uchar ArraySrc2[ 1 ];

   ArrayCopy (ArrayDst2, ArraySrc2, 10 );
   Print ( ArraySize (ArrayDst2)); // 11
      
   return ;
}
 

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

Mql5 dilinin özellikleri, incelikleri ve çalışma yöntemleri

A100 , 2021.05.20 13:43

Aradaki fark, normal işlevler (sağdan sola) ve satır içi işlevler (belirsiz sıra) olmasıdır.

satır içi işlevler hiç işlev değildir, yani. onların bir adresi yok. Bu açıdan, standart ve kullanıcı arasında hiçbir fark yoktur, bu nedenle, örneğin, en basit kullanıcı işlevinin (esas olarak satır içi olan) argümanları neden her zaman sağdan sola hesapladığı açık değildir. Gelecekte satır içi işlevler için sıranın değişebileceğini dışlamıyorum, bu nedenle

Bir keresinde, hesaplama sırasını güvenle kullanmak için satır içi anahtar kelimeyi tanıtmayı önermiştim:


Mevcut MQL5'te belirli işlevler için satır içi oluşturmayı devre dışı bırakmak mümkün müdür?

 
merhaba neden bu

 
MqlTick Ticks[4] = {}; // Обнуление статического массива.
 
fxsaber # :

Mantıklı değil çünkü:

 struct X {
    int i;
};
void OnStart ()
{
    X x[ 200000 ] = {};
}

F5 donuyor. Ayrıca, bu tartışmalı bir yapıcı baypas

 
A100 # :

Mantıklı değil çünkü:

F5 donuyor.

anlamadım Sıfırlama yararlı bir şeydir, bu yüzden mantıklıdır.