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

 
Marat Sultanov #:
Eskiden (eski derleyici yapılarında bile) bir sınıfı bildirilmeden önce kullanmak mümkündü:
Ancak şimdi derlerken bir hata alıyoruz:
tanımlanmamış sınıf 'A' kullanılamaz

Çalışmayı durdurursa, doğru olup olmadığını bilmek iyi olur.

Nesneler yerine işaretçiler yaparsanız, eski sürüm de çalışacaktır.

 
fxsaber #:

Çalışmayı durdurduysa, yapılacak doğru şeyin bu olup olmadığını bilmek iyidir.

Nesneler yerine işaretçiler yaparsanız, eski sürüm de çalışacaktır.

Harika bir nokta ve ipucu için teşekkürler!

Evet, gerçekten de durum bir işaretçi ile mükemmel bir şekilde çözülür:

class A;

class B
{
   public: A * a;
   public: int Val;
};

class A
{
   public: B * b;
   public: int Test() {return b.Val + 1;}
};

//+------------------------------------------------------------------+
//|                                                                                |
//+------------------------------------------------------------------+
void OnStart()
{
   B b;
   A a;
   
   b.a = GetPointer(a);
   b.a.b = GetPointer(b);
   b.Val = 1;
   
   Print(b.a.Test());
}
 

Hızlı algoritma hayranları. Nanosaniyeler için savaşanlar :)


Görev: Çubuğun şu anda var olduğu bilindiğinde, verilen zamana ve TF'ye göre çubuk açılış zaman ını bulun. Örneğin, açılış ve kapanış pozisyonlarının zamanına göre.

Çoğu programcı iTime ve iBarShift'in bir kombinasyonunu kullanacaktır. Bu en yavaş uygulama olacaktır, özellikle böyle bir uygulama yüklenen verilerin veya taranmış dizilerin güncel bir geçmişini gerektirir. Ayrıca, gerekli geçmiş eksikse bu yaklaşım hata üretebilir.

Daha ileri düzey programcılar bu sorunu MqlDateTime yapısı ve TimeToStruct() fonksiyonu ile çözecektir. Bu kötü bir çözüm değildir ve yeterince hızlıdır.

Ancak, önceki çözümden birkaç kat daha üretken olan üçüncü bir çözüm daha vardır:

//+------------------------------------------------------------------+
// получает время открытия виртуального бара по входному времени и Таймфрейму, вне зависимости от того, существует реальный бар или нет.
// корректно считает только до 28.02.2100 !!!!
// не является заменой iBarShift!!! Не зависит от истории баров.  
datetime getStartTimeOfBarFast(ENUM_TIMEFRAMES tf, datetime t) {
   if (tf==0) tf=_Period;

   int ts=0;
   if (tf<PERIOD_MN1) {
      ushort i_tf= ushort(tf);
      uchar _i =uchar(i_tf>>14);
      int n = i_tf & 0x0FFF;
      ts = (_i==0)?n*60:(_i==1)?n*60*60:60*60*24*7;
   }
   if (tf<PERIOD_W1) return t-t%ts;
   if (tf==PERIOD_W1) return t-(t+4*24*60*60)%ts;
   else { // Period MN1
      static int dm[12] = {0,31,61,92,122,153,184, 214, 245, 275, 306, 337};
      static int last_days = 0;
      static datetime last_result = 0;
      int days = int(t/(24*60*60));
      if (last_days!=days) {
         last_days = days;
         int d1 = (days+306+365)%1461;
         int y = d1/365;
         datetime t1 = t - t%(24*60*60) - d1*24*60*60;
         int m = 0;
         if (d1==1460) {
            m=11;
            y--;
         };
         int d = d1-y*365+1;
         if (d!=31) if (d==276) m = 9;
            else m = int (d/30.68);
         if (m<0 || m>11) return -1;
         last_result = t1+y*365*24*60*60+dm[m]*24*60*60;
      }
      return last_result;
   }
}
//+------------------------------------------------------------------+

Bu algoritmadaki ana zorluk ayın başlangıç zamanını hesaplamaktır (yeşil ile vurgulanmıştır) Lütfen algoritmanın işleyişini anlamaya çalışmayın. Burada basitten karmaşığa gitmenin sonucu olan bir sihir var. Karmaşık olandan basit olana giden ters yolu geçmek çok daha zor olacaktır.

Performans kazancı, sarı renkle vurgulanan standart PeriodSeconds() işlevi yerine TF'den bir çubuktaki saniyeleri alma algoritması tarafından da sağlanır.


Her üç yöntemin performansını hesaplayan ve karşılaştıran bir test komut dosyası ekliyorum:

2023.11.14 12:15:29.145 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_MN1========
2023.11.14 12:15:29.146 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 21.20 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:29.146 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 6.10 наносекунд - Быстрый расчет
2023.11.14 12:15:29.147 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 142.00 наносекунд - Расчет через iBarShift
2023.11.14 12:15:29.147 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:15:34.226 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_MN1========
2023.11.14 12:15:34.227 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 19.80 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:34.227 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 6.70 наносекунд - Быстрый расчет
2023.11.14 12:15:34.228 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 127.50 наносекунд - Расчет через iBarShift
2023.11.14 12:15:34.228 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:15:39.856 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_W1========
2023.11.14 12:15:39.856 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11997367833600, время выполнения 1 иттерации = 2.80 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:39.856 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11997367833600, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.14 12:15:39.857 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11997367833600, время выполнения 1 иттерации = 98.30 наносекунд - Расчет через iBarShift
2023.11.14 12:15:39.857 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:15:52.770 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_H2========
2023.11.14 12:15:52.771 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000355999200, время выполнения 1 иттерации = 4.10 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:52.771 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000355999200, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.14 12:15:54.255 timeToStartMonth (EURUSD,M1)    контрольная сумма - 0, время выполнения 1 иттерации = 148466.50 наносекунд - Расчет через iBarShift
2023.11.14 12:15:54.255 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:15:58.759 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_M4========
2023.11.14 12:15:58.759 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000391999920, время выполнения 1 иттерации = 3.60 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:58.759 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000391999920, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.14 12:15:59.864 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000017286960, время выполнения 1 иттерации = 110555.70 наносекунд - Расчет через iBarShift
2023.11.14 12:15:59.864 timeToStartMonth (EURUSD,M1)    ========================================================================

iBarShift ile sağlama toplamı eşleşmeyecektir , çünkü iBarShift gerçek çubuklarla çalışır. Sağlama toplamı yalnızca MN1 ve W1 zaman dilimlerinde çakışacaktır, çünkü bu tür çubukların geçmişinde delik yoktur.
Algoritma önceki hesaplamaları kaydetmek için çalışmaya başladığında döngüde küçük bir zaman adımı (bir günden az) kullanırsanız performans daha yüksek olacaktır:

2023.11.14 12:14:10.714 timeToStartMonth (EURUSD,M1)    =====LOOP=1000000========STEPS=1000 seconds======PERIOD_MN1========
2023.11.14 12:14:10.722 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 8.03 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:14:10.723 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 1.18 наносекунд - Быстрый расчет
2023.11.14 12:14:10.860 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 136.80 наносекунд - Расчет через iBarShift
2023.11.14 12:14:10.860 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:14:17.502 timeToStartMonth (EURUSD,M1)    =====LOOP=1000000========STEPS=1000 seconds======PERIOD_MN1========
2023.11.14 12:14:17.510 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 7.70 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:14:17.511 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 1.18 наносекунд - Быстрый расчет
2023.11.14 12:14:17.648 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 137.54 наносекунд - Расчет через iBarShift
2023.11.14 12:14:17.648 timeToStartMonth (EURUSD,M1)    ========================================================================


iBarShift aracılığıyla algoritma için aşırı değerler (mavi ile vurgulanmıştır), gerekli geçmişin veya dizi tarafından hesaplanan TF'lerin mevcut eksikliğinden kaynaklanır ve bu da bunların yüklenmesini başlatır.
Yüklemeden sonra sonuç aşağıdaki gibi olacaktır:

2023.11.14 12:47:06.158 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_H2========
2023.11.14 12:47:06.158 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000379996800, время выполнения 1 иттерации = 4.60 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:47:06.158 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000379996800, время выполнения 1 иттерации = 2.60 наносекунд - Быстрый расчет
2023.11.14 12:47:06.159 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000009103200, время выполнения 1 иттерации = 129.10 наносекунд - Расчет через iBarShift
2023.11.14 12:47:06.159 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:47:13.899 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_M4========
2023.11.14 12:47:13.899 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000411199920, время выполнения 1 иттерации = 2.80 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:47:13.899 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000411199920, время выполнения 1 иттерации = 1.40 наносекунд - Быстрый расчет
2023.11.14 12:47:13.903 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000038634480, время выполнения 1 иттерации = 381.30 наносекунд - Расчет через iBarShift
2023.11.14 12:47:13.903 timeToStartMonth (EURUSD,M1)    ========================================================================

Dosyalar:
 
Nikolai Semko #:

Hızlı algoritma hayranları. Nanosaniyeler için savaşanlar :)

...

😮😲😳🥴🤪

...

ah...

mmm....

oooh....

gkghm... Basit sorumun bu şekilde ortaya çıkacağını düşünmemiştim.

Aynen böyle.

 
Artyom Trishkin #:

😮😲😳🥴🤪

...

Ah...

Mmm.

ohhhh....

ahem. Basit sorumun bu şekilde sonuçlanacağını düşünmemiştim.

Oh.

Evet Artem, beni bir süre kandırdın.
Sportif bir ilgiydi.
Umarım ben dahil birilerinin işine yarar. :))

 
Nikolai Semko #:

Evet Artem, beni bir süre kandırdın.
Sportif ilgi üzerine çalıştım.
Umarım birilerine, bu arada bana da faydalı olur. :))

Tabii ki olacak. Harika. Tekrar teşekkür ederim!

S.F. Bu beni eğlendirdi: "sadece 28.02.2100 tarihine kadar doğru sayılır !!!!".

Ondan sonra ne yapacağız?

 
Artyom Trishkin #:

Tabii ki işe yarayacak. Harika. Tekrar teşekkür ederim!

S.F. Bu beni eğlendirdi: "sadece 28.02.2100 tarihine kadar doğru sayılır !!!!".

Ondan sonra ne yapacağız?

haha.
Bu algoritmanın 75 yıl boyunca talep göreceğinden şüpheliyim. Kuantum bilgisayarlar muhtemelen tamamen farklı bir programlama ile dünyayı çoktan yönetecek.
Dürüst olmak gerekirse, Miladi takvimi hesaba katmak tembellikti. 2000 yüksek riskliydi, 2100 artık değil.

 
Nikolai Semko #:

haha.
Bu algoritmanın 75 yıl boyunca talep göreceğinden şüpheliyim. Kuantum bilgisayarlar muhtemelen tamamen farklı bir programlama ile dünyayı çoktan yönetecek.
Dürüst olmak gerekirse, Gregoryen takvimini tamamen hesaba katmak tembellikti. 2000 yüksek riskliydi, 2100 artık değil.

MN için önceden hesaplanmış bir dizi kullanabilirsiniz, orada neredeyse hiçbir şey yoktur

Ln2(12 ay * yüz yıl)...11 if'ler ve ikili aramada karşılaştırmalar, ancak diğer hesaplamalar olmadan.

 
Maxim Kuznetsov #:

MN için önceden hesaplanmış bir dizi kullanabilirsiniz, orada neredeyse hiç veri yoktur.

Ln2(12 ay * yüz yıl)...11 if'ler ve ikili aramada karşılaştırmalar, ancak başka hesaplamalar olmadan.

Hiçbir zorluk yok. Nasıl uygulanacağını biliyorum.
Sadece hiçbir zaman yararlı olmayacağından %100 emin olduğum bir şey yapmak istemiyorum.
 
Maxim Kuznetsov #:

MN için önceden hesaplanmış bir dizi kullanabilirsiniz, orada neredeyse hiç veri yoktur.

Ln2(12 ay * yüz yıl)...11 if'ler ve ikili aramada karşılaştırmalar, ancak diğer hesaplamalar olmadan.

Ah, ilk başta yanlış okumuşum.
Hayır, yanılıyorsunuz. Performans artışı işe yaramayacaktır. Hala hesaplamalarda takılıp kalacaksınız. Ve dizi elemanlarına erişim algoritmayı çok yavaşlatır.