Programar indicadores ou robôs em MQL5 costuma envolver vetores simples, mas rapidamente esbarramos em situações que exigem mais de uma dimensão – por exemplo, armazenar preços de múltiplos símbolos ao longo de várias barras ou cruzar matrizes de parâmetros de otimização. O ponto de dor típico é que a sintaxe parece arcaica e a depuração, pouco intuitiva. Se você já tentou declarar double matriz[10][5]; e acabou com “array out of range”, este texto mostra, passo a passo, como transformar essa frustração em código funcional e escalável.
Declaração prática e armadilhas comuns
Em MQL5 a matriz multidimensional deve ter todas as dimensões definidas no momento da declaração. O erro mais frequente é omitir o tamanho da primeira dimensão, confiando que o compilador a inferirá – o que nunca acontece.
- Correto:
double preco[SymbolCount][Bars]; - Errado:
double preco[][Bars];
Além disso, lembre‑se de que o índice começa em 0. Um loop que vai de i = 1 a i <= SymbolCount vai estourar a matriz.
Manipulação segura
Para percorrer a matriz use dois loops aninhados, sempre verificando limites:
| Loop | Descrição |
|---|---|
for(i=0;i | Itera sobre símbolos |
for(j=0;j | Itera sobre barras |
Um truque contra‑intuitivo: ao precisar copiar uma linha inteira para outra matriz, prefira ArrayCopy ao invés de atribuir célula a célula – ganha velocidade e evita “off‑by‑one”.
Exemplo real: cruzamento de médias em três ativos
Suponha que queira comparar a média móvel de 20 períodos de EURUSD, GBPUSD e USDJPY nas últimas 100 barras. O código abaixo cria a matriz, preenche e gera um alerta quando todas as três médias estão acima da média de 50 períodos.
int symbols=3; int bars=100; double ma20[symbols][bars]; double ma50[symbols][bars]; string symb[3]={"EURUSD","GBPUSD","USDJPY"}; for(int s=0;sma50[0][b] && ma20[1][b]>ma50[1][b] && ma20[2][b]>ma50[2][b]) Alert("Convergência de alta nas 3 moedas na barra ",b); } Note a verificação de limites antes de acessar ma20[2][b]. Qualquer tentativa de ler ma20[3][b] geraria um erro de compilação.
Quando a matriz falha
Se o número de símbolos ou de barras varia dinamicamente, matrizes estáticas tornam‑se inviáveis. Nesses casos, migre para ArrayResize ou use struct contendo double[] dinâmicos. O custo é perda de acesso direto (índices duplos) e aumento de complexidade de código.
FAQ rápido
- Posso usar
intcomo índice? Sim, mas prefirauintquando não houver valores negativos. - Qual o limite de tamanho? Cada dimensão tem limite de 2 147 483 647 elementos, porém a memória disponível no terminal costuma ser o gargalo.
- ArrayCopy funciona em 2D? Não diretamente; copie linha a linha ou use um loop interno.
Dominar matrizes multidimensionais abre caminho para estratégias de correlação, otimizações paralelas e backtests mais robustos. Se quiser aprofundar, consulte a documentação oficial da MQL5 – vale a pena ler a seção sobre Array handling antes de implementar a próxima ideia.
Primeiros passos após adquirir o código
- Abra o MetaEditor (Ctrl+F4) e crie um novo .mq5 em
Experts → MyExperts. - Copie a estrutura básica da matriz:
int matrix[3][5]; // 3 linhas, 5 colunasSalve e compile. Se houver erros, o console mostrará a linha exata – corrija antes de prosseguir.
Configuração inicial da matriz
- Definir tamanho dinamicamente usando
ArrayResize:
// 2 dimensões: linhas=10, colunas=4 ArrayResize(matrix,10); ArrayResize(matrix,4,0); // 0 = mesma dimensão anterior- Inicializar valores com loops aninhados:
for(int i=0;iManipulação avançada – leitura e escrita
- Obter um elemento:
int val=matrix[2][3]; - Alterar em tempo real (ex.: dentro de
OnTick()):
void OnTick() { static int cnt=0; matrix[0][cnt%ArrayRange(matrix,1)]=Close[0]; cnt++; }Este padrão preenche a primeira linha com o preço de fechamento mais recente, girando a coluna a cada tick.
Workflow recomendado – checklist operacional
| Etapa | Ação | Resultado esperado |
|---|---|---|
| 1 | Declarar matriz estática ou dinâmica | Memória alocada corretamente |
| 2 | Inicializar com ArrayInitialize ou loops | Todos os elementos com valor base |
| 3 | Implementar leitura/escrita nos eventos (OnInit, OnTick) | Dados atualizados em tempo real |
| 4 | Testar em Strategy Tester (modo visual) | Sem erros de acesso fora dos limites |
| 5 | Optimizar usando ArraySetAsSeries quando necessário | Performance maximizada |
Erros comuns e como evitá‑los
- Index out of range – sempre usar
ArrayRange(matrix,dim)para validar índices. - Confusão entre linhas e colunas – lembre‑se que a primeira dimensão representa linhas.
- Não liberar memória em scripts de longa execução – chame
ArrayFree(matrix)ao final.
Aplicações práticas
Com matrizes multidimensionais você pode:
- Armazenar histórico de indicadores (ex.: 10 períodos × 4 indicadores).
- Construir tabelas de correlação entre pares de moedas.
- Implementar algoritmos de otimização que exigem matrizes de parâmetros.
⚠️ Dica de produtividade: combine
ArrayCopycomArraySetAsSeriespara transformar rapidamente séries temporais em colunas de matriz.
FAQ rápido
- Posso usar
doubleem vez deint? Sim. Basta declarardouble matrix[][];e ajustar as funções de inicialização. - Qual o limite máximo de tamanho? Depende da memória disponível; em contas padrão, matrizes acima de 10 000 × 10 000 podem causar falhas.
- Existe suporte nativo para 3D? Não diretamente, mas pode aninhar
ArrayResizeduas vezes para simular.
Para aprofundar, consulte a documentação oficial do MQL5. Ela traz exemplos prontos e boas práticas de gerenciamento de memória.
Perfil ideal e limitações práticas
Se você é trader que já domina a lógica de programar indicadores e robôs em MQL5, mas ainda sente que seus códigos “esmagam” dados complexos, este guia sobre matrizes multidimensionais pode ser a ponte que falta.
Não é para quem ainda está enrolado nas bases de eventos OnTick ou na sintaxe básica de variáveis simples. Quem ainda luta para compilar “int x[10];” vai desperdiçar tempo lendo explicação avançada de ponteiros e indireções.
Quem deve usar
- Desenvolvedores que precisam armazenar séries históricas de múltiplos símbolos simultaneamente.
- Analistas que criam algoritmos de correlação cruzada entre pares de moedas, commodities ou índices.
- Programadores que pretendem implementar grids ou redes de estratégias (grid trading, hedging).
Quem não terá bom aproveitamento
- Iniciantes que ainda não compreendem a diferença entre Series e Buffers.
- Quem faz apenas estratégias “one‑shot”, sem necessidade de armazenar mais de duas dimensões.
- Operadores que dependem exclusivamente de scripts predefinidos da comunidade.
Limitações contextuais
Memória: cada camada adicional de índices multiplica o consumo de RAM. Em um terminal padrão de 2 GB, matrizes 3×3×10000 podem estourar o limite e causar crash.
Desempenho: loops aninhados sobre matrizes grandes são penalizados pelo interpretador MQL5; a otimização com “ArraySetAsSeries” e “ArrayResize” ainda deixa a latência latente.
Portabilidade: código que explora recursos avançados de ponteiros (malloc, memcpy) dificulta a migração para MetaTrader 4 ou outras plataformas.
FAQ contextual
| Pergunta | Resposta |
|---|---|
| Posso usar matrizes 4D? | Sim, a sintaxe permite, mas o consumo de memória cresce exponencialmente; raramente é justificável. |
| Existe limite de tamanho? | Praticamente 2 147 483 647 elementos por dimensão, limitado pela memória disponível. |
| Como depurar valores? | Use PrintFormat("%f", matriz[i][j]); ou a ferramenta de inspeção de arrays no MetaEditor. |
Checklist de decisão
- Preciso comparar >2 séries simultâneas? Sim → Matrizes.
- Meu algoritmo roda em timeframe M1? Reavalie o custo de memória.
- Tenho acesso a VPS com >8 GB RAM? Vai tolerar o overhead.
Parecer editorial equilibrado
O conteúdo entrega a base necessária para quem deseja “escalar” seus robôs. Não promete milagres; deixa claro que a curva de aprendizado se materializa em prática constante.
Para quem já lida com arrays simples, o salto para estruturas multidimensionais gera ganho real de organização e reduz bugs de indexação. Porém, se seu negócio se resume a um único par de moedas, o esforço pode ser desnecessário.
Mini cenários reais
Trader A – usa duas dimensões para armazenar preços de EURUSD e GBPUSD ao longo de 5000 barras. Resultado: estratégia de spread mais limpa, sem múltiplas chamadas a CopyRates.
Trader B – tentou três dimensões para cruzar 5 pares e 3 indicadores simultâneos. O script consumiu 1,8 GB e travou no back‑test de 1 ano. Reduzir para duas dimensões e recalcular indicadores on‑the‑fly resolveu.
Próximos passos
Teste a implementação em um demo com cópia limitada antes de migrar para produção. Monitore uso de memória via “Terminal → Histórico”. Caso ultrapasse 70 % da RAM disponível, simplifique a estrutura.
Em resumo, se você tem o perfil de desenvolvedor avançado, orçamento de hardware adequado e necessidade de manipular dados em camadas, as matrizes multidimensionais são um trunfo. Caso contrário, mantenha o código plano e foque em otimizações de lógica.



