Testare 'CopyTicks'. - pagina 42

 
1702 - i difetti di CopyTicks trovati sono stati corretti!
 

Dopo una chiamata riuscita a CopyTicks offline, GetLastError restituisce 4403.

 
Volendo ottenere tutti i ticchettii dei simboli personalizzati in questo modo, causa Out of memory
CopyTicks(Symb, Ticks, COPY_TICKS_ALL, 0, UINT_MAX); // out of memory


Lo farò tramite CopyTicksRange, ma il comportamento di CopyTicks sembra giusto da cambiare.

 
A volte CopyTicksRange fa sì che le BAR vengano caricate dall'anno barbuto: 2003.hcc, ecc.
 
CopyTicksRange sul carattere personalizzato restituisce zero. CopyTicks è normale.
 

CopyTicks (build 1881) restituisce dati più vecchi di quelli richiesti, se non vengono richiesti tick freschi. Cioè restituisce dati più vecchi del parametro. Il bug è fluttuante - appare in momenti diversi, così ho scritto del piccolo codice che lo riproduce. L'ho eseguito nel tester su EURUSD H1, 2017.08.01 - 2018.08.01.

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

Ecco l'output:

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 ERROR: i=0, ticks[i].time_msc=1501552175606 (2017.08.01 01:49:35)

Cioè abbiamo richiesto dalle 03:00 e ricevuto dalle 01:49. In condizioni reali, la differenza era più di un mese.

 
Una domanda per gli esperti. Quali sono le potenziali insidie di questo metodo per ottenere zecche fresche?
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:
Ecco una domanda per gli esperti. Quali potenziali errori possono esserci con questo metodo per ottenere zecche fresche?

L'ordine delle zecche con lo stesso tempo non è garantito, sembra.

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Ticchettii in tempo reale

Andrey Khatimlianskii, 2020.01.31 14:40

A proposito, c'èun eccellente articolo di Vasily Sokolov sulla corretta raccolta delle zecche. Lì in dettaglio è il processo di sincronizzazione analogica (che non ho, per cui a volte vengono stampati gli stessi tick):

Ma la funzione CopyTiks non permette di richiedere N ultimi tick. Invece fornisce tutti i tick, che provengono dal momento specificato. Questo complica il compito. Dovremmo eseguire una query, ottenere un array di tick e confrontarlo con un array di tick, ricevuto nell'aggiornamento precedente. Allo stesso tempo, scopriremo quali zecche appena arrivate non fanno parte della "fornitura precedente", cioè sono nuove. Ma è impossibile confrontare direttamente le zecche tra di loro, semplicemente perché non ci possono essere differenze visibili tra di loro. Per esempio, guardiamo la tabella delle offerte qui sotto:

Figura 5. Tabella di tutti gli accordi con un esempio di accordi identici.

Vediamo immediatamente due gruppi di zecche assolutamente identiche. Sono contrassegnati da cornici rosse, hanno lo stesso tempo, volume, direzione e prezzo. Così, vediamo che è impossibile confrontare le singole zecche tra loro.

Ma è possibile confrontareun gruppo di zecche. Se due gruppi di tick sono uguali tra loro, possiamo concludere che questi tick e i successivi sono già stati analizzati durante il precedente aggiornamento del prezzo.


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

L'ordine delle zecche con lo stesso tempo non è garantito, sembra.

Se stai parlando di gruppi di zecche, non sembra esserci nulla di sbagliato nel codice.

 
La cache dei tick non viene resettata.
#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))); // Распечатываем текущее состояние памяти.
}


Risultato (eseguito a freddo - subito dopo l'avvio del terminale).

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


È possibile spegnere l'Expert Advisor, nulla cambierà in termini di consumo del terminale.

Motivazione: