Do iniciante ao especialista: Reporting EA - Configuração do fluxo de trabalho
Sumário:
- Introdução
- Conhecendo os relatórios de negociação em MQL5
- Implementação
- Testes
- Conclusão
- Principais aprendizados
- Conteúdo do anexo
Introdução
A ideia de desenvolver esta abordagem surgiu quando comecei a receber diariamente, por e-mail, confirmações de operações da minha corretora. Esses resumos apresentavam uma visão clara e profissional da atividade de negociação e destacavam o potencial para a análise estatística do desempenho. Ao explorar o terminal MetaTrader 5, descobri que sua versão atual conta com uma ferramenta abrangente para geração de relatórios, capaz de exportar relatórios detalhados tanto no formato HTML quanto no formato PDF. No entanto, ela não dispõe de funcionalidades para envio automático de relatórios nem para gerenciamento centralizado. Neste artigo, buscamos examinar o papel dos relatórios de negociação, esclarecer os principais termos que eles contêm e destacar sua importância prática para qualquer trader que queira tomar decisões bem fundamentadas.
Nosso objetivo final é implementar um sistema de relatórios personalizado usando MQL5 em conjunto com Python e outras ferramentas externas. Essa solução gerará relatórios detalhados, garantirá compatibilidade com vários formatos de arquivo e oferecerá suporte ao envio automatizado por meio de métodos práticos e confiáveis.
Depois de analisar os documentos exportados do MetaTrader 5, ficou claro que eles contêm informações valiosas e métricas previamente calculadas, que fornecem aos traders uma visão matemática de seus resultados; essas informações podem influenciar diretamente as decisões de negociação e os ajustes de comportamento.
Atualmente, os relatórios no MetaTrader 5 geralmente podem ser obtidos por meio de navegação manual. No entanto, ao trabalhar com EAs, temos a possibilidade de controlar programaticamente a geração e o envio desses relatórios. Embora algumas corretoras já os enviem automaticamente, nosso objetivo nesta discussão é desenvolver um sistema que permita agendar o envio dos relatórios de acordo com nossas próprias preferências, personalizando tanto a frequência quanto o conteúdo.
Ao desenvolver essa solução, analisaremos a importância prática dos relatórios de negociação com base em uma experiência pessoal. Também examinaremos os termos comuns encontrados nesses relatórios e discutiremos como eles podem ser usados para melhorar tanto estratégias de negociação manual quanto a avaliação de desempenho de EAs.
No MetaTrader 5, é possível acessar os relatórios de negociação selecionando "Relatórios" no menu "Exibir" ou usando o atalho Alt+E. A janela do relatório exibe diferentes aspectos da sua atividade de negociação em um formato claro e bem estruturado. Nessa janela, você também pode salvar seus relatórios em formato HTML ou PDF, como mostrado na figura abaixo:

Acessando os relatórios da conta no terminal MetaTrader 5
A ilustração acima mostra alguns dos principais componentes normalmente encontrados nos relatórios de negociação. Embora essas informações sejam muito valiosas, muitos traders tendem a se concentrar exclusivamente nos gráficos e na execução das operações, muitas vezes deixando de revisar periodicamente seus relatórios de desempenho. É essencial desenvolver uma compreensão clara desses relatórios, pois isso fortalece a disciplina e contribui para uma mentalidade de trading mais saudável, ao permitir aprender com o histórico de negociação.
Depois de me familiarizar com meu relatório de negociação, tomei a iniciativa de estudar os principais termos contidos nele e reuni anotações com exemplos práticos para facilitar a compreensão. Na próxima seção, você encontrará cinco tópicos estruturados, cada um com uma explicação concisa, mas informativa. Elas servem de base para o plano de implementação que veremos mais adiante neste artigo. Quando chegarmos à etapa de desenvolvimento técnico, o objetivo é garantir uma compreensão clara desses conceitos relacionados aos relatórios. Se você já estiver familiarizado com eles, pode avançar diretamente para a etapa de implementação.
Conhecendo os relatórios de negociação em MQL5
1. Resumo dos resultados de desempenho
Retorno sobre o investimento (ROI):
- Mede quanto o saldo da conta aumenta em relação ao capital inicial.
- Considere um capital inicial de 5.000 dólares e um saldo final de 12.000 dólares. Isso representa um aumento de 140%, ou seja, cada dólar colocado em risco se transforma em 2,40 dólares.
Drawdown:
- Registra a queda percentual mais acentuada desde a máxima até a mínima subsequente.
- Imagine que o capital atinja um pico de 12.000 dólares e depois caia para 9.600 dólares, uma queda de 20%, o que indica o recuo mais profundo antes da recuperação.
Indicadores de atividade:
- Refletem o ritmo e a consistência da negociação: número de operações por semana, percentual de operações vencedoras e duração média da posição.
- Como exemplo, realizar 80 operações ao longo de oito semanas resulta em 10 operações por semana; obter lucro em 32 delas gera uma taxa de acerto de 40%; e um tempo total de exposição ao mercado de 160 dias corresponde a uma média de 2 dias.
Índice de Sharpe:
- Indica quanto retorno excedente foi obtido para cada unidade de volatilidade assumida.
- Para ilustrar, compare dois sistemas que geram 15% ao ano: aquele que oscila ±2% ao dia terá um índice de Sharpe significativamente maior do que o que oscila ±6%, refletindo uma curva de capital mais suave.
Fator de lucro:
- Expressa o lucro bruto dividido pelo prejuízo bruto para mostrar a eficiência das operações vencedoras em relação às perdedoras.
- Tomemos, por exemplo, operações lucrativas no valor de 8.000 dólares contra operações com prejuízo no valor de 5.000 dólares, o que resulta em uma razão de 1,6. Assim, cada dólar perdido é compensado por 1,60 dólar de lucro.
Fator de recuperação:
- Compara o lucro líquido com o maior drawdown observado.
- Suponha que uma estratégia gere lucro de 4.000 dólares e, no pior caso, perca 1.000 dólares. Um fator de recuperação igual a 4 indica que o lucro foi quatro vezes maior que a maior perda.
2. Detalhamento de lucros e perdas
Lucro bruto e perda bruta:
- Os totais das operações lucrativas e das operações com prejuízo compõem o resultado bruto antes da dedução dos custos.
- Por exemplo, lucro de 15.000 dólares contra prejuízos de 6.000 dólares gera um saldo positivo de 9.000 dólares.
Comissões e lucro líquido:
- A dedução de comissões, swaps e outras taxas dos resultados brutos mostra o lucro real.
- Para dimensionar isso, subtraia 1.200 dólares em comissões de um lucro de 9.000 dólares e obtenha lucro líquido de 7.800 dólares.
Tendências mensais:
- Traçar gráficos dos resultados líquidos mês a mês mostra variações no desempenho.
- Por exemplo, um aumento de 4.000 dólares em janeiro, de 3.000 dólares em fevereiro, de 800 dólares em março e uma queda de 500 dólares em abril indicam uma tendência de queda que exige atenção.
3. Análise de risco
Drawdown máximo:
- Identifica a maior queda percentual desde o pico até a mínima subsequente.
- Imagine que sua conta tenha caído de 20.000 para 14.000 dólares e depois se recuperado; no pior caso, a queda foi de 30%.
Lucros e perdas consecutivos:
- As séries mais longas de resultados positivos ou negativos testam tanto a estabilidade do sistema quanto a psicologia do trader.
- Imagine sofrer sete perdas seguidas e depois obter cinco operações lucrativas consecutivas; cada sequência afeta a confiança, a disciplina e o tamanho da posição.
Excursão Máxima Favorável (MFE):
- Acompanha o maior lucro não realizado alcançado ao longo da operação.
- Para ilustrar, uma posição pode subir 600 dólares até seu pico antes que alguma ordem de saída seja acionada.
Excursão Máxima Adversa (MAE):
- Registra a maior perda não realizada incorrida antes do fechamento.
- Considere que a mesma operação pode cair 200 dólares antes de fechar com lucro, indicando pontos em que um ajuste no stop-loss pode ser útil.
4. Desempenho por instrumento/símbolo
Taxa de acerto por ativo:
- O percentual de acerto em cada mercado mostra onde a vantagem é mais forte.
- Por exemplo, o par EURUSD pode gerar lucro em 48% das operações, enquanto o par USDJPY gera lucro em 60%, indicando sinais mais fortes no USDJPY.
Contribuição ao lucro:
- O lucro líquido discriminado por instrumento mostra de onde o lucro realmente vem.
- Tomemos, por exemplo, o caso em que o EURUSD contribui com 9.600 dólares para o total, enquanto o XAUUSD reduz esse resultado em 1.100 dólares, orientando a alocação de recursos.
Risco de concentração:
- Mostra a parcela do capital ou o número de operações vinculadas a um único mercado.
- Suponha que 40% do capital esteja alocado no par EURUSD; uma mudança repentina na cotação do euro pode afetar o resultado geral de forma desproporcional.
Fator de lucro por instrumento:
- Compara os lucros e perdas totais de cada mercado, permitindo avaliar a eficiência com mais precisão.
- Para ilustrar, o par USDJPY pode apresentar um fator de 1,8, enquanto o AUDCAD fica em 0,9, indicando quais pares devem ser priorizados e quais devem ser evitados.
5. Atividade e padrões comportamentais
Distribuição das operações:
- O equilíbrio entre posições longas e curtas mostra o viés direcional.
- Por exemplo, manter 70% das posições compradas sugere um viés predominantemente altista, que pode enfraquecer em mercados laterais.
Automação versus operação manual:
- Comparar operações algorítmicas com operações manuais mostra onde está a verdadeira vantagem.
- Basta considerar que 65% do lucro líquido vem de operações automatizadas e 35% de operações manuais, o que destaca a robustez do sistema.
Análise temporal:
- O detalhamento dos resultados por hora e por dia da semana permite identificar períodos ideais e vulneráveis.
- Por exemplo, a maioria das perdas pode ocorrer entre 11:00 e 12:00 GMT, indicando que é melhor evitar o período do almoço.
Métricas de estilo:
- A abordagem é definida pela duração média da posição e pelo volume semanal de negociação.
- Para ilustrar, uma duração média da posição de quatro horas, combinado com cerca de 25 operações por semana, caracteriza uma estratégia intradiária de ritmo moderado.
Implementação
Nesta etapa, começamos a configurar nosso fluxo de trabalho. Com base na seção anterior, em que analisamos em detalhes a terminologia dos relatórios de negociação, será mais fácil entender esta parte, pois ela apresenta menos conceitos novos.
Para atingir o objetivo deste artigo, desenvolveremos um EA que processa a exportação de dados e gera os logs necessários. Esse EA servirá como elo entre o MetaTrader 5 (MQL5) e as bibliotecas Python responsáveis pelo processamento dos dados históricos de negociação e pela geração do relatório final em formato portátil, de modo semelhante às ferramentas de relatório integradas ao terminal MetaTrader 5.
Começaremos apresentando um fluxograma que descreve todo o fluxo, seguido de um detalhamento das ferramentas e configurações de ambiente necessárias para colocar tudo em funcionamento. Todos os componentes deste projeto são baseados em tecnologias de código aberto, garantindo acessibilidade para todos.

