CopyTicks

A função obtém, dentro da matriz ticks_array, ticks no formato MqlTick, além disso a indexação é realizada do passado para o presente, ou seja, o tick com índice 0 é o mais antigo na matriz. Para a análise de ticks, é necessário verificar o campo flags, que indica o que foi alterado nesse tick.

int  CopyTicks(
   string           symbol_name,           // nome do símbolo
   MqlTick&         ticks_array[],         // matriz para recebimento de ticks
   uint             flags=COPY_TICKS_ALL,  // sinalizador que define o tipo de ticks obtidos
   ulong            from=0,                // data a partir da qual são solicitados os ticks
   uint             count=0                // número de ticks que é necessário obter
   );

Parâmetros

symbol_name

[in]  Símbolo.

ticks_array

[out]  Matriz do tipo MqlTick para recebimento de ticks.

flags

[in]  sinalizador que especifica o tipo de ticks solicitados. COPY_TICKS_INFO — ticks chamados pelas alterações do Bid e/ou Ask, COPY_TICKS_TRADE — ticks com alterações em Last e Volume, COPY_TICKS_ALL — todos os ticks. Em qualquer tipo de solicitação, nos restantes campos da estrutura MqlTick são acrescentados os valores do tick anterior.

from

[in]  Data a partir da qual são solicitados os ticks. É especificada em milissegundos desde 01.01.1970. Se o parâmetro from=0, são entregues as últimas count de ticks.

count

[in]  Número de ticks solicitados. Se os parâmetros from e count não forem definidos, no matriz ticks_array[] serão registrados todos os últimos ticks disponíveis, mas não mais de 2 000.

Valor de retorno

Núerod de ticks copiados ou -1 em caso de OnCalculate() nos indicadores é chamada após a entrada de cada tick.

Nos EAs e scripts, a função CopyTicks() pode esperar até 45 segundos antes de obter o resultado: Em contraste com o indicador, cada EA e script opera em seu próprio thread e, portanto, pode esperar 45 segundos até a conclusão da sincronização. Se, durante este tempo, a quantidade necessária de ticks não forem sincronizados, CopyTicks () irá retornar ticks disponíveis, por tempo esgotado, e continuará a sincronização. A função OnTick() nos EAs não é processador de ticks, ela simplesmente notifica o EA sobre as mudanças no mercado. Essas mudanças podem ser um lote: o terminal pode fazer simultaneamente alguns ticks, mas a função OnTick () será chamada somente uma vez para notificar o EA do estado mais recente do mercado.

Velocidade de retorno de dados: o terminal armazena, para cada símbolo, os últimos 4096 ticks no cache para acesso rápido (para símbolos com livro de ofertas serão 65536 ticks), as solicitações de esses dados são feitas com maior velocidade. Ao solicitar ticks da sessão de negociação atual fora dos limites do cache, a CopyTicks() chama os ticks que são armazenados na memória do terminal, estas solicitações exigem mais tempo de execução. As mais lentas são as solicitações de ticks para outros dias, como, neste caso, os dados são lidos a partir do disco.

Exemplo:

#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property script_show_inputs
//--- Requesting 100 million ticks to be sure we receive the entire tick history
input int      getticks=100000000; // The number of required ticks
//+------------------------------------------------------------------+
//| Função de início do programa script                              |
//+------------------------------------------------------------------+
void OnStart()
  {
//---  
   int     attempts=0;     // Contagem de tentativas
   bool    success=false;  // A flag de uma cópia bem sucedida de ticks
   MqlTick tick_array[];   // Tick recebendo o array
   MqlTick lasttick;       // Para receber os últimos dados do tick
   SymbolInfoTick(_Symbol,lasttick);
//--- Faça 3 tentativas de receber ticks
   while(attempts<3)
     {
      //--- Medição da hora de início antes de receber os ticks
      uint start=GetTickCount();
//--- Solicitando o histórico de ticks desde 1970.01.01 00:00.001 (parâmetro para=1 ms)
      int received=CopyTicks(_Symbol,tick_array,COPY_TICKS_ALL,1,getticks);
      if(received!=-1)
        {
         //--- Mostrando informações sobre o número de ticks e tempo gasto
         PrintFormat("%s: received %d ticks in %d ms",_Symbol,received,GetTickCount()-start);
         //--- Se o histórico de ticks é sincronizado, o código de erro é igual a zero
         if(GetLastError()==0)
           {
            success=true;
            break;
           }
         else
            PrintFormat("%s: Ticks ainda não estão sincronizados, %d ticks recebidos por %d ms. Error=%d",
            _Symbol,received,GetTickCount()-start,_LastError);
        }
      //--- Contagem de tentativas
      attempts++;
      //--- Uma pausa de um segundo para aguardar o fim da sincronização da base de dados de ticks
      Sleep(1000);
     }
//--- A recepção de ticks solicitados no início do histórico de ticks falhou em três tentativas
   if(!success)
     {
      PrintFormat("Error! Falha em receber %d ticks do %s em três tentativas",getticks,_Symbol);
      return;
     }
   int ticks=ArraySize(tick_array);
//--- Mostrando a hora da primeira marca no array
   datetime firstticktime=tick_array[ticks-1].time;
   PrintFormat("Horário do último tick = %s.%03I64u",
               TimeToString(firstticktime,TIME_DATE|TIME_MINUTES|TIME_SECONDS),tick_array[ticks-1].time_msc%1000);
//--- Obtivemos o último tick no array
   datetime lastticktime=tick_array[0].time;
   PrintFormat("Horário do primeiro tick = %s.%03I64u",
               TimeToString(lastticktime,TIME_DATE|TIME_MINUTES|TIME_SECONDS),tick_array[0].time_msc%1000);
 
//---                                                           
   MqlDateTime today;
   datetime current_time=TimeCurrent();                         
   TimeToStruct(current_time,today);                            
   PrintFormat("current_time=%s",TimeToString(current_time));   
   today.hour=0;
   today.min=0;
   today.sec=0;
   datetime startday=StructToTime(today);
   datetime endday=startday+24*60*60;
   if((ticks=CopyTicksRange(_Symbol,tick_array,COPY_TICKS_ALL,startday*1000,endday*1000))==-1) 
     {
      PrintFormat("CopyTicksRange(%s,tick_array,COPY_TICKS_ALL,%s,%s) failed, error %d",       
                  _Symbol,TimeToString(startday),TimeToString(endday),GetLastError());          
      return;                                                                                  
     }
   ticks=MathMax(100,ticks); 
//--- Mostrando os primeiros 100 ticks do último dia
   int counter=0;
   for(int i=0;i<ticks;i++)
     {
      datetime time=tick_array[i].time;
      if((time>=startday) && (time<endday) && counter<100)
        {
         counter++;
         PrintFormat("%d. %s",counter,GetTickDescription(tick_array[i]));
        }
     }
//--- Mostrando as primeiras 100 ofertas do último dia
   counter=0;
   for(int i=0;i<ticks;i++)
     {
      datetime time=tick_array[i].time;
      if((time>=startday) && (time<endday) && counter<100)
        {
         if(((tick_array[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) || ((tick_array[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL))
           {
            counter++;
            PrintFormat("%d. %s",counter,GetTickDescription(tick_array[i]));
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Retorna a descrição de string de um tick                         |
//+------------------------------------------------------------------+
string GetTickDescription(MqlTick &tick)
  {
   string desc=StringFormat("%s.%03d ",
                            TimeToString(tick.time),tick.time_msc%1000);
//--- Checando flags
   bool buy_tick=((tick.flags&TICK_FLAG_BUY)==TICK_FLAG_BUY);
   bool sell_tick=((tick.flags&TICK_FLAG_SELL)==TICK_FLAG_SELL);
   bool ask_tick=((tick.flags&TICK_FLAG_ASK)==TICK_FLAG_ASK);
   bool bid_tick=((tick.flags&TICK_FLAG_BID)==TICK_FLAG_BID);
   bool last_tick=((tick.flags&TICK_FLAG_LAST)==TICK_FLAG_LAST);
   bool volume_tick=((tick.flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME);
//--- Verificar flags de negociação num primeiro tick
   if(buy_tick || sell_tick)
     {
      //--- Formando uma saída para o tick de negociação
      desc=desc+(buy_tick?StringFormat("Buy Tick: Last=%G Volume=%d ",tick.last,tick.volume):"");
      desc=desc+(sell_tick?StringFormat("Sell Tick: Last=%G Volume=%d ",tick.last,tick.volume):"");
      desc=desc+(ask_tick?StringFormat("Ask=%G ",tick.ask):"");
      desc=desc+(bid_tick?StringFormat("Bid=%G ",tick.ask):"");
      desc=desc+"(Trade tick)";
     }
   else
     {
      //--- Forme uma saída diferente para um tick de informação
      desc=desc+(ask_tick?StringFormat("Ask=%G ",tick.ask):"");
      desc=desc+(bid_tick?StringFormat("Bid=%G ",tick.ask):"");
      desc=desc+(last_tick?StringFormat("Last=%G ",tick.last):"");
      desc=desc+(volume_tick?StringFormat("Volume=%d ",tick.volume):"");
      desc=desc+"(Info tick)";
     }
//--- Retornando descrição do tick
   return desc;
  }
//+------------------------------------------------------------------+
/* Exemplo de saída
Si-12.16: recebeu 11048387 ticks em 4937 ms
Horário do último tick = 2016.09.26 18:32:59.775
Horário do primeiro tick = 2015.06.18 09:45:01.000
1.  2016.09.26 09:45.249 Ask=65370 Bid=65370 (Info tick)
2.  2016.09.26 09:47.420 Ask=65370 Bid=65370 (Info tick)
3.  2016.09.26 09:50.893 Ask=65370 Bid=65370 (Info tick)
4.  2016.09.26 09:51.827 Ask=65370 Bid=65370 (Info tick)
5.  2016.09.26 09:53.810 Ask=65370 Bid=65370 (Info tick)
6.  2016.09.26 09:54.491 Ask=65370 Bid=65370 (Info tick)
7.  2016.09.26 09:55.913 Ask=65370 Bid=65370 (Info tick)
8.  2016.09.26 09:59.350 Ask=65370 Bid=65370 (Info tick)
9.  2016.09.26 09:59.678 Bid=65370 (Info tick)
10. 2016.09.26 10:00.000 Sell Tick: Last=65367 Volume=3 (Trade tick)
11. 2016.09.26 10:00.000 Sell Tick: Last=65335 Volume=45 (Trade tick)
12. 2016.09.26 10:00.000 Sell Tick: Last=65334 Volume=95 (Trade tick)
13. 2016.09.26 10:00.191 Sell Tick: Last=65319 Volume=1 (Trade tick)
14. 2016.09.26 10:00.191 Sell Tick: Last=65317 Volume=1 (Trade tick)
15. 2016.09.26 10:00.191 Sell Tick: Last=65316 Volume=1 (Trade tick)
16. 2016.09.26 10:00.191 Sell Tick: Last=65316 Volume=10 (Trade tick)
17. 2016.09.26 10:00.191 Sell Tick: Last=65315 Volume=5 (Trade tick)
18. 2016.09.26 10:00.191 Sell Tick: Last=65313 Volume=3 (Trade tick)
19. 2016.09.26 10:00.191 Sell Tick: Last=65307 Volume=25 (Trade tick)
20. 2016.09.26 10:00.191 Sell Tick: Last=65304 Volume=1 (Trade tick)
21. 2016.09.26 10:00.191 Sell Tick: Last=65301 Volume=1 (Trade tick)
22. 2016.09.26 10:00.191 Sell Tick: Last=65301 Volume=10 (Trade tick)
23. 2016.09.26 10:00.191 Sell Tick: Last=65300 Volume=5 (Trade tick)
24. 2016.09.26 10:00.191 Sell Tick: Last=65300 Volume=1 (Trade tick)
25. 2016.09.26 10:00.191 Sell Tick: Last=65300 Volume=6 (Trade tick)
26. 2016.09.26 10:00.191 Sell Tick: Last=65299 Volume=1 (Trade tick)
27. 2016.09.26 10:00.191 Bid=65370 (Info tick)
28. 2016.09.26 10:00.232 Ask=65297 (Info tick)
29. 2016.09.26 10:00.276 Sell Tick: Last=65291 Volume=31 (Trade tick)
30. 2016.09.26 10:00.276 Sell Tick: Last=65290 Volume=1 (Trade tick)
*/

Veja também

SymbolInfoTick, Estrutura para recebimento de preços atuais, OnTick()