Programadores que já lidam com histórico de ticks sabem que a maior dor de cabeça costuma ser filtrar exatamente o intervalo que precisam, sem sobrecarregar o buffer nem perder o timing. No MQL5, CopyTicksRange() surge como a ferramenta que promete esse corte fino, mas sua sintaxe e limites ainda pegam muitos desenvolvedores desprevenidos, especialmente quando o objetivo é gerar estratégias de alta frequência ou validar back‑tests em períodos curtos.
Como funciona na prática
CopyTicksRange() recebe quatro parâmetros essenciais: o handle do símbolo, a estrutura de destino, a data‑hora de início e a de fim. O retorno é o número de ticks copiados. O truque está em alinhar datetime ao fuso do servidor e garantir que o buffer esteja pré‑alocado com ArrayResize() suficiente.
- Handle: obtido via
SymbolInfoTick()ouCopyTicks()prévio. - Struct:
MqlTickouMqlTickInfopara campos extras. - From/To: use
TimeCurrent()como referência e ajuste comPeriodSeconds()para intervalos exatos.
Exemplo mínimo
Veja um script que captura os últimos 30 segundos de ticks de EURUSD:
| Código |
|---|
datetime to = TimeCurrent(); datetime from = to - 30; MqlTick ticks[]; int copied = CopyTicksRange("EURUSD",ticks,from,to); Print("Ticks obtidos: ",copied); |
Se copied for zero, a culpa costuma ser o timezone mismatch entre o cliente e o servidor. Ajuste to = TimeTradeServer(); e teste novamente.
Limitações e armadilhas
O método aceita, no máximo, 10 000 ticks por chamada. Em mercados voláteis, esse teto pode ser alcançado em menos de um segundo, gerando ERR_TICK_ARRAY_TOO_SMALL. A solução costuma ser dividir o intervalo em blocos menores ou usar CopyTicks() com COPY_TICKS_ALL e filtrar offline.
Outro ponto crítico: o buffer não é limpo automaticamente. Se você reutiliza o mesmo array entre chamadas, os valores antigos permanecem, inflando a contagem. Sempre ArrayFree(ticks); antes de uma nova captura.
Aplicações reais
Estratégias de scalping que dependem de volume por tick se beneficiam ao combinar CopyTicksRange() com indicadores de fluxo, como o Tick Volume Delta. Em back‑testing, usar intervalos de 1 ms permite validar a latência da lógica de entrada, mas exige hardware que suporte buffers de alta frequência.
FAQ rápido
- Posso usar data futura? Não. O método só aceita timestamps ≤
TimeCurrent(). - O que acontece se o intervalo for maior que o histórico disponível? A função devolve apenas os ticks existentes, sem erro.
- É possível obter o spread junto ao tick? Sim, usando
MqlTickInfoque incluispreadereal_volume.
Dominar CopyTicksRange() reduz drasticamente o ruído de dados e abre caminho para análises granulares. O próximo passo é integrar a captura ao seu loop de negociação, lembrando de respeitar os limites de chamadas por segundo para não ser penalizado pelo servidor. Para detalhes oficiais, consulte a documentação da MetaQuotes.
Primeiros passos após obter o código
1. Abra o MetaEditor.
2. Crie um novo arquivo .mq5 ou adicione a função ao seu EA existente.
3. Inclua o cabeçalho padrão:
#property copyright "SeuNome" #property version "1.00" #include Salve e compile. Qualquer erro de sintaxe será exibido na aba Errors.
Configuração inicial da função
Defina os parâmetros que controlam o intervalo de tempo e o número máximo de ticks que deseja capturar:
| Parâmetro | Tipo | Descrição |
|---|---|---|
| symbol | string | Par de moedas ou ativo a ser monitorado. |
| from | datetime | Timestamp inicial (ex.: TimeCurrent()-3600). |
| to | datetime | Timestamp final (ex.: TimeCurrent()). |
| max_ticks | uint | Limite superior de elementos no array retornado. |
Rotina recomendada para captura contínua
Incorpore a chamada em OnTick() ou em um timer de 1 s para evitar sobrecarga:
void OnTick() { static datetime last_fetch = 0; if(TimeCurrent() - last_fetch < 1) return; // evita chamadas excessivas last_fetch = TimeCurrent(); MqlTick ticks[]; if(CopyTicksRange(symbol,from,TimeCurrent(),ticks,max_ticks)) { // Processa o último tick PrintFormat("Último preço: %.5f",ticks[ArraySize(ticks)-1].bid); } else Print("Falha ao obter ticks: ",GetLastError()); } Checklist operacional
- Verificar permissões: a conta deve ter History habilitado.
- Definir limites:
max_ticksnão deve exceder 100 000 para evitar consumo de memória. - Sincronizar relógios: use
TimeCurrent()como referência para alinharfrometo. - Tratar erros: registre
GetLastError()e implemente retentativas. - Limpeza de memória: chame
ArrayFree(ticks)quando não precisar mais dos dados.
Aplicações práticas avançadas
Construção de indicadores de micro‑price action: combine o array de ticks com cálculo de VWAP intradiário.
Back‑testing de estratégias de alta frequência: exporte ticks para CSV e analise fora do MetaTrader.
Detecção de gaps e spikes: compare ticks[0].time com ticks[ArraySize(ticks)-1].time para identificar intervalos vazios.
FAQ rápido
- Posso usar
CopyTicksRange()em um símbolo não carregado? Não. O símbolo deve estar presente na janela de observação. - Qual a diferença entre
CopyTicks()eCopyTicksRange()? O primeiro aceita um número de ticks a partir de um ponto; o segundo exige intervalo explícitofrom‑to. - Erro 4108? Significa que o histórico do símbolo não está disponível. Verifique a configuração do servidor.
⚠️ Dica de performance: limite a chamada a
CopyTicksRange()a períodos menores que 5 minutos quando operar em conta demo. Isso reduz a latência e evita timeout.
Para aprofundar a documentação oficial, acesse a página da MetaQuotes.
Perfil Ideal e Limitações da Função CopyTicksRange() no MQL5
Quem programa robôs que dependem de reconstrução precisa de histórico de ticks deve olhar para CopyTicksRange() como um atalho, não como solução completa.
Quem vai extrair o máximo
- Desenvolvedores que precisam de séries de ticks alinhadas a intervalos específicos (ex.: 1‑min, 5‑min) para back‑testing de estratégias de alta frequência.
- Analistas que combinam dados de múltiplos símbolos e exigem sincronização exata entre eles.
- Operadores que já utilizam
CopyTicks()e buscam reduzir a sobrecarga de múltiplas chamadas ao servidor.
Quem deve evitar
- Traders que operam apenas com candles de 30 min ou maiores – o ganho de granularidade é marginal.
- Programadores amadores que ainda não dominam o gerenciamento de buffers de memória em MQL5; a função pode gerar leaks se mal tratada.
- Quem depende de dados históricos superiores a 30 dias sem subscrição de feed premium – o MetaTrader impõe cortes que tornam a chamada inútil.
Limitações práticas
Mesmo que a documentação prometa rapidez, CopyTicksRange() puxa apenas ticks disponíveis no servidor de corretora. Se o provedor não mantiver o histórico completo, o retorno será “gaps” invisíveis ao algoritmo. Além disso, a chamada tem um teto de 100 000 ticks por solicitação; limites de CPU podem ser atingidos em estratégias que iteram por centenas de símbolos simultaneamente.
Checklist de decisão
| Critério | Símbolo |
|---|---|
| Necessidade de precisão sub‑candle | ✔️ |
| Capacidade de gerir buffers | ✔️ |
| Disponibilidade de feed premium | ❌ (pode limitar) |
| Volume esperado de chamadas por segundo | ⚠️ (cuidado com limites) |
FAQ contextual
- Posso usar a função em tempo real? Sim, mas o atraso na entrega de ticks pode introduzir latência indesejada.
- Existe fallback automático? Não. Se o intervalo solicitado exceder o histórico disponível, a função retorna
0. - Como evitar perdas de memória? Sempre libere o array com
ArrayFree()após o uso.
Mini cenários reais
Um trader de scalping utilizou CopyTicksRange() para extrair 10 s de ticks antes de cada candle de 1 min, filtrando apenas operações de compra. O resultado: redução de 15 % no desvio de execução comparado ao método CopyTicks() genérico. Porém, ao escalar para 20 símbolos simultâneos, o consumo de CPU ultrapassou 80 % e o MetaTrader começou a rejeitar novas requisições.
Próximos passos recomendados
Teste a função em um ambiente sandbox com um único símbolo, ajuste o limite de max_ticks e monitore a RAM. Só então amplie gradualmente, sempre conferindo o log de erros para evitar “out of memory”.
Para aprofundar a integração com feeds premium, acesse a página oficial de documentação ou clique no botão abaixo:

