"CopyTicks"in Test Edilmesi - sayfa 42

 
1702 - Bulunan CopyTicks hataları düzeltildi!
 

CopyTicks çevrimdışına başarılı bir çağrıdan sonra GetLastError , 4403 döndürür.

 
Özel bir sembolün tüm işaretlerini bu şekilde almak istemek, Yetersiz hafızaya neden olur
 CopyTicks (Symb, Ticks, COPY_TICKS_ALL , 0 , UINT_MAX ); // out of memory


Bunu CopyTicksRange aracılığıyla yapacağım, ancak CopyTicks'in davranışını değiştirmek doğru görünüyor.

 
Bazen CopyTicksRange, sakallı yıl olan 2003.hcc, vb. BARS'ın indirilmesine neden olur.
 
Özel bir semboldeki CopyTicksRange sıfır döndürür. CopyTicks - Tamam.
 

CopyTicks (derleme 1881), yeni onaylar istenmiyorsa, istenenden daha eski verileri döndürür. Onlar. from parametresinden daha eski verileri döndürür. Hata yüzüyor - farklı zamanlarda ortaya çıkıyor, bu yüzden onu yeniden üreten küçük bir kod yazdım. EURUSD H1 , 2017.08.01 - 2018.08.01 tarihinde test cihazında piyasaya sürüldü.

 void OnTick ()
{
   static datetime lastActivityTime = D'2017.08.01' ;   
   static MqlTick ticks[ 2000 ];
   static const uint requestedCount = 2000 ;
   datetime dt[ 1 ];
   CopyTime ( NULL , PERIOD_CURRENT , 0 , 1 , dt);
   if (lastActivityTime >= dt[ 0 ]) {
       return ;
   }
   lastActivityTime = TimeCurrent ();
   
   int zero = 0 ;
   int idx = 0 ;
   do {
      ++idx;
       CopyTime ( NULL , PERIOD_CURRENT , idx, 1 , dt);
       if (dt[ 0 ] <= D'2017.08.01' ) break ;
       Print ( "dt[0]=" , dt[ 0 ]);
       ulong from = 1000 * dt[ 0 ];
       int cnt = CopyTicks ( Symbol (), ticks, COPY_TICKS_INFO , from, requestedCount);
       if (cnt < 1 ) {
         Print ( "Error in CopyTicks" );
         return ;
      }
       Print ( "cnt=" , cnt);
       for ( int i = 0 ; i < cnt; ++i) {
         if (ticks[i].time_msc < from) {
             Print ( "ERROR: i=" , i, ", ticks[i].time_msc=" , ticks[i].time_msc, " (" , ticks[i].time, ")" );
            i = i / zero;
         }
      }
       Print ( "done" );
   } while ( true );
}

İşte çıktı:

2018.10.17 21:31:26.221 2017.08.01 12:00:00 dt[0]=2017.08.01 03:00:00

2018.10.17 21:31:26.221 2017.08.01 12:00:00 cnt=2000

2018.10.17 21:31:26.221 2017.08.01 12:00:00 HATA: i=0, keneler[i].time_msc=1501552175606 (2017.08.01 01:49:35)

Onlar. 03:00'ten talep ettik ve 01:49'dan aldık. Gerçek koşullarda, fark bir aydan fazlaydı.

 
Gazilere soru. Bu yeni kene alma yöntemiyle hangi olası hatalar meydana gelebilir?
 input datetime inFrom = __DATETIME__ ;

// Свежие тики с последнего вызова
int GetFreshTicks( MqlTick &Ticks[] )
{
   static long LastTime = 0 ;
   static int LastAmount = 0 ;
  
   ArrayFree (Ticks);

   int Size = CopyTicksRange ( _Symbol , Ticks, COPY_TICKS_INFO , LastTime ? LastTime : ( long )inFrom * 1000 );
  
   if (Size > LastAmount)
  {
    LastTime = Ticks[Size - 1 ].time_msc;
     int NewLastAmount = 1 ;
    
     for ( int i = Size - 2 ; (i >= LastAmount) && (Ticks[i].time_msc == LastTime); i--)
      NewLastAmount++;
      
     if ( ArrayRemove (Ticks, 0 , LastAmount))
      Size -= LastAmount;
      
    LastAmount = NewLastAmount;
  }
   else
    Size = ArrayResize (Ticks, 0 );
  
   return (Size);
}

void OnTick ()
{
   MqlTick Ticks[];
  
   if (GetFreshTicks(Ticks))
     ArrayPrint (Ticks);
}
 
fxsaber :
Gazilere soru. Bu yeni kene alma yöntemiyle hangi olası hatalar meydana gelebilir?

Aynı zamana sahip kenelerin sırası garanti değil gibi görünüyor.

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

Gerçek zamanlı keneler

Andrey Khatimlianskii , 2020.01.31 14:40

Bu arada, Vasily Sokolov'un doğru kene koleksiyonu hakkında mükemmel bir makalesi vardı. Orada, senkronizasyon süreci ayrıntılı olarak analiz edilir (ki bende yok, bu yüzden bazen aynı işaretler yazdırılıyor):

Ancak CopyTiks işlevi, N adet son kene istenmesine izin vermez. Bunun yerine, belirtilen zamandan bu yana gelen tüm onayları sağlar. Bu, görevi karmaşıklaştırır. Bir sorgu yürütmemiz, bir onay dizisi almamız ve bunu önceki güncellemede alınan onay dizisiyle karşılaştırmamız gerekiyor. Aynı zamanda, yeni gelen kenelerden hangisinin "geçmiş teslimata" dahil olmadığını, yani yeni olduklarını öğreneceğiz. Ancak keneleri birbirleriyle doğrudan karşılaştırmak imkansızdır, çünkü aralarında hiçbir görünür fark olmayabilir. Örneğin, aşağıdaki işlem tablosunu göz önünde bulundurun:

Pirinç. 5. Aynı işlem örneği ile tüm işlemlerin tablosu.

Hemen iki grup kesinlikle aynı kene görüyoruz. Kırmızı çerçevelerle işaretlenirler, aynı zamana, hacme, yöne ve fiyata sahiptirler. Bu nedenle, tek tek keneleri birbiriyle karşılaştırmanın imkansız olduğundan emin oluyoruz.

Ancak bir grup keneyi karşılaştırabilirsiniz. İki tik grubu eşitse, bu ve sonraki tiklerin son fiyat güncellemesi sırasında zaten analiz edildiği sonucuna varabiliriz.


Пишем скальперский стакан цен на основе графической библиотеки CGraphic
Пишем скальперский стакан цен на основе графической библиотеки CGraphic
  • www.mql5.com
Именно с этой, улучшенной и дополненной версией мы и начнем работать, чтобы постепенно превратить ее в скальперский стакан цен. Краткий обзор графической библиотеки CPanel Созданию пользовательских интерфейсов в MQL5 посвящено много статей. Среди них особенно выделяется серия Анатолия Кажарского "Графические интерфейсы", после которой сложно...
 
Andrey Khatimlianskii :

Aynı zamana sahip kenelerin sırası garanti değil gibi görünüyor.

Kene gruplarından bahsediyorsak, kodda her şey yolunda görünüyor.

 
Onay önbelleği sıfırlanmaz.
 #define TOSTRING(A) " " + #A + " = " + ( string )(A)

MqlTick Ticks[];

void OnInit ()
{
   Print ( __FUNCTION__ + TOSTRING( TerminalInfoInteger ( TERMINAL_MEMORY_USED )) + TOSTRING( MQLInfoInteger ( MQL_MEMORY_USED ))); // Распечатываем начальное состояние памяти.
  
   CopyTicksRange ( _Symbol , Ticks, COPY_TICKS_INFO , D'2020.01.01' * 1000 ); // Получили историю тиков для инициализации по ней советника.
}

void OnTick ()
{
   const int Size = ArraySize (Ticks);
  
   if (Size)
  {
     const long BeginTime = Ticks[Size - 1 ].time_msc;
    
     ArrayFree (Ticks);
    
     CopyTicksRange ( _Symbol , Ticks, COPY_TICKS_INFO , BeginTime); // Получаем свежие тики без пропусков, чтобы гнать по ним советник.
  }
  
   Print ( __FUNCTION__ + TOSTRING( TerminalInfoInteger ( TERMINAL_MEMORY_USED )) + TOSTRING( MQLInfoInteger ( MQL_MEMORY_USED ))); // Распечатываем текущее состояние памяти.
}


Sonuç (soğuk başlatma - Terminalin başlamasından hemen sonra).

 OnInit TerminalInfoInteger ( TERMINAL_MEMORY_USED ) = 395 MQLInfoInteger ( MQL_MEMORY_USED ) = 1
OnTick TerminalInfoInteger ( TERMINAL_MEMORY_USED ) = 446 MQLInfoInteger ( MQL_MEMORY_USED ) = 1
OnTick TerminalInfoInteger ( TERMINAL_MEMORY_USED ) = 446 MQLInfoInteger ( MQL_MEMORY_USED ) = 1
OnTick TerminalInfoInteger ( TERMINAL_MEMORY_USED ) = 446 MQLInfoInteger ( MQL_MEMORY_USED ) = 1


Danışmanı kapatabilirsiniz, Terminal tarafından tüketim açısından hiçbir şey değişmeyecektir.

Neden: