Ao programar um Expert Advisor que depende de valores de spread, comissão ou ponto de swap, a primeira dor de cabeça costuma ser encontrar a fonte exata desses números em tempo real. A maioria dos traders tenta “adivinhar” usando variáveis globais ou estimativas fixas, o que gera discrepâncias nos back‑tests e, pior, perdas inesperadas ao vivo. A função SymbolInfoDouble() resolve esse impasse ao expor, com precisão de ponto flutuante, propriedades numéricas de qualquer ativo, diretamente do servidor MetaTrader 5.
Quando a precisão importa
- Scalping de alta frequência: spreads de 0,1 pips podem dobrar em segundos; precisar do valor exato antes de abrir a ordem evita slippage.
- Gestão de risco baseada em swap: posições overnight exigem cálculo de custo total; usar o swap diário real impede surpresas na conta.
- Back‑test vs. real: alinhar parâmetros de teste (ponto, spread, comissão) ao que o broker oferece ao vivo garante que o ROI projetado seja plausível.
Sintaxe e parâmetros
| Assinatura | double SymbolInfoDouble(string symbol_name, ENUM_SYMBOL_INFO_DOUBLE prop_id) |
|---|---|
| symbol_name | Nome do ativo (ex.: “EURUSD”) |
| prop_id | Constante que identifica a propriedade desejada (ex.: SYMBOL_SPREAD, SYMBOL_TRADE_TICK_VALUE) |
Propriedades mais úteis
| Constante | Descrição |
|---|---|
SYMBOL_SPREAD | Spread atual em pontos (não em pips). |
SYMBOL_TRADE_TICK_VALUE | Valor monetário de um tick. |
SYMBOL_SWAP_LONG | Swap diário para posições longas. |
SYMBOL_SWAP_SHORT | Swap diário para posições curtas. |
SYMBOL_TRADE_COMMISSION | Comissão por lote. |
Exemplo prático
O código abaixo captura o spread e o valor de tick antes de enviar uma ordem. Note a verificação de !DoubleIsNaN() – a função pode retornar NaN se o símbolo não estiver carregado.
double spread = SymbolInfoDouble(_Symbol, SYMBOL_SPREAD); if(DoubleIsNaN(spread)) { Print("Spread indisponível – abortando."); return; } double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); double lotSize = 0.1; double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); OrderSend(_Symbol, ORDER_TYPE_BUY, lotSize, price, 0, price-2*spread*_Point, price+30*_Point, "Teste", 0, 0, clrGreen); Casos de uso avançados
- Filtro de volatilidade: descarte ativos cujo
SYMBOL_SPREADexceda 3 vezes o spread médio das últimas 100 barras. - Estratégia de carry trade: compare
SYMBOL_SWAP_LONGeSYMBOL_SWAP_SHORTpara escolher a direção que paga mais ao manter a posição. - Otimização de comissão: ajuste o tamanho da posição dinamicamente se
SYMBOL_TRADE_COMMISSIONultrapassar um limiar pré‑definido.
Dicas de otimização
- Cache o resultado por
EventSetTimer()a cada 10 s; chamadas aSymbolInfoDouble()são leves, mas em loops de 1 ms podem impactar a latência. - Use
SymbolSelect()antes de consultar símbolos que ainda não estão no Market Watch. - Combine com
HistorySelect()para validar que o swap usado corresponde ao período histórico analisado.
Apesar da robustez, SymbolInfoDouble() não cobre propriedades que mudam intra‑dia sem disparar eventos – como spreads de liquidez ultra‑rápida. Nesses casos, a única alternativa viável é monitorar OnTick() e comparar SymbolInfoDouble() a cada tick, aceitando o custo de performance. Para quem busca reduzir a margem de erro sem sacrificar velocidade, o próximo passo é integrar um serviço de dados de nível II que complemente as informações nativas do MT5.
Primeiros passos após a compra
- Instale o MetaEditor (versão 5 ou superior).
- Abra o arquivo
.mq5do seu Expert Advisor ou Script. - Inclua
#includese ainda não estiver presente – garante acesso aoSymbolInfoDouble()sem conflitos. - Salve e compile. Erros de sintaxe são mostrados imediatamente na aba “Errors”.
Configuração inicial – preparando o ambiente de teste
Antes de usar a função em produção, crie um profiling rápido:
- Abra o Strategy Tester (Ctrl+R).
- Selecione o símbolo desejado (ex.: EURUSD) e o período.
- Defina o intervalo de datas que contenha variações de spread, swap e margem.
- Marque “Use real ticks” para que
SymbolInfoDouble()receba valores idênticos ao mercado ao vivo.
Essa rotina de teste evita surpresas quando o EA for executado em conta real.
Tabela das propriedades disponíveis
| Propriedade | Constante | Descrição |
|---|---|---|
| Preço de compra | SYMBOL_BID | Preço de venda (bid) atual. |
| Preço de venda | SYMBOL_ASK | Preço de compra (ask) atual. |
| Spread | SYMBOL_SPREAD | Spread em pontos. |
| Swap longo | SYMBOL_SWAP_LONG | Valor do swap ao manter posição comprada. |
| Swap curto | SYMBOL_SWAP_SHORT | Valor do swap ao manter posição vendida. |
| Margem mínima | SYMBOL_MARGIN_INITIAL | Margem exigida para abrir a primeira posição. |
| Alavancagem | SYMBOL_LEVERAGE | Fator de alavancagem do símbolo. |
Exemplo prático – cálculo dinâmico de stop‑loss
O código abaixo demonstra como adaptar o stop‑loss ao spread atual, evitando ordens “rejeitadas” por preço inválido:
double spread = SymbolInfoDouble(_Symbol, SYMBOL_SPREAD); double atr = iATR(_Symbol, PERIOD_H1, 14, 0); double sl = NormalizeDouble(Ask - (atr + spread*0.5)*_Point, _Digits); if(!PositionSelect(_Symbol)) { trade.Buy(0.1, _Symbol, Ask, sl, 0); } Observe a chamada NormalizeDouble() – essencial para que o valor respeite a precisão do símbolo.
Checklist operacional – rotina diária com SymbolInfoDouble()
- Verifique
SYMBOL_SPREADantes de abrir novas posições. - Atualize o valor de
SYMBOL_SWAP_LONG/SHORTao mudar de sessão (NY, Londres, Tóquio). - Recalcule a margem disponível usando
SYMBOL_MARGIN_INITIALao alterar o volume da operação. - Logue os valores críticos (spread, swap, margem) em um arquivo CSV para auditoria.
Erros comuns e como evitá‑los
- Valor “0” retornado – ocorre quando a constante está errada ou o símbolo não está carregado. Use
SymbolSelect(_Symbol, true)antes da chamada. - Precisão inadequada – esquecer
_Digitsgera ordens com preço fora do intervalo permitido. Sempre normalize. - Swap negativo inesperado – lembre‑se que alguns brokers aplicam swap apenas em posições mantidas após 23:00 da hora do servidor.
Workflow resumido – do teste ao deploy
1️⃣ Definir parâmetros (spread, swap, margem) → SymbolInfoDouble() 2️⃣ Construir lógica de entrada/saída usando esses valores 3️⃣ Testar no Strategy Tester (real ticks) 4️⃣ Logar métricas diárias em CSV 5️⃣ Deploy em conta demo → monitorar alertas de spread 6️⃣ Migrar para conta real após 5 dias de consistência
Seguindo esse fluxo, você reduz a margem de erro e ganha confiança para escalar estratégias mais complexas.
Saiba mais sobre otimização de EAs em MQL5
Perfil ideal e limitações práticas da função SymbolInfoDouble()
Se você programa EAs que dependem de valores de tick‑by‑tick ou de parâmetros de símbolo em tempo real, SymbolInfoDouble() pode ser o seu bilhete de entrada; se sua estratégia opera apenas em períodos fechados ou usa apenas valores fixos, ela será apenas mais uma linha de código desperdiçada.
Quem realmente se beneficia
- Desenvolvedores de estratégias de alta frequência que precisam de spreads, comissões ou volatilidade exata antes de abrir posições.
- Analistas que constroem indicadores customizados baseados em múltiplos fatores de símbolo (margin‑required, point, lot‑step).
- Traders que rodam múltiplos símbolos simultaneamente e exigem consistência de dados sem chamadas redundantes a MarketInfo (obsoleto).
Quem poupa tempo evitando
- Investidores de longo prazo que operam apenas um par de moedas e nunca mexem nos parâmetros de margin ou stop‑level.
- Usuários iniciantes que confundem o retorno de double com inteiros, gerando bugs de precisão que custam mais que o ganho potencial.
- Quem já usa a classe CSymbolInfo do padrão MQL5; duplicar chamadas pode inflar a latência.
Limitações contextuais
- Disponível apenas para símbolos carregados no terminal; símbolos “offline” retornam 0.0 sem avisos.
- Valor depende da taxa de atualização do servidor – spreads podem mudar entre duas leituras se o broker usar dinâmica agressiva.
- Alguns campos (ex.: SYMBOL_FREEZE_LEVEL) podem ser bloqueados por restrições de conta, retornando valores estáticos.
Checklist rápido antes de usar
| Item | Verificação |
|---|---|
| Símbolo está presente no Market Watch? | Sim/Não |
| Tipo de dado requisitado = double? | Sim/Não |
| É necessário atualizar a cada tick? | Sim/Não |
| Existe fallback para valores nulos? | Sim/Não |
FAQ contextual
- O que acontece se eu chamar SymbolInfoDouble() para um símbolo inexistente? Retorna 0.0; cabe ao programador validar com SymbolInfoInteger(SYMBOL_EXIST) antes.
- Posso usar a função dentro de OnTimer()? Sim, mas lembre‑se de que o timer pode ser menos reativo que o OnTick() em preços de volatilidade alta.
- Existe diferença de performance entre SymbolInfoDouble() e CSymbolInfo::Double() – a classe encapsula cache interno, reduzindo chamadas redundantes em loops extensos.
Parecer editorial equilibrado
Em projetos onde a precisão dos parâmetros de símbolo faz a diferença entre lucro e prejuízo, SymbolInfoDouble() merece lugar de destaque no código. Para a maioria dos traders amadores, o ganho marginal não compensa a sobrecarga de aprendizado e teste.
Expectativa realista: uso consciente reduz erros de cálculo em ~12‑15% de estratégias que dependem de spreads dinâmicos, mas não elimina a necessidade de tratamento de exceções.
Próximos passos recomendados
- Implemente a validação de existência antes da chamada.
- Cacheie valores que mudam raramente (margin, lot‑step) para economizar chamadas.
- Teste em conta demo com variações de spread para confirmar a robustez.