Fluxo operacional do Reporting EA
Para começar, certifique-se de que o MetaTrader 5 esteja instalado no seu sistema. Depois, configure o ambiente Python, que explicarei em detalhes mais adiante. Uma lista simplificada dos requisitos e ferramentas usados neste fluxo de trabalho é apresentada na tabela abaixo.
| Componente | Ferramentas de código aberto | Custo | Notas de implementação |
|---|---|---|---|
| Extração de dados | EA do MetaTrader 5 (ReporterEA.mq5) | Gratuito | Exportação personalizada para CSV com filtragem por intervalo de datas |
| Mecanismo de agendamento | Eventos de timer do MetaTrader 5 (OnTimer()) | Gratuito | Agendamento interno no terminal MetaTrader 5 |
| Processamento | Python 3.10+ (Pandas, Matplotlib) | Gratuito | Executado pelo EA por meio de ShellExecute |
| Envio do relatório | smtplib + Gmail SMTP | Gratuito | Vários envios gratuitos de e-mail por dia a partir do script Python |
| Manutenção | Funções de limpeza automática do EA | Gratuito | Rotação de arquivos e tratamento de erros em MQL5/Python |
Desenvolvimento do Reporting EA
Nesta etapa, começamos o desenvolvimento do EA de acordo com o plano. Vou explicar cada componente do código, mostrando como eles funcionam em conjunto para formar um sistema coeso e funcional. O objetivo é criar um EA confiável, capaz de executar sua função sem problemas. Acompanhe enquanto dividimos o desenvolvimento em etapas claras e gerenciáveis, garantindo que cada elemento seja fácil de entender e contribua de forma significativa para o produto final.
No MetaEditor 5, abra um novo arquivo e selecione o modelo "Expert". Recomendo remover todas as seções do código gerado automaticamente que não estejam alinhadas com nossos objetivos atuais de desenvolvimento, para que possamos nos concentrar apenas no que importa. Siga as etapas numeradas abaixo para começarmos a criar o EA passo a passo.
1. Metadados do arquivo e instruções de compilação
Na parte superior do arquivo, as diretivas #property declaram os metadados do EA. Essas propriedades incluem dados de copyright e links exibidos no campo "Sobre" do terminal MetaTrader 5, além do número da versão e do modo de compilação estrito. O modo estrito impõe regras mais rigorosas de checagem de tipos e compilação, ajudando a evitar erros sutis ao proibir conversões implícitas de tipo e exigir conversões explícitas.
#property copyright "Clemence Benjamin" #property link "https://www.mql5.com/go?link=https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property strict
2. Importação de constantes e da Windows API
As diretivas #define criam nomes simbólicos para constantes usadas com frequência (SW_HIDE para ocultar janelas de console e INVALID_FILE_ATTRIBUTES para verificar erros). Depois disso, o código importa duas bibliotecas do sistema Windows usando #import: kernel32.dll para funções relacionadas a atributos de arquivos (GetFileAttributesW) e shell32.dll para executar processos externos (ShellExecuteW). Ao chamar essas funções nativas das DLLs, o EA amplia as capacidades nativas do MetaTrader 5 para verificar a existência de arquivos e iniciar o interpretador Python.
#define SW_HIDE 0 #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF //--- Windows API imports #import "kernel32.dll" uint GetFileAttributesW(string lpFileName); #import #import "shell32.dll" int ShellExecuteW(int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd); #import
3. Parâmetros de entrada do usuário para configuração
A seção de parâmetros de entrada exibe as opções configuráveis na janela de configurações do EA. Os usuários podem especificar o caminho absoluto para o executável do Python (PythonPath), o script Python a ser executado (ScriptPath), a hora e o minuto em que o relatório diário deve ser gerado (Reportthour, ReportMinute), se o envio de notificações estará habilitado (EnableEmail) e se uma execução de teste será realizada na inicialização (TestOnInit). Usá-los como parâmetros de entrada permite que usuários não programadores alterem o comportamento sem editar o código-fonte.
//--- User inputs input string PythonPath = "C:\\Users\\BTA24\\AppData\\Local\\Programs\\Python\\Python312\\python.exe"; input string ScriptPath = "C:\\Users\\BTA24\\Documents\\BENJC_TRADE_ADVISOR\\Scripts\\processor.py"; input int ReportHour = 15; // Hour (24h) to run report input int ReportMinute = 55; // Minute after the hour input bool EnableEmail = true; // Send push notification input bool TestOnInit = true; // Immediately run export+Python on init
4. Gestão do estado global
A única variável global, lastRunTime, armazena o timestamp da última execução bem-sucedida do relatório. Ao comparar TimeCurrent() com lastRunTime, o EA garante que o relatório seja gerado apenas uma vez a cada 24 horas, embora o callback de timer seja executado com mais frequência.
//--- Globals datetime lastRunTime = 0;
5. Lógica de inicialização (OnInit)
A função OnInit() executa todos os procedimentos de inicialização. Primeiro, ela exibe mensagens de status no log do EA. Verifica os atributos dos arquivos do executável do Python e do script Python e exibe avisos caso eles não existam. Em seguida, verifica as permissões de gravação criando um arquivo fictício, gravando nele, fechando-o e removendo-o no diretório MQL5\Files. Depois, configura um evento de timer recorrente a cada 30 segundos usando EventSetTimer(30). Por fim, se TestOnInit estiver definido como true, ela chama imediatamente RunDailyExport() para testar todo o fluxo de exportação e execução do Python, registrando o horário atual em lastRunTime.
int OnInit() { Print(">> Reporting EA initializing…"); // Verify Python executable if(GetFileAttributesW(PythonPath) == INVALID_FILE_ATTRIBUTES) Print("!! Python executable not found at: ", PythonPath); else Print("✔ Found Python at: ", PythonPath); // Verify Python script if(GetFileAttributesW(ScriptPath) == INVALID_FILE_ATTRIBUTES) Print("!! Python script not found at: ", ScriptPath); else Print("✔ Found script at: ", ScriptPath); // Test write permission int h = FileOpen("test_perm.txt", FILE_WRITE|FILE_COMMON|FILE_ANSI); if(h==INVALID_HANDLE) Print("!! Cannot write to MQL5\\Files directory!"); else { FileWrite(h, "OK"); FileClose(h); FileDelete("test_perm.txt"); Print("✔ Write permission confirmed."); } // Set timer EventSetTimer(30); Print(">> Timer set to 30 seconds."); // Test run on init if(TestOnInit) { Print(">> Test mode: running initial export."); RunDailyExport(); lastRunTime = TimeCurrent(); } return(INIT_SUCCEEDED); }
6. Lógica de desinicialização (OnDeinit)
Quando o EA é removido ou a plataforma é encerrada, a função OnDeinit() é chamada. Sua única responsabilidade é fazer a limpeza desativando o timer (EventKillTimer()) e registrando uma mensagem de desinicialização. A liberação correta dos recursos do timer evita callbacks pendentes e possíveis falhas.
void OnDeinit(const int reason) { EventKillTimer(); Print(">> Reporting EA deinitialized."); }
7. Callback do timer para agendamento (OnTimer)
A cada 30 segundos, OnTimer() é executada e extrai a hora e o minuto atuais usando a estrutura MqlDateTime. Ela verifica se o horário atual corresponde ao horário configurado do relatório (ReportHour, ReportMinute), ou se já passou dele, e se pelo menos 86.400 segundos (24 horas) se passaram desde lastRunTime. Essa dupla verificação garante que o relatório seja gerado uma vez por dia, no minuto agendado ou depois dele.
void OnTimer() { MqlDateTime dt; TimeToStruct(TimeCurrent(), dt); if(dt.hour==ReportHour && dt.min>=ReportMinute && (TimeCurrent()-lastRunTime)>86400) { RunDailyExport(); lastRunTime = TimeCurrent(); } }
8. Rotinas principais: exportação e chamada do Python (RunDailyExport)
- Esta função inclui as principais etapas da rotina de geração de relatórios do EA.
- Calcula o caminho absoluto para o diretório MQL5\Files no MetaTrader 5 usando TerminalInfoString.
- Cria nomes de arquivos com data no nome tanto para o arquivo CSV exportado quanto para o arquivo de log, formatando a data atual e removendo os pontos.
- Chama a função ExportHistoryToCSV() para gravar o histórico de operações dos últimos 30 dias em um arquivo CSV. Se isso falhar, a função é interrompida.
- Cria uma linha de comando que chama o interpretador Python com o script e o nome do arquivo CSV, redirecionando tanto a saída padrão quanto o erro padrão para o arquivo de log. A formatação de strings e StringFormat garantem que caminhos contendo espaços sejam corretamente colocados entre aspas.
- Chama o wrapper ShellExecute() do EA para iniciar cmd.exe /c <pythonCmd>, capturando o código de retorno inteiro para o log de diagnóstico.
- Faz uma pausa de 3 segundos com Sleep(3000) para permitir que o processo Python externo seja concluído.
- Verifica a existência do arquivo de log e, em seguida, lê e exibe seu conteúdo linha por linha no log do EA.
- Por fim, cria uma notificação com um breve resumo do caminho do arquivo CSV e, se estiver habilitada, envia essa notificação para os terminais móveis do usuário usando a função sendNotification().
void RunDailyExport() { string filesDir = TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Files\\"; string dateStr = TimeToString(TimeCurrent(), TIME_DATE); StringReplace(dateStr, ".", ""); string csvName = "History_" + dateStr + ".csv"; string logName = "ProcLog_" + dateStr + ".txt"; string csvFull = filesDir + csvName; string logFull = filesDir + logName; // 3) Export CSV if(!ExportHistoryToCSV(csvName)) { Print("!! CSV export failed: ", csvFull); return; } Print("✔ CSV exported: ", csvFull); // 4) Build Python command string pythonCmd = StringFormat( "\"%s\" \"%s\" \"%s\" >> \"%s\" 2>&1", PythonPath, ScriptPath, csvFull, logFull ); string fullCmd = "/c " + pythonCmd; PrintFormat("→ Launching: cmd.exe %s", fullCmd); // 5) Execute int result = ShellExecute(" " + fullCmd); PrintFormat("← ShellExecute returned: %d", result); // 6) Wait Sleep(3000); // 7) Read log if(GetFileAttributesW(logFull) == INVALID_FILE_ATTRIBUTES) Print("!! Log file not created: ", logFull); else { Print("=== Python Log Start ==="); int fh = FileOpen(logName, FILE_READ|FILE_COMMON|FILE_TXT); while(fh!=INVALID_HANDLE && !FileIsEnding(fh)) Print("PY: ", FileReadString(fh)); if(fh!=INVALID_HANDLE) FileClose(fh); Print("=== Python Log End ==="); } // 8) Notification string msg = "Report & log generated: " + csvFull; Print(msg); if(EnableEmail) SendNotification(msg); }
9. Geração de arquivos CSV (ExportHistoryToCSV)
Essa função auxiliar automatiza a extração do histórico de operações para um arquivo CSV. Ela seleciona todo o histórico dos últimos 30 dias (HistorySelect), percorre o ticket de cada operação e extrai as propriedades (hora, tipo, símbolo, volume, preço, lucro, comissão, swap) com as funções HistoryDealGet*, gravando-as como valores separados por vírgulas por meio de FileWrite. Depois de escrever a linha de cabeçalho, o loop cria cada linha usando DoubleToString e TimeToString, garantindo precisão numérica consistente e formatação uniforme dos timestamps. A verificação adequada de erros em FileOpen evita falhas não tratadas.
bool ExportHistoryToCSV(string filename) { datetime end = TimeCurrent(); datetime start = end - 2592000; // last 30 days HistorySelect(start, end); int total = HistoryDealsTotal(); int fh = FileOpen(filename, FILE_WRITE|FILE_CSV|FILE_COMMON|FILE_ANSI, ","); if(fh==INVALID_HANDLE) { Print("!! FileOpen failed for: ", filename); return(false); } FileWrite(fh, "Ticket,Time,Type,Symbol,Volume,Price,Profit,Commission,Swap"); for(int i=0; i<total; i++) { ulong deal = HistoryDealGetTicket(i); if(deal==0) continue; long tr = HistoryDealGetInteger(deal, DEAL_TIME); datetime t = (datetime)tr; int tp = (int)HistoryDealGetInteger(deal, DEAL_TYPE); string sym = HistoryDealGetString (deal, DEAL_SYMBOL); double vol = HistoryDealGetDouble (deal, DEAL_VOLUME); double prc = HistoryDealGetDouble (deal, DEAL_PRICE); double pf = HistoryDealGetDouble (deal, DEAL_PROFIT); double cm = HistoryDealGetDouble (deal, DEAL_COMMISSION); double sw = HistoryDealGetDouble (deal, DEAL_SWAP); FileWrite(fh, deal, TimeToString(t, TIME_DATE|TIME_SECONDS), tp, sym, DoubleToString(vol,2), DoubleToString(prc,5), DoubleToString(pf,2), DoubleToString(cm,2), DoubleToString(sw,2) ); } FileClose(fh); return(true); }
10. Wrapper de comando de shell (ShellExecute)
A função ShellExecute atua como um wrapper leve para a chamada importada da API ShellExecuteW. Ao padronizar a chamada de cmd.exe, ela oculta a complexidade da API nativa e sempre usa SW_HIDE para suprimir as janelas de console. O retorno de um código de retorno inteiro permite que o EA detecte e registre possíveis erros ao iniciar comandos externos
int ShellExecute(string command) { return(ShellExecuteW(0, "open", "cmd.exe", command, NULL, SW_HIDE)); }
Desenvolvimento do script de processamento em Python
Começamos configurando o Python e instalando as bibliotecas necessárias. Primeiro, abriremos o prompt de comando e executaremos os comandos de instalação necessários. Depois disso, você poderá preparar seu script Python usando um editor de texto. Pessoalmente, prefiro o Notepad++, uma ferramenta de código aberto, mas você pode usar qualquer IDE para Python de sua escolha.
Configuração
1. Para preparar a versão Python, comece instalando o interpretador Python 3.x mais recente (por exemplo, 3.10 ou 3.12). Crie e ative um ambiente virtual na pasta do seu projeto:
python -m venv venv source venv/Scripts/activate # Windows # or source venv/bin/activate # macOS/Linux
2. Depois da ativação, instale os pacotes necessários com:
pip install pandas fpdf
- pandas faz o parsing de CSV e a análise de dados,
- FPDF (ou outra biblioteca de geração de PDF de sua escolha) gera o relatório.
3. Se você pretende enviar alertas por e-mail, instale também uma biblioteca SMTP, como yagmail, ou use o smtplib integrado ao Python.
Agora é hora de desenvolver o script Python. Seguiremos as etapas abaixo para implementar cada parte.
1. Cabeçalho do script e importações
O script começa com uma configuração no estilo Unix, que permite sua execução em sistemas compatíveis, seguida da importação das principais bibliotecas:
- sys, os e traceback para interação com o sistema operacional, tratamento de argumentos e exibição de mensagens de erro;
- pandas para carregamento e manipulação de dados;
- datetime e timedelta para cálculo de datas;
- FPDF do pacote fpdf para criação de relatórios em formato PDF.
#!/usr/bin/env python import sys, os, traceback import pandas as pd from datetime import datetime, timedelta from fpdf import FPDF
2. Rotinas principais: verificação de argumentos e arquivos
A função main(csv_path) atua como orquestradora. Ela exibe o arquivo CSV que está sendo processado e verifica imediatamente se o arquivo existe. Se ele não existir, lança FileNotFoundError. Isso espelha as verificações preliminares do próprio EA em MQL5 para confirmar a existência dos caminhos do executável e do script Python.
def main(csv_path): print(f"Processing CSV: {csv_path}") if not os.path.isfile(csv_path): raise FileNotFoundError(f"CSV not found: {csv_path}")
3. Carregamento e parsing do arquivo CSV
Usando pandas.read_csv, o script carrega o arquivo CSV do histórico de negociação criado pelo EA. Em seguida, converte a coluna "Time" em objetos datetime com pd.to_datetime, garantindo a precisão dos cálculos temporais posteriores. Isso é análogo à formatação dos valores de tempo pelo EA usando TimeToString.
# 1. Load & parse df = pd.read_csv(csv_path) df['Time'] = pd.to_datetime(df['Time'])
4. Resumo analítico computado
O script reúne os principais indicadores de desempenho em um dicionário de relatório:
- 'date': data de hoje como string;
- 'net_profit': soma da coluna Profit;
- 'trade_count': número total de linhas no DataFrame;
- 'top_symbol': símbolo com o maior lucro acumulado, usando groupby e idxmax.
Esses indicadores correspondem ao conteúdo do arquivo CSV do EA e permitem que o PDF represente com precisão o que foi exportado.
# 2. Analytics report = { 'date' : datetime.now().strftime("%Y-%m-%d"), 'net_profit' : df['Profit'].sum(), 'trade_count': len(df), 'top_symbol' : df.groupby('Symbol')['Profit'].sum().idxmax() }
5. Criação do relatório em formato PDF
O script cria o caminho de saída no mesmo diretório MQL5\Files do CSV, nomeando o arquivo PDF pela data. Em seguida, chama generate_pdf(report, pdf_file). Isso é coerente com o fato de que o EA registra a saída do Python e espera que quaisquer artefatos, tanto em formato CSV quanto em formato PDF, sejam colocados na pasta comum de arquivos.
# 3. Generate PDF dirpath = os.path.dirname(csv_path) pdf_file = os.path.join(dirpath, f"Report_{report['date']}.pdf") generate_pdf(report, pdf_file) print(f"PDF written: {pdf_file}") return 0
6. Criação do arquivo PDF com FPDF
A função generate_pdf usa a API simples do FPDF: cria um documento, adiciona uma página, define a fonte e escreve linhas para cada indicador. O parâmetro ln=True passa automaticamente para a próxima linha. Esse helper modular permite separar as responsabilidades de formatação do PDF da lógica dos dados.
def generate_pdf(report, output_path): pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=12) pdf.cell(0, 10, f"Report Date: {report['date']}", ln=True) pdf.cell(0, 10, f"Total Trades: {report['trade_count']}", ln=True) pdf.cell(0, 10, f"Net Profit: ${report['net_profit']:.2f}", ln=True) pdf.cell(0, 10, f"Top Symbol: {report['top_symbol']}", ln=True) pdf.output(output_path)
7. Manutenção: limpeza de relatórios antigos
Para evitar o preenchimento excessivo do disco, clean_old_reports remove todos os arquivos PDF cuja idade excede o número configurado de dias, por padrão 30. Ela é executada somente quando o EA inicia o script aos domingos (weekday() == 6) e recebe o caminho do CSV em sys.argv[1], garantindo que o diretório correto seja usado como alvo. Essa manutenção está alinhada à própria lógica de controle de execução do EA, com nomes baseados em datas e execução controlada em intervalos de 24 horas.
def clean_old_reports(days=30): now = datetime.now() cutoff = now - timedelta(days=days) dirpath = os.path.dirname(sys.argv[1]) for fname in os.listdir(dirpath): if fname.startswith("Report_") and fname.endswith(".pdf"): full = os.path.join(dirpath, fname) if datetime.fromtimestamp(os.path.getmtime(full)) < cutoff: os.remove(full) print(f"Deleted old report: {full}")
8. Ponto de entrada do script e tratamento de erros
O bloco if __name__ == "__main__": garante o uso de apenas um argumento, o caminho completo para o arquivo CSV. Ele envolve a chamada de main em try/except para capturar qualquer exceção, exibir o traceback e encerrar a execução com um código diferente de zero, exatamente como o EA captura stdout/stderr gerados pelo processo Python e exibe quaisquer erros em seus logs. A manutenção adicional é realizada semanalmente antes do encerramento.
if __name__ == "__main__": if len(sys.argv) != 2: print("Usage: processor.py <full_csv_path>") sys.exit(1) try: ret = main(sys.argv[1]) # Optional maintenance if datetime.now().weekday() == 6: clean_old_reports(30) sys.exit(ret) except Exception as e: print("ERROR:", e) traceback.print_exc() sys.exit(1)
Interação entre o EA MetaTrader 5 e o script Python
- Convenção de nomes de arquivos: o EA cria um arquivo CSV com nome no formato de data (History_YYYYMMDD.csv), e o script Python espera exatamente um argumento apontando para esse arquivo.
- Alinhamento dos diretórios: ambos os componentes operam na pasta MQL5\Files do MetaTrader 5, permitindo localizar os arquivos sem dificuldade.
- Propagação de erros: o EA redireciona stdout e stderr gerados pelo processo Python para um arquivo de log com timestamp; qualquer exceção no script, como CSV ausente ou erro de parsing, é capturada quando o EA lê o arquivo de log e exibida no log do EA.
- Agendamento: quando o Python é iniciado, entra em ação a lógica do timer de 24 horas do EA; o script em si não mantém estado além do processamento dos dados de entrada, contando com o EA para chamá-lo no momento correto.
- Coordenação da manutenção: a limpeza semanal dos arquivos PDF é iniciada pelo script, mas somente quando ele é chamado aos domingos, de acordo com a periodicidade semanal de verificação do EA, caso essa lógica seja expandida.
Testes
Nesta seção, anexaremos o Reporting EA a um gráfico do MetaTrader 5. Em um computador com Windows, é importante habilitar a importação de DLLs nativas para permitir a execução de processos externos. Durante os testes, o EA atingiu seu objetivo: exportou o histórico de negociação como arquivo CSV e iniciou o script Python responsável pelo processamento dos dados. Em seguida, o script gera os indicadores necessários do relatório e os exporta como um documento PDF bem-acabado, pronto para envio por e-mail ou arquivamento para consulta.

Implantação do Reporting EA
Log do EA Reporting EA:
2025.07.24 20:44:57.061 Reporting EA (GBPJPY.0,M1) >> Reporting EA initializing… 2025.07.24 20:44:57.061 Reporting EA (GBPJPY.0,M1) !! Python executable not found at: C:\path_to\python.exe 2025.07.24 20:44:57.061 Reporting EA (GBPJPY.0,M1) !! Python script not found at: C:\path_to\reports_processor.py 2025.07.24 20:44:57.062 Reporting EA (GBPJPY.0,M1) ✔ Write permission confirmed. 2025.07.24 20:44:57.062 Reporting EA (GBPJPY.0,M1) >> Timer set to 30 seconds. 2025.07.24 20:44:57.062 Reporting EA (GBPJPY.0,M1) >> Test mode: running initial export. 2025.07.24 20:44:57.063 Reporting EA (GBPJPY.0,M1) ✔ CSV exported: C:\TERMINAL_PATH\MQL5\Files\History_20250724.csv 2025.07.24 20:44:57.063 Reporting EA (GBPJPY.0,M1) → Launching: cmd.exe /c "C:\path_to\python.exe" "C:\path_to\reports_processor.py" "C:\TERMINAL_PATH\MQL5\Files\History_20250724.csv" >> "C:\TERMINAL_PATH\MQL5\Files\ProcLog_20250724.txt" 2>&1 2025.07.24 20:44:57.124 Reporting EA (GBPJPY.0,M1) ← ShellExecute returned: 42 2025.07.24 20:45:00.124 Reporting EA (GBPJPY.0,M1) !! Log file not created: C:\Users\TERMINAL_PATH\MQL5\Files\ProcLog_20250724.txt 2025.07.24 20:45:00.124 Reporting EA (GBPJPY.0,M1) Report & log generated: C:\Users\TERMINAL_PATH\Files\History_20250724.csv
O log do Expert acima mostra uma tentativa de inicialização do Reporting EA em que o sistema não conseguiu encontrar o executável especificado nem o script Python. Isso ocorreu porque os caminhos dos arquivos foram renomeados intencionalmente no código (por exemplo, C:\path_to\python.exe e C:\path_to\reports_processor.py) para fins de demonstração ou como marcadores de posição. Como resultado, o EA não conseguiu executar o script Python nem gerar o resultado de log esperado (ProcLog_20250724.txt). Apesar disso, o EA confirmou com sucesso as permissões de gravação e exportou o histórico de negociação como arquivo CSV.
Esse teste destaca a importância de configurar corretamente os caminhos dos arquivos no seu EA, apontando para o interpretador Python real e para o script de processamento, para garantir a geração contínua dos relatórios de ponta a ponta. Sempre confira novamente e use caminhos absolutos válidos, compatíveis com a configuração do seu sistema local, para evitar problemas semelhantes e usar todos os recursos da ferramenta de relatórios.
Conclusão
Este artigo se concentrou principalmente em compreender os relatórios de negociação, configurar um fluxo de trabalho funcional e desenvolver as ferramentas necessárias para entregar relatórios de negociação personalizados em formato PDF (Portable Document Format). Para não sobrecarregar a apresentação, as etapas finais de envio por e-mail do arquivo PDF gerado foram reservadas para uma publicação futura. No entanto, a geração do arquivo PDF a partir do arquivo CSV exportado foi concluída com sucesso usando bibliotecas Python. Melhorias futuras, como a inclusão de gráficos e recursos avançados de relatórios, serão apresentadas no próximo artigo.
Agora que tanto o EA quanto o script Python correspondente estão prontos, temos condições de avançar ainda mais. Assim, este projeto soluciona a necessidade de gerar relatórios de negociação agendados e personalizáveis com recursos visuais que facilitam a compreensão. Assim como a contabilidade é essencial para qualquer negócio, a geração regular de relatórios é vital no trading, pois promove a consciência dos resultados, a disciplina e o crescimento psicológico dos traders.
Principais aprendizados
| Aprendizado | Descrição |
|---|---|
| 1. Design modular | Separar a lógica de exportação CSV (MQL5) da lógica de criação de relatórios (Python) aumenta a manutenibilidade e permite que cada componente evolua de forma independente. |
| 2. Tratamento robusto de erros | A verificação dos caminhos dos arquivos, a captura de exceções no Python e o registro de falhas garantem que o sistema falhe de forma controlada e possa ser depurado e facilitam a depuração. |
| 3. Integração entre linguagens | A chamada de scripts externos por meio de ShellExecute demonstra como plataformas de negociação podem aproveitar bibliotecas e ecossistemas externos poderosos. |
| 4. Agendamento automatizado | O uso de callbacks de timer em MQL5 para iniciar a exportação diária garante a execução dos relatórios sem intervenção manual, aumentando a consistência e a confiabilidade. |
| 5. Logging centralizado | A gravação de logs na aba Experts do MetaTrader 5 e em arquivos de texto externos fornece visibilidade clara sobre cada etapa do fluxo de trabalho. |
| 6. Verificação do ambiente | Verificar a disponibilidade do Python e dos scripts na inicialização evita surpresas em tempo de execução e orienta os usuários quanto aos requisitos de configuração. |
| 7. Ferramentas de código aberto | O uso de bibliotecas gratuitas e amplamente utilizadas (pandas, FPDF) e de APIs padrão reduz as barreiras de entrada e incentiva a colaboração com a comunidade. |
| 8. Parâmetros configuráveis pelo usuário | Expor o caminho, o horário agendado e as opções de notificação como parâmetros de entrada torna o EA flexível e adaptável a diferentes ambientes de negociação. |
Conteúdo do anexo
| Nome do arquivo | Versão | Descrição |
|---|---|---|
| reporting_processor.py | Script Python que carrega o histórico de operações em formato CSV, calcula o resumo analítico (lucro líquido, número de operações, instrumento principal), gera um relatório em formato PDF por meio do FPDF e, se necessário, remove relatórios antigos. | |
| Reporting EA.mq5 | 1.0 | EA do MetaTrader 5 que exporta o histórico de operações dos últimos 30 dias para o formato CSV, chama processor.py, registra seu código de saída, verifica a existência do arquivo PDF gerado e envia uma notificação push. |
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/18882
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Transferência de dados de ticks do MetaTrader para Python via sockets usando serviços MQL5
Análise espectral singular em MQL5
Está chegando o novo MetaTrader 5 e MQL5
Teoria dos grafos: Algoritmo de Dijkstra no trading
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso