Se você já tentou contar quantas vezes um critério aparece em um intervalo e acabou repetindo a mesma fórmula por dezenas de linhas, sabe o quanto isso pode travar seu fluxo de trabalho. PositionsTotal() surge como a tentativa de centralizar esse cálculo, mas a realidade prática costuma ser mais tortuosa: dependência de arrays ordenados, limites de memória e comportamento inesperado quando há valores ausentes.
Quando usar PositionsTotal()
- Objetivo: obter o número total de ocorrências de um elemento dentro de um intervalo sem percorrer a lista manualmente.
- Cenário típico: relatórios de inventário onde cada linha representa um SKU e você precisa saber quantas vezes um código específico aparece.
- Limitação: a função só funciona corretamente se o intervalo for contíguo e sem células vazias. Caso contrário, o retorno pode ser
#N/Aou subestimar o total.
Como implementar passo a passo
1. Defina o intervalo de busca (ex.: A2:A1000).
2. Insira a fórmula =PositionsTotal(A2:A1000; "ABC123") em qualquer célula livre.
3. Pressione Enter e verifique o resultado.
Se a sua planilha contém linhas vazias, insira antes a função IFERROR para evitar erros:
=IFERROR(PositionsTotal(A2:A1000; "ABC123"); 0)Exemplo completo
| SKU | Descrição |
|---|---|
| ABC123 | Caneta azul |
| XYZ789 | Lápis preto |
| ABC123 | Caneta azul |
| — | |
| ABC123 | Caneta azul |
Aplicando =PositionsTotal(A2:A6;"ABC123") o resultado será 3, mesmo com a linha vazia.
Performance e armadilhas
- Em planilhas com mais de 100 000 linhas, a função pode consumir até 30 % a mais de CPU, provocando lentidão ao abrir o arquivo.
- Se o intervalo inclui fórmulas que retornam
#VALUE!, PositionsTotal() ignora essas linhas, mas o usuário pode interpretar o total como correto. - Quando o critério é numérico e o intervalo contém texto, a contagem pode ser zero inesperadamente – um ponto contra‑intuitivo que costuma gerar dúvidas.
Objeções comuns
“E se eu precisar contar vários critérios ao mesmo tempo?” – a solução não é empilhar PositionsTotal(), mas usar uma tabela dinâmica ou combinar com SUMPRODUCT. Isso evita múltiplas chamadas de função e melhora a velocidade.
Próximo passo
Teste a função em um subconjunto da sua base. Se o tempo de cálculo ultrapassar 2 segundos, replique o critério em uma coluna auxiliar e use PIVOT para consolidar. Assim, você garante que a planilha continue responsiva enquanto extrai insights precisos.
Primeiros passos após a instalação
Abra o editor de scripts e carregue a biblioteca padrão. Em seguida, declare a função que irá chamar PositionsTotal() dentro do OnInit() para validar o ambiente:
int totalPosicoes; int OnInit() { totalPosicoes = PositionsTotal(); Print("Posições abertas: ", totalPosicoes); return(INIT_SUCCEEDED); } Se o retorno for 0, seu terminal está limpo. Qualquer número maior indica ordens pendentes ou executadas.
Configuração inicial – checklist operacional
- Verificar conta: Garanta que está conectado ao servidor correto (demo ou real).
- Habilitar histórico: Ative History Center para que
PositionsTotal()reflita todas as transações. - Sincronizar horário: Ajuste o fuso horário do MetaTrader para evitar discrepâncias de contagem.
- Definir filtro: Use
PositionSelect()antes de analisar detalhes (símbolo, tipo, lucro).
Rotina recomendada para monitoramento diário
Crie um script que rode a cada OnTick() ou OnTimer() (ex.: a cada 60 s). Isso garante que a contagem esteja sempre atualizada sem sobrecarregar a CPU.
| Etapa | Ação | Objetivo |
|---|---|---|
| 1 | Chamar PositionsTotal() | Obter número bruto de posições |
| 2 | Loop de for(i=0;i | Iterar cada posição |
| 3 | Aplicar filtros (symbol, magic number) | Isolar operações relevantes |
| 4 | Registrar métricas (lucro, stop loss, take profit) | Gerar base para análise de performance |
Erros comuns e como evitá‑los
- Contagem estática: chamar
PositionsTotal()apenas noOnInit()deixa o valor desatualizado. Solução: mover a chamada para um evento recorrente. - Confusão entre ordens e posições:
OrdersTotal()conta pedidos pendentes;PositionsTotal()conta apenas posições abertas. Use o método correto conforme a necessidade. - Limite de iterações: loops sem verificação de
PositionsTotal()podem gerar overflow se houver muitas posições simultâneas. Sempre reavaliar o total dentro do loop.
Produtividade prática – mini dashboard textual
Incorpore no seu Expert Advisor (EA) um painel simples que exiba:
string dashboard = "Posições: " + IntegerToString(PositionsTotal()) + "\nLucro total: " + DoubleToString(AccountInfoDouble(ACCOUNT_PROFIT),2) + "\nSpread médio: " + DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_SPREAD),1); Comment(dashboard); O Comment() aparece no canto superior da tela, permitindo monitorar em tempo real sem abrir janelas auxiliares.
Performance e escalabilidade
Em contas com mais de 200 posições simultâneas, a chamada direta a PositionsTotal() pode consumir até 0,8 ms por tick. Para reduzir esse impacto:
- Cache o resultado em uma variável global e atualize apenas quando
OnTrade()disparar. - Desative o modo visual refresh enquanto o script processa grandes volumes.
- Utilize
ArraySetAsSeries()para armazenar informações de posições em ordem cronológica, facilitando buscas binárias.
Com essas práticas, a latência permanece invisível ao trader, garantindo que a estratégia reaja instantaneamente.
Observação: a documentação oficial da MetaTrader sobre PositionsTotal() recomenda validar o retorno antes de usar índices, pois valores negativos indicam falha de chamada.
Perfil ideal e limitações de quem usa PositionsTotal()
Se você tem mais de um contrato aberto simultaneamente e depende de métricas precisas para gerenciar risco, PositionsTotal() pode ser seu aliado silencioso. Não é para quem faz day‑trade de um único ticker ou para quem se contenta com relatórios mensais genéricos.
Quem realmente tira proveito
- Traders que operam multi‑ativos (forex, commodities, ações) e precisam contar posições em tempo real.
- Desenvolvedores de EA que implementam filtros de sobreposição de ordens para evitar overexposição.
- Analistas de portfólio que extraem dados de histórico para calibrar algoritmos de alocação.
Quem provavelmente não encontrará valor
- Investidores “buy‑and‑hold” com pouca rotatividade de ordens.
- Usuários de plataformas que já disponibilizam dashboards com contagem automática.
- Quem não tem familiaridade com MQL4/5 e não pretende tocar no código.
Limitações práticas
O retorno da função é um int simples – nada de detalhes sobre lotes, ordem aberta ou preço médio. Em contas com centenas de posições, a chamada pode consumir ciclos de CPU perceptíveis; não é ideal para ciclos de 1 ms em HFT. Além disso, funciona apenas no lado cliente – servidores de corretoras que disfarçam posições residuais podem ocultar informações.
FAQ contextual
- Posso usar em contas sem “hedge”? Sim, a contagem inclui tanto posições netas quanto brutas.
- E se eu fechar a conta e abrir outra? A contagem reinicia; não há histórico persistente.
- Afeta o cálculo de swap? Indiretamente, pois o número de posições determina a taxa total de swap aplicada.
Checklist rápido antes de integrar
| Critério | Situação |
|---|---|
| Necessita de contagem em tempo real? | ✔️ |
| Volume de ordens > 50? | ✔️ |
| CPU disponível ≥ 10 % para chamadas MQL? | ⚠️ |
| Plano de fallback caso a função falhe? | ⚠️ |
Parecer editorial equilibrado
Em síntese, PositionsTotal() brilha quando seu workflow depende de um “contador” confiável para milhares de ordens – por exemplo, um robô que impede novas entradas ao atingir um limite predefinido. Se seu cenário é menos intensivo, a função se torna mais um detalhe trivial do que um diferencial competitivo. Não há magia; a precisão vem do próprio motor da corretora.
Mini cenários reais
- Scalper de EUR/USD – 30 posições simultâneas, usa
PositionsTotal()para limitar a 20; evita “cúspide de margem”. - Gestor de portfólio institucional – 120 contratos de energia; contagem serve para gerar alertas de diversificação automática.
Próximos passos: teste a função em ambiente demo por 48 h, monitorando uso de CPU. Se o consumo permanecer abaixo de 5 % e a contagem for consistente, inclua no seu EA. Caso contrário, procure alternativas como HistoryTotal() combinada com filtros de status.



