
Negociação algorítmica com MetaTrader 5 e R para iniciantes
Introdução
MetaTrader é um produto mundialmente reconhecido no campo das plataformas de negociação. Este software, conhecido por sua alta qualidade, é gratuito, o que o torna acessível a uma ampla gama de usuários. Por esse motivo, a comunidade MetaTrader tem registrado um crescimento sustentável ano após ano. A comunidade, que agora é mais diversificada do que nunca em sua história, inclui pessoas de diferentes origens culturais e com excelentes habilidades em linguagens de programação. É notável que, além do MetaQuotes Language 5 (a linguagem oficial da plataforma), o Python é a única linguagem de programação com suporte completo na plataforma MetaTrader.
A comunidade MetaQuotes sempre dá as boas-vindas aos novos membros que fazem a transição R, independentemente de sua experiência em meio acadêmico ou em computação científica. Apesar dos avanços em Python e a integração exclusiva do Python como a única linguagem (além do MQL5) totalmente suportada no terminal MetaTrader, pessoas que dominam R não devem considerar suas habilidades de programação como obsoletas. Este artigo desafia qualquer noção de obsolescência, mostrando que, com um pouco de criatividade e engenhosidade, é perfeitamente possível criar um Expert Advisor de negociação algorítmica complexo usando R e MetaTrader 5.
Com base na experiência do autor, é importante notar que os pacotes discutidos neste artigo demonstram interação imperfeita quando usados separadamente no terminal MetaTrader 5. Cada pacote tem suas limitações. No entanto, quando usados em conjunto, esses pacotes compensam efetivamente as limitações uns dos outros, formando uma base confiável que facilita o desenvolvimento de algoritmos de negociação usando R e MetaTrader.
Pontos de atenção:
1. Considerações sobre o sistema operacional:
A demonstração foi realizada em um computador rodando o Windows 11, build 22621.1848. Esses passos não foram testados em sistemas operacionais alternativos.
2. Compatibilidade da versão do R:
A demonstração utiliza a versão 4.3.2 do R. É fundamental que os participantes usem a mesma versão do R, pois alguns pacotes apresentados nesta apresentação não suportam versões anteriores da linguagem R.
3. Integração com RStudio:
Esta demonstração se integra ao RStudio, que é um ambiente de desenvolvimento integrado avançado projetado para codificação em R. Recomenda-se aos participantes que utilizem o RStudio para uma experiência de programação otimizada durante toda a demonstração.
Configuração do ambiente
Vamos começar configurando nosso ambiente.
Primeiro, certifique-se de que a versão 4.3.2 do R está instalada no seu computador. Se você não tem certeza ou não tem o R instalado, vamos passar por todas as etapas juntos.
Para verificar se o R está instalado, procure o ícone do R na área de trabalho. Se ele não estiver lá, você pode buscar por "R" — isso deve abrir o terminal do R, se ele já estiver instalado. Você pode instalar o R a partir do repositório oficial no The Comprehensive R Archive Network. Este link sempre levará você à última versão do R, que atualmente é a versão 4.3.2. Após baixar o arquivo de instalação, siga as instruções na tela, começando pela seleção do idioma.
Agora que você tem o R instalado, vamos verificar a versão em uso. Abra o terminal do R e você verá a versão exibida no topo da mensagem de boas-vindas, toda vez que iniciar uma nova sessão. Se precisar de mais informações, você sempre pode usar o comando `version` no terminal.
Fig. 1. Verificação da versão do R
Agora vamos configurar o RStudio. Você pode baixar o RStudio aqui: RStudio Desktop - Posit. Basta seguir as instruções na tela conforme elas aparecem, similar ao processo de instalação do R que discutimos anteriormente.
Após a conclusão da instalação, vamos verificar a versão do R que o RStudio está usando.
Abra o RStudio.
Selecione Tools (ferramentas) e Global Options... (opções globais).
Fig. 2. Verificação da versão do R usada no RStudio
Você verá a versão do R em uso.
Se o seu computador tiver duas ou mais versões do R instaladas, clique em Change... (alterar).
Fig. 3. Verificação da versão do R usada no RStudio
Escolha "Choose a specific version of R" (escolher uma versão específica do R), selecione a versão 4.3.2, clique em OK e reinicie o RStudio para que as alterações tenham efeito.
Fig. 4. Escolha da versão do R
Após reiniciar o RStudio, é necessário instalar algumas dependências.
#Algorithmic Trading With RStudio And MetaTrader 5 #Gamuchirai Zororo Ndawana #This script will help you get your environment setup and test that everything is working fine #Sunday 17 December 2023 #Installing Dependencies install.packages("stringi") #This package is a dependency for devtools install.packages("devtools") #We will use this package to install R packages hosted on github install.packages("xts") #We will use this package to plot data fetched from the MetaTrader 5 Terminal install.packages("quantmod") #We will use this package to plot data fetched from the MetaTrader 5 Terminal install.packages("ttr") #We will use this package to calculate technical indicator values install.packages("reticulate") #We will use this package to call Python libraries in R devtools::install_github("Kinzel/mt5R") #We will use this open source package to interact with the MetaTrader 5 Terminal
Começaremos importando a primeira biblioteca — `reticulate`. Esta biblioteca permite executar código Python no R. Utilizaremos `reticulate` para instalar a biblioteca MT5 Python em um ambiente virtual. Após instalar a biblioteca MT5, poderemos usar `reticulate` como uma ponte entre o RStudio e o ambiente virtual Python. Esta conexão intermediária nos permitirá enviar comandos ao nosso terminal MetaTrader 5, facilitando a execução de negociações.
Vamos começar baixando a biblioteca `reticulate`.
#Libraries #Importing reticulate library(reticulate)Em seguida, criaremos um ambiente virtual usando a função `virtualenv_create()` da biblioteca `reticulate`. A função aceita um parâmetro de string, representando o nome do nosso ambiente virtual. Na programação, ambientes virtuais oferecem um método para criar espaços isolados e autônomos para projetos individuais. A justificativa fundamental para o uso de ambientes virtuais é o gerenciamento eficaz de dependências, mitigando conflitos e garantindo a reprodutibilidade do projeto. Isso se torna especialmente importante quando vários projetos ou pacotes têm dependências comuns, mas precisam de diferentes versões das mesmas dependências.
#Create a virtual environment virtualenv_create("rstudio-metatrader5")
Após a criação da virtualenv, o próximo passo é ativá-la e utilizá-la. Isso é feito utilizando a função `use_virtualenv()` da biblioteca `reticulate`. Ativar a virtualenv garante que as operações subsequentes em Python sejam executadas no contexto isolado desse ambiente, permitindo gerenciar dependências e configurações específicas do nosso projeto.
#Use the virtual environemnt use_virtualenv("rstudio-metatrader5")
Vamos instalar a biblioteca Python para MetaTrader 5, utilizando a função `py_install()` da biblioteca `reticulate`. Nós fornecemos à função o nome da biblioteca que vamos instalar, neste caso "MetaTrader5".
#Install metatrader5 python library py_install("MetaTrader5")
Depois de instalar a biblioteca, o próximo passo é importar a biblioteca MetaTrader 5 e salvá-la em uma variável chamada "MT5". Isso é feito com a função `import()` da biblioteca `reticulate`. A variável "MT5" servirá como nossa interface para interagir com a biblioteca MetaTrader 5 nos próximos passos.
#Import MetaTrader 5 MT5 <- import("MetaTrader5")
Antes de continuar, certifique-se de que o terminal MetaTrader 5 não está em execução no momento. Se ele estiver aberto, por favor, feche-o.
Agora vamos iniciar o terminal MetaTrader 5 diretamente do RStudio. Podemos conseguir isso chamando a função de inicialização da biblioteca MetaTrader 5 Python. Se a inicialização for bem-sucedida, a função retornará TRUE, indicando que o terminal MetaTrader 5 foi iniciado com sucesso.
#Initialize the MetaTrader 5 Terminal MT5$initialize()
[1] TRUE
Embora possamos acessar informações da conta, dados do terminal e características dos símbolos, enfrentamos nossa primeira limitação: a incapacidade de fazer login programático em outra conta. A conta que está ativa durante a inicialização do terminal se torna a única conta acessível, a menos que seja alterada manualmente pelo usuário. Embora seja possível criar um script Python para fazer login em outra conta usando a biblioteca MetaTrader 5 e executá-lo a partir do R usando `reticulate`, este artigo assume que os leitores possuem apenas conhecimento de programação em R e uma compreensão básica de programação em MQL5.
Outra limitação é a incapacidade de solicitar informações históricas de preços usando `reticulate`. Esta limitação pode estar relacionada à conversão automática de tipos de dados pelo `reticulate` ao transferir objetos entre R e Python. Consequentemente, surgem dificuldades ao lidar com o objeto retornado ao solicitar dados históricos de preços do terminal. Aqui, utilizamos um segundo pacote para corrigir as limitações do `reticulate`.
#Get account information
account_info <- MT5$account_info()
#Print account information
account_info$company
account_info$balance
account_info$name
#Get terminal information
terminal_info <- MT5$terminal_info()
terminal_info$build
terminal_info$company
terminal_info$name
[1]"Deriv.com Limited"
[1]868.51
[1]"Gamuchirai Ndawana"
[1]4094
[1]"MetaQuotes Software Corp."
[1]"MetaTrader 5"
#Requesting price data price_data <- MT5$copy_rates_from_pos("Boom 1000 Index",MT5$TIMEFRAME_M1,0,10)
Error in py_call_impl(callable, call_args$unnamed, call_args$named) :
SystemError: returned a result with an exception set
Run `reticulate::py_last_error()` for details.
Usamos o MT5R para resolver esses problemas. Mas primeiro, vamos entender como o MT5R funciona internamente.
O pacote MT5R estabelece uma conexão WebSocket entre o RStudio e o terminal MetaTrader 5, criando um canal de comunicação full-duplex. Em um sistema full-duplex, os dados podem ser enviados e recebidos simultaneamente. Para que esse canal seja eficaz, o terminal MetaTrader 5 deve ouvir em uma porta específica que utilizaremos para enviar instruções. Além disso, ele deve interagir com nossa sessão do RStudio através dessa mesma porta. Felizmente, o MT5R inclui um Expert Advisor, escrito em MetaQuotes Language 5, que escuta nossos comandos. O Expert Advisor tem código aberto, proporcionando flexibilidade para adicionar funcionalidades adicionais. O código-fonte pode ser baixado aqui. Note que anexamos à artigo uma versão configurada do Expert Advisor, que inclui uma função adicional para posicionamento automático de trailing stops e take profits.
Fig. 5. Esquema do MT5R
Depois de baixar o Expert Advisor, você deve colocá-lo nas mesmas pastas que os outros EAs. Inicie seu terminal MetaTrader 5, abra o menu "Arquivo" e selecione "Abrir pasta de dados".
Fig. 6. Localizando a pasta de dados
Em seguida, navegue até ".\MQL5\experts\" e coloque o Expert Advisor na pasta Experts. Depois, abra o símbolo que você deseja negociar e coloque o Expert Advisor MT5R no gráfico. O sistema pode perguntar se você deseja conceder permissão para que o MetaTrader 5 realize operações de rede no seu computador. Conceda essa permissão. Uma vez feito isso, estamos prontos para voltar ao RStudio e continuar a criação do nosso algoritmo de negociação.
Abra o RStudio e importe as bibliotecas MT5R, xts e quantmod.
#Import the MT5R Library library(mt5R) #Import xts to help us plot library(xts) #Import quantmod to help us plot library(quantmod)
Em seguida, verifique se nossa conexão com o terminal está estabelecida usando a função `Ping()` do pacote MT5R. A função retornará TRUE se conseguir se comunicar com o Expert Advisor.
#Check if our connection is established MT5.Ping() #Global variables MARKET_SYMBOL <- "Volatility 75 Index"
[1] TRUE
O MT5R não resolve o problema de login que discutimos anteriormente, mas resolve a questão da solicitação de dados de preços.
Para solicitar dados de preços do nosso terminal MetaTrader 5, chamamos a função `GetSymbol` da nossa biblioteca MT5R. A função espera o nome do símbolo, seguido do timeframe em minutos (portanto, dados diários serão 1440) e, por fim, o número de linhas. Os dados mais antigos estão no topo, e o preço atual está na parte inferior.
Observe que definimos o parâmetro `xts` como verdadeiro. Isso converte o bloco de dados em um objeto de série temporal do R e formata automaticamente as datas no gráfico. Isso também nos permite adicionar facilmente valores de indicadores técnicos ao nosso bloco de dados.
#Request historical price data price_data <- MT5.GetSymbol(MARKET_SYMBOL, iTF = 1, iRows=5000,xts = TRUE)Podemos facilmente plotar os dados de preços usando a função `lineChart()` do quantmod.
#Plotting a line chart
lineChart(price_data, name = MARKET_SYMBOL)
Fig. 7. Exibição de dados de preços no RStudio
Também podemos adicionar indicadores técnicos ao nosso gráfico usando a função `addIndicator` do quantmod, por exemplo, adicionando um Índice de Força Relativa (RSI) de 60 períodos ao nosso gráfico.
#We can also add technical indicators to the plot
addRSI(n=60)
Fig. 8. Adicionando indicadores técnicos ao gráfico
Processamento de dados personalizados
Quando adicionamos RSI e o indicador Aroon, nós os adicionamos apenas ao gráfico. Para adicionar os valores dos indicadores técnicos ao nosso dataframe, devemos chamar o indicador do pacote quantmod e, em seguida, fornecer as colunas apropriadas necessárias para os cálculos. As colunas relevantes são indicadas na documentação; neste exemplo, adicionaremos ao dataframe uma média móvel simples de 20 períodos, um índice de força relativa (RSI) de 20 períodos e um indicador de amplitude média verdadeira (ATR) de 20 períodos.
#Add moving average price_data$SMA_20 <- SMA(price_data$Close,n = 20) #Add RSI to the dataframe price_data$RSI_20 <- RSI(price_data$Close,n=20) #Add ATR to the dataframe price_data$ATR_20 <- ATR(price_data[,c("High","Low","Close")], n=20)
Depois de fazer isso, removeremos todas as linhas com valores ausentes.
#Drop missing values
price_data <- na.omit(price_data)
Adicionaremos uma função chamada "próximo fechamento" (next close), que conterá o preço do próximo fechamento. Se o valor do próximo fechamento for maior que o preço de fechamento atual, nosso alvo será igual a um, caso contrário, será zero. Isso é feito usando a função `ifelse` no R.
#Next close price price_data$Next_Close <- lag(price_data$Close,-1) #Setting up our target price_data$Target <- ifelse( ( (price_data$Next_Close) > price_data$Close) , 1 , 0)
Agora estamos prontos para fazer a divisão treino-teste. Usaremos as primeiras 4000 linhas para treinamento e o restante para teste. Ao trabalhar com dados de séries temporais, evitamos a divisão aleatória para evitar vazamento de dados — situação em que o modelo inadvertidamente aprende com informações futuras para prever o passado. Em vez disso, priorizamos manter a ordem temporal natural dos dados. Na prática, escolhemos as primeiras 4000 linhas em sua sequência cronológica e seguimos com o restante das linhas. Essa abordagem garante que nosso modelo aprenda com dados passados para prever o futuro, mantendo as melhores práticas de análise de séries temporais.
#Train test split train_set <- price_data[1:4000,] train_y <- price_data[1:4000,c("Target")] test_set <- price_data[4001:4980,] test_y <- price_data[4001:4980,c("Target")]
Agora que dividimos nossos dados em conjuntos de treinamento e teste, o próximo passo é treinar o modelo escolhido. Neste caso, escolhemos a análise discriminante quadrática (QDA). O QDA é focado em maximizar a diferenciação entre duas classes, promovendo uma classificação mais eficaz dos dados. Isso é alcançado maximizando a separação das médias dos dois grupos e minimizando a variabilidade média dentro de cada grupo. Para implementar o QDA, usamos a biblioteca MASS, que contém o modelo QDA. Portanto, importamos a biblioteca MASS para acessar e usar o modelo QDA em nossa análise.
#Fitting models library(MASS) #Quadratic Discriminant Analysis #Using OHLC Data qda <- qda(Target ~ Open+High+Low+Close,data = train_set) qda
Call:
qda(Target ~ Open + High + Low + Close, data = train_set)
Prior probabilities of groups:
0 1
0.49925 0.50075
Group means:
Open High Low Close
0 365424.6 365677.8 365159.9 365420.5
1 365125.4 365384.0 364866.6 365131.4
A partir da matriz de confusão, vemos que nosso modelo prevê melhor os movimentos de alta do que os de baixa no mercado.
#Evaluating model performance #Custom Quadratic Discriminant Analysis qda_predictionts <- predict(qda,test_set) qda_predictionts <- qda_predictionts$class #Confusion matrix table(qda_predictionts,test_y)
Fig. 9. Matriz de confusão
Implementação da lógica de negociação
Chegamos ao ponto fundamental do nosso algoritmo de negociação, onde o imperativo inicial é criar uma variável denominada `last_trade`. Essa variável adquire importância ao desempenhar a função chave de monitorar a transação mais recente iniciada. Sua importância reside em auxiliar no fechamento oportuno das posições quando nosso modelo prevê um movimento desfavorável do mercado, que pode potencialmente minar nossa posição geral no mercado. Vale lembrar nosso sistema simples de codificação, onde o valor 1 significa compra (BUY) e o valor 0 significa venda (SELL).
#Keeping track of the last trade last_trade <- -1
Ao implementar nosso algoritmo, é necessário iniciar um loop infinito, no qual nossa lógica de negociação está inserida. Esse loop infinito é alcançado incluindo uma função de timeout, regulando assim a frequência das iterações. Em conformidade com a geração de novos candles, buscamos ciclos de iteração síncronos. A integração da função `Sys.sleep` garante que nossas ações de negociação estejam em sintonia com as mudanças do mercado minuto a minuto.
Nosso primeiro passo é obter as informações de mercado atuais.
Em seguida, passamos esses dados para nosso modelo e obtemos a previsão.
Depois que nosso modelo fez a previsão, verificamos se temos posições abertas usando o pacote MT5 que instalamos via `reticulate`. Se não tivermos posições abertas, procedemos à abertura de uma posição na direção da previsão do mercado e, em seguida, atualizamos nossa variável `last_trade`.
Caso contrário, se tivermos uma posição aberta, verificamos se o nosso modelo prevê um movimento contra ela. Se sim, fechamos a posição.
Por fim, precisamos adicionar um timeout para que nosso algoritmo verifique nossa posição uma vez a cada candle.
while(TRUE){ #Fetching current market data print("Fetching market information") data <- MT5.GetSymbol(MARKET_SYMBOL,iTF=1, iRows = 2) data <- data[1,] #Forecasting market move qda_forecast <- predict(qda,data) qda_forecast <- qda_forecast$class print("Model forecast: ") print(qda_forecast) #Checking if we have no open positions current_positions <- MT5$positions_total() #If we have no open positions, open a position following the model forecast if(current_positions == 0){ print("We have no open positions. Opening a new position") #A Forecast of 1 means buy if(qda_forecast == 1){ print("Opening Buy Position") MT5$Buy(MARKET_SYMBOL,symbol_info$volume_min) last_trade <- 1 } #A Forecast of 0 means sell if (qda_forecast == 0){ print("Opening Sell Position") MT5$Sell(MARKET_SYMBOL,symbol_info$volume_min) last_trade <- 0 } } else{ #Are we anticipating a move against our open position? if(last_trade != qda_forecast){ #If we are, let's close our position print("Closing open position") MT5$Close(MARKET_SYMBOL) #Reset last trade last_trade <- -1 } else{ #Otherwise everything is expected to be fine print("The current position is aligned with the market") info <- MT5$account_info() print("Current Profit") print(info$profit) } } #Wait for a new candle to form Sys.sleep(60) }
Fig. 10. Modelo de Análise Discriminante Quadrática no R negociando em tempo real no MetaTrader 5
Considerações finais
Apesar das dificuldades ao desenvolver um algoritmo de negociação em tempo real usando R e MetaTrader 5, o artigo demonstra que a tarefa é mais alcançável do que pode parecer à primeira vista. Até mesmo iniciantes na linguagem R podem fazer progressos significativos. As limitações dos pacotes individuais são eficazmente mitigadas por pacotes adicionais, e, em particular, a abordagem adotada minimiza as dependências. No geral, apresenta uma estrutura viável e confiável, acessível a qualquer usuário de R.
Além disso, a versão configurada do Expert Advisor MT5R anexada ao artigo é destinada à inclusão autônoma de stop-losses e take-profits, ajudando no gerenciamento da negociação. Os usuários são encorajados a expandir a funcionalidade do Expert Advisor conforme necessário. Desejo a vocês paz, prosperidade e negociações lucrativas!
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/13941





- 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