Testando 'CopyTicks'. - página 42

 
1702 - as falhas do CopyTicks encontradas foram corrigidas!
 

Após uma chamada bem sucedida para CopyTicks offline, GetLastError retorna 4403.

 
Desejando obter todos os tiquetaques de símbolos personalizados desta forma causa Fora da memória
CopyTicks(Symb, Ticks, COPY_TICKS_ALL, 0, UINT_MAX); // out of memory


Vou fazer isso via CopyTicksRange, mas o comportamento do CopyTicks parece certo para mudar.

 
Às vezes o CopyTicksRange faz com que os BARs sejam carregados a partir do ano barbudo: 2003.hcc etc.
 
CopyTicksRange em caracteres personalizados retorna zero. CopyTicks é normal.
 

CopyTicks (build 1881) retorna dados mais antigos do que os solicitados se não forem solicitados carrapatos frescos. Ou seja, ele retorna dados mais antigos do que o parâmetro. Bug está flutuando - ele aparece em momentos diferentes, então escrevi um pequeno código que o reproduz. Eu o testei no 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);
}

Aqui está a saída:

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 01:49:35)

Isto é, solicitamos a partir das 03:00 e recebemos a partir de 01:49. Em condições reais, a diferença foi de mais de um mês.

 
Uma pergunta para os experientes. Quais são as armadilhas potenciais deste método de obtenção de carrapatos frescos?
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:
Esta é uma pergunta para os especialistas. Que erros potenciais podem existir com este método de obtenção de carrapatos frescos?

A ordem dos carrapatos com o mesmo tempo não é garantida, ao que parece.

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

Tiquetaques em tempo real

Andrey Khatimlianskii, 2020.01.31 14:40

A propósito, háum excelente artigo de Vasily Sokolov sobre a correta coleta de carrapatos. Lá em detalhes é o processo de sincronização analógica (que eu não tenho, por causa do qual às vezes são impressos os mesmos carrapatos):

Mas a função CopyTiks não permite solicitar N últimos ticks. Em vez disso, ele fornece todos os carrapatos, que vieram do momento especificado. Isto complica a tarefa. Devemos realizar uma consulta, obter uma matriz de carrapatos e compará-la com uma matriz de carrapatos, recebida na atualização anterior. Ao mesmo tempo, descobriremos quais carrapatos recém-chegados não fazem parte do "fornecimento anterior", ou seja, são novos. Mas é impossível comparar carrapatos entre eles diretamente, simplesmente porque pode não haver nenhuma diferença visível entre eles. Por exemplo, vejamos a tabela de acordos abaixo:

Figura 5. Tabela de todos os acordos com um exemplo de acordos idênticos.

Vemos imediatamente dois grupos de carrapatos absolutamente idênticos. Eles são marcados com quadros vermelhos, têm o mesmo tempo, volume, direção e preço. Assim, vemos que é impossível comparar carrapatos individuais uns com os outros.

Mas é possível compararum grupo de carrapatos. Se dois grupos de carrapatos são iguais um ao outro, podemos concluir que estes e os seguintes carrapatos já foram analisados durante a atualização de preços anterior.


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

A ordem dos carrapatos com o mesmo tempo não é garantida, ao que parece.

Se você está falando de grupos de carrapatos, não parece haver nada de errado com isso no código.

 
O cache de carrapatos não é redefinido.
#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))); // Распечатываем текущее состояние памяти.
}


Resultado (esfriar - imediatamente após o início do Terminal).

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


É possível desligar o Expert Advisor, nada mudará em termos de consumo pelo Terminal.