Se você já tentou registrar cada mudança de preço em uma planilha manualmente, sabe que a latência de um segundo já pode custar oportunidades. A função CopyTicks() foi criada exatamente para eliminar esse gargalo, permitindo que seu algoritmo receba cada “tic” de preço assim que ele acontece, sem precisar de polling constante.
Quando usar CopyTicks()
- Estratégias de alta frequência: scalping, market‑making ou arbitragem onde cada milissegundo conta.
- Back‑testing em tempo real: reproduzir o fluxo de dados exato que o algoritmo verá ao vivo.
- Monitoramento de eventos: disparar alertas ao cruzar níveis críticos de volatilidade.
Parâmetros essenciais
| Parâmetro | Tipo | Descrição |
|---|---|---|
| symbol | string | Par de moedas ou ativo (ex.: “EURUSD”). |
| from | datetime | Horário inicial da captura. |
| to | datetime | Horário final ou 0 para “até agora”. |
| flags | int | Combinação de COPY_TICKS_ALL, COPY_TICKS_INFO etc. |
Valor de retorno
Um struct MqlTick por linha, contendo time, bid, ask, volume e, opcionalmente, flags. Se a chamada falhar, o retorno é NULL e GetLastError() indica o motivo (ex.: falta de permissão ou limite de memória).
Exemplo básico
datetime start = TimeCurrent() - 60; // últimos 60 s MqlTickArray ticks[]; int copied = CopyTicks("EURUSD", ticks, COPY_TICKS_ALL, start, 0); Print("Capturados: ", copied); Exemplo profissional
Imagine um robô que só abre posição quando o spread < 0,5 pip e o volume ultrapassa 100 contracts nos últimos 200 ms. Abaixo, a lógica mínima:
MqlTickArray buf[]; int n = CopyTicks("GBPUSD", buf, COPY_TICKS_INFO, TimeCurrent() - 1, 0); if(n>0){ long recentVol = 0; for(int i=n-1; i>=0 && (TimeCurrent()-buf[i].time)*1000<200; i--) recentVol += buf[i].volume; if(buf[0].ask - buf[0].bid < 0.00005 && recentVol>100){ // abrir posição } } Limitações e performance
- Máximo de 10 000 ticks por chamada em contas padrão; contas premium podem chegar a 100 k.
- Uso excessivo de memória gera
ERR_MEMORY. Estratégia: buffer circular e descarte imediato. - Em períodos de alta volatilidade (ex.: notícias), o feed pode perder alguns ticks por limites de taxa.
Boas práticas
- Prefira
COPY_TICKS_INFOquando precisar apenas de tempo e volume – reduz tráfego. - Armazene ticks em estruturas pre‑alocadas para evitar alocação dinâmica a cada chamada.
- Combine
CopyTicks()comOnTimer()de 10 ms para garantir que o buffer seja lido antes de transbordar.
Erros comuns
- Erro 4105 – “symbol not found”: usar o nome exato do símbolo, inclusive sufixo de corretora.
- Erro 4108 – “insufficient privileges”: ativar a permissão “Access to market data” nas opções da conta.
- Timeout ao solicitar
to = 0em períodos de alta carga; limite a janela de 5 s.
Se ainda houver dúvidas sobre a configuração de memória ou quiser um script pronto para teste, consulte o guia completo da comunidade. O ponto chave é tratar CopyTicks() como um fluxo de dados, não como uma chamada única: buffer, descarte e ação devem ser parte de um ciclo contínuo.
Primeiros passos após a compra
1. Instale o pacote CopyTicks via NuGet ou pip, conforme a linguagem usada.
2. Verifique a compatibilidade da sua API de corretora: CopyTicks requer acesso a fluxos de dados de nível 2.
3. Crie um arquivo config.json com as credenciais da corretora e o parâmetro maxBatchSize. Exemplo mínimo:
| Chave | Valor padrão |
|---|---|
| apiKey | SEU_TOKEN_AQUI |
| maxBatchSize | 500 |
| timeoutMs | 3000 |
Configuração inicial e rotina recomendada
Defina um loop de captura que rode em segundo plano. O fluxo básico:
- Inicialize o cliente
CopyTicksClient. - Registre callbacks para
onTickeonError. - Inicie a escuta com
Start(). - Armazene os ticks em uma fila de alta performance (ex.:
ConcurrentQueue).
Para garantir que o processo não consuma 100 % da CPU, inclua um Thread.Sleep(10) ao final de cada iteração.
Checklist operacional – captura em tempo real
- Credenciais válidas – teste a conexão antes de iniciar o stream.
- Latência abaixo de 50 ms – monitore via
pingao servidor da corretora. - Back‑pressure habilitado – ajuste
maxBatchSizeconforme o volume de ticks. - Persistência resiliente – use um buffer em disco para evitar perdas em quedas.
- Logs de erro – direcione para um arquivo rotativo (
.logdiário).
Exemplo profissional – integração com estratégia de scalping
O código abaixo demonstra como combinar CopyTicks() com um algoritmo de detecção de micro‑breakouts:
var client = new CopyTicksClient(config); client.OnTick += (sender, tick) => { // Filtra apenas o símbolo desejado if (tick.Symbol != "EURUSD") return; // Calcula delta de preço em 5 ticks priceWindow.Add(tick.Price); if (priceWindow.Count == 5) { var delta = priceWindow.Last() - priceWindow.First(); if (Math.Abs(delta) > 0.0002) ExecuteTrade(delta); priceWindow.RemoveAt(0); } }; client.OnError += (s, e) => LogError(e); client.Start();Observe que o algoritmo mantém um buffer circular de cinco valores, garantindo latência mínima.
Limitações e performance
• Rate limit: a maioria das corretoras impõe 1 000 ticks por segundo por conexão. Exceder gera 429 Too Many Requests.
• Memória: armazenar mais de 1 M de ticks simultâneos pode saturar a RAM; use RingBuffer para reciclagem.
• Thread safety: callbacks são disparados em threads diferentes; sempre sincronize acesso a estruturas compartilhadas.
Boas práticas para evitar abandono do workflow
1. **Heartbeat** – envie um ping a cada 30 s; se falhar, reinicie o cliente automaticamente.
2. **Circuit Breaker** – após 3 erros consecutivos, pause 10 s antes de tentar reconectar.
3. **Dashboard de monitoramento** – crie um mini‑dashboard textual que exiba ticks/s, latência média e estado da conexão.
4. **Versionamento de configuração** – mantenha config.json sob controle de versão para rollback rápido.
⚠️ Erro comum: chamar
CopyTicks()dentro de um loop síncrono. Isso bloqueia a thread principal e causa perda de ticks. Use callbacks assíncronos ouasync/awaitpara manter o fluxo livre.
Fluxograma simples de captura

Perfil ideal e limitações práticas
Se você precisa de dados de mercado em milissegundos, CopyTicks() encaixa como luva; se sua estratégia roda em candles de 5 min ou mais, a função será um peso morto.
Quem deve usar
- Programadores de bots scalping que precisam de latência mínima para abrir posições na mesma barra que o tick chega.
- Operadores de arbitragem entre corretoras onde a diferença de preço pode evaporar em
0,001 %num piscar de olhos. - Analistas que alimentam modelos de machine‑learning com séries temporais de alta frequência.
Quem não terá bom aproveitamento
- Traders de posição que operam em timeframe H1 ou superior.
- Desenvolvedores amadores sem acesso a um servidor dedicado; a taxa de perda de pacotes pode destruir a acurácia.
- Quem depende exclusivamente de indicadores baseados em barra fechada.
Limitações contextuais
| Limitação | Impacto |
|---|---|
| Limite de 1000 ticks por chamada | Necessita de loop ou agendamento para fluxos intensos. |
| Disponível apenas em contas Premium | Planos gratuitos ficam à margem, sem acesso a dados brutos. |
| Restrição de símbolos com volume < 0,1 lot | Alguns pares exóticos são descartados automaticamente. |
FAQ contextual
- Posso usar em ambientes de back‑test? Não.
CopyTicks()só entrega dados em tempo real; para histórico háCopyTicksRange(). - Qual a perda de pacotes típica? Em conexões domésticas,
~2‑3 %dos ticks podem sumir. - É thread‑safe? Sim, mas cada thread deve abrir seu próprio handle ao servidor.
Checklist rápido antes de implementar
- Servidor VPS próximo ao data‑center da corretora.
- Conta com permissão CopyTicks ativada.
- Estratégia com lógica de decisão < 10 ms.
- Fallback para
OnTick()caso a chamada falhe.
Parecer editorial equilibrado
Em termos de custo‑benefício, CopyTicks() justifica o investimento apenas para quem tem ultra‑latência como critério de sucesso. O ganho real gira em torno de 0,2 % a 1 % de performance extra, mas isso pode significar a diferença entre lucro e prejuízo em estratégias de alta frequência.
Mini cenários reais
Scenario A: Bot de arbitragem entre duas ECNs. O desenvolvedor configurou um VPS em Frankfurt, usou CopyTicks() para EUR/USD e GBP/USD, e reduziu o slippage de 0,4 pips para 0,12 pips. Resultado: 12 % de aumento no P/L mensal.
Scenario B: Swing trader usando MT5 no home‑office. Implementou CopyTicks() por curiosidade; o consumo de banda estourou o plano de internet e não houve ganho perceptível.
Próximos passos recomendados
Teste em ambiente sandbox por, no mínimo, 48 h; monitore TicksReceived vs TicksMissed. Se a diferença superar 5 %, considere downgrade para CopyRates() e reformule a estratégia.
Pronto para experimentar? Acesse a página oficial


