Neste artigo, você irá entender como enviar ordens automaticamente no MetaTrader5 usando Python.
Todas as estratégias de trading exigem que o trader realize compra e venda de ativos em determinados períodos de tempo. Para automatizar as operações utilizando Python, é necessário saber advir ordens por meio de código.
Para enviar uma ordem na plataforma MetaTrader5, além de uma conta já estabelecida, é preciso utilizar duas funções principais que atuam em conjunto para checar e enviar a ordem. Antes de tudo, é importante entender o que é uma ordem, que consiste em instruções a um corretor ou corretora para comprar ou vender um título em nome de um investidor.
Introdução ao envio de ordens no MetaTrader5
Antes de prosseguir com o roteamento de ordens no MetaTrader5, é necessário estabelecer uma ação sobre a qual trabalharemos. Para isso, vamos declará-la e verificar sua existência no MT5 em algumas etapas, por questões de segurança de código.
# preparamos o ativo
symbol="ITUB4"
symbol_info = mt5.symbol_info(symbol)
if symbol_info is None:
error_quit(f"{symbol} não foi encontrado, não é possível chamar order_check()")
# se o símbolo não estiver disponível no MarketWatch, adicionamos
if not symbol_info.visible:
print(symbol, "não está visível, tentando conectar...")
if not mt5.symbol_select(symbol,True):
error_quit(f"symbol_select({symbol}) falhou, exiting...")
Com isso feito, podemos prosseguir.
O primeiro passo é verificar se temos as condições necessárias para realizar a operação que desejamos. Para isso, é necessário enviar uma requisição para o terminal do MetaTrader5, que verifica a possibilidade. A estrutura básica da função necessária, a order_check()
, segue o seguinte padrão:
mt5.order_check(
request # estrutura de solicitação
)
Essa função deve retornar se a operação é possível ou não. Mas antes temos que montar um request
, que é o objeto interpretado pelo MetaTrader5 para fazer as requisições.
A estrutura de um request
A estrutura básica de um request segue alguns campos necessários que serão organizados em um dicionário. São eles:
Chave | Valor | Tipo |
action | Compõe o tipo de trade que será feito. Como esse trade será posto? | mt5 object ou inteiro |
symbol | O ativo que estamos operando | mt5 object |
volume | Volume da operação | float (é preciso calcular o valor mínimo de volume para evitar o erro 10014 Invalid volume ) |
type | Tipo de ordem: Compra, venda, buy_limit, sell_limit… | mt5 object ou inteiro |
price | Valor de ask | float |
sl | Stop loss da operação | float |
tp | Take-Profit da operação | float |
deviation | Desvio – Valor da medida de volatilidade do mercado | inteiro |
magic | Atribui um número cada pedido pendente, a fim de usar essa informação para identificá-lo | inteiro |
comment | Comentário arbitrário do programador | string |
type_time | Quando a operação será realizada? | mt5 object ou inteiro |
type_filling | Tipo de ordem: Fill or Kill, Immediate or Cancel ou Return | mt5 object ou inteiro |
Caso queira compreender melhor sobre cada campo necessário para a execução de um request
, recomendamos que dê uma olhada na documentação do MLQ5 sobre cada campo específico. Mas, abaixo, cobriremos um caso geral que deve satisfazer as operações.
À primeira vista, podem parecer muitos parâmetros para a realização de uma operação, mas todo trader sabe que são parâmetros necessários, sendo alguns obrigatórios e outros não, como é o exemplo do Stop-Loss e do Take-Profit entre outros.
Verificando fundos para realizar uma operação
Para executar um código de checagem de fundos de uma operação, além da request, é necessário uma série de passos. Porém, antes definiremos duas funções essenciais: uma em caso de erro e outra para checar se o volume de compra que estamos tentando realizar é possível.
# Funções para diminuir repetições de código
def error_quit(message):
print(message)
mt5.shutdown(); quit()
def check_volume(vol, symbol):
maxvol = mt5.symbol_info(symbol).volumehigh
minvol = mt5.symbol_info(symbol).volumelow
if vol < minvol or vol > maxvol:
error_quit(f'Volume Selecionado: {vol}\nVolume Mínimo: {minvol}\nVolume Máximo: {maxvol}')
Para checarmos a nossa ordem, é preciso executar:
point = mt5.symbol_info(symbol).point
ask = mt5.symbol_info_tick(symbol).ask
# estabelecer o volume aqui para mitigar erros
volume = 100.0
check_volume(volume, symbol)
request = {
"action": mt5.TRADE_ACTION_DEAL, # TRADE_ACTION_DEAL -> Ordem imediata
"symbol": symbol,
"volume": volume,
"type": mt5.ORDER_TYPE_BUY, # ORDER_TYPE_BUY -> Ordem para compra
"price": ask, # preço ask
"sl": ask-100*point,
"tp": ask+100*point,
"deviation": 10,
"magic": 234000,
"comment": "asimov python script",
"type_time": mt5.ORDER_TIME_GTC, # ORDER_TIME_GTC -> A ordem permanecerá na fila até ser tirada
"type_filling": mt5.ORDER_FILLING_RETURN, # ORDER_FILLING RETURN -> No caso de uma execução parcial, a ordem de mercado ou limit com um volume residual não é retirada e continua
}
Ao printar o result[‘retcode’]
e result[‘comment’]
, obtemos o código de resposta do programa e o comentário atribuído, compreendendo assim se a operação foi bem sucedida e, caso não, quais foram os resultados obtidos durante a execução.
É importante lembrar que a verificação de fundos para uma operação não envia a ordem. Para enviá-la, é necessário outro comando, o qual cobrimos a seguir.
Como enviar ordens no MetaTrader5
Aqui, utilizaremos a função order_send()
, padrão do MT5, para envio de ordens, que segue uma estrutura de requisição semelhante ao do order_check()
. A estrutura é a seguinte:
mt5.order_send(
request # estrutura de solicitação
)
Para testarmos o envio de ordens, iremos executar uma ordem de compra de um ativo específico (aqui utilizaremos o ITUB4), esperar 2 segundos utilizando a função time.sleep()
nativa do Python e executar a ação de venda para que seja confirmada a operação de maneira demonstrativa.
Como operação padrão, antes devemos definir o volume, point, price e deviation. Nesse caso, utilizaremos o price de ask na compra e o preço de bid na venda, como há de ser. Iniciando pela ordem de compra:
volume = 100.0
point = mt5.symbol_info(symbol).point
price = mt5.symbol_info_tick(symbol).ask
deviation = 20
# estrutura de request igual à utilizada no order_check()
request = {
"action": mt5.TRADE_ACTION_DEAL, # ação imediata de transação
"symbol": symbol,
"volume": volume,
"type": mt5.ORDER_TYPE_BUY, # ordem de mercado para compra
"price": price, # preço ask
"sl": price - 100 * point, # não é necessário
"tp": price + 100 * point, # não é necessário
"deviation": deviation,
"magic": 234000,
"comment": "asimov python script open",
"type_time": mt5.ORDER_TIME_GTC, # A ordem permanecerá na fila até ser tirada
"type_filling": mt5.ORDER_FILLING_RETURN, # Ordem manual
}
# enviamos a solicitação de negociação
result = mt5.order_send(request)
Nesse caso, o resultado é retornado da mesma maneira anterior, porém, para fins didáticos, utilizamos aqui o método de atributos para desmembramento. Primeiro, devemos checar por meio do código de retorno se a ordem foi concluída. Para isso, utilizaremos primeiro uma função pré-definida (para evitar repetição de código posteriormente) e será comparado o retorno do resultado com a constante do MT5 chamada de mt5.TRADE_RETCODE_DONE
, que nada mais nada menos é que um inteiro de valor 10009
, representando o sucesso da operação.
A função que criaremos serve para dar o retorno em uma espécie de log do resultado de qualquer operação, iterando sobre os campos do objeto de resultado:
def order_result_log(result_object):
# solicitamos o resultado na forma de dicionário e exibimos elemento por elemento
result_dict = result_object._asdict()
for field in result_dict.keys():
print(f" {field}={result_dict[field]}")
#se esta for uma estrutura de uma solicitação de negociação, também a exibiremos elemento a elemento
if field == "request":
traderequest_dict = result_dict[field]._asdict()
for tradereq_filed in traderequest_dict:
print(f"\ttraderequest: {tradereq_filed}={traderequest_dict[tradereq_filed]}")
Tendo a função definida, podemos checar se a operação de compra foi concluída.
# verificamos o resultado da execução
if result.retcode != mt5.TRADE_RETCODE_DONE:
order_result_log(result); error_quit()
Caso a operação tenha sido executada corretamente, entregamos alguns retornos, como a posição de compra e, na sequência, aguardamos dois segundos utilizando o time.sleep()
para que possamos comprar novamente, dessa vez ao preço de bid.
# resultados da ordem de compra
position_id = result.order
print('POSIÇÃO:', position_id)
print(f"1. order_send(): by {symbol} {volume} lots at {price} desvio={deviation} points")
print("2. order_send() executada:")
print(f" posição aberta: POSITION_TICKET={position_id}")
# tempo de processamento e redefinição da posição
time.sleep(2)
print(f" timer 2s antes de fechar a posição #{position_id}")
Abaixo iniciamos o processo de fechamento, seguindo a mesma lógica anterior de `requests`.
# ORDEM DE FECHAMENTO =================
price = mt5.symbol_info_tick(symbol).bid
deviation = 20
request = {
"action": mt5.TRADE_ACTION_DEAL, # ação imediata de transação
"symbol": symbol,
"volume": volume,
"type": mt5.ORDER_TYPE_SELL, # ordem de mercado para venda
"position": position_id, # ticket
"price": price, # preço bid
"deviation": deviation,
"magic": 234000,
"comment": "asimov python script close",
"type_time": mt5.ORDER_TIME_GTC, # A ordem permanecerá na fila até ser tirada
"type_filling": mt5.ORDER_FILLING_RETURN, # Ordem manual
}
# enviamos a solicitação de negociação
result = mt5.order_send(request)
Tendo o resultado em mãos, devemos verificar o resultado e disponibilizar para o usuário:
# verificamos o resultado da execução
print(f"3. close position #{position_id}: sell {symbol} {volume} lots at {price} desvio={deviation} points")
if result.retcode != mt5.TRADE_RETCODE_DONE:
print(f"4. order_send falhou, retcode={result.retcode}")
print(" resultado",result)
else:
print(f"4. posição #{position_id} closed, {result}")
order_result_log(result)
Ordens e registros temporais
Em resumo, é assim que se executa uma ordem e checa seus parâmetros derivados. No entanto, se você também deseja aprender a checar as ordens já realizadas, as posições abertas e abduzir de maneira conclusiva a qualidade de uma série de trades para validar uma estratégia, recomendamos a leitura do seguinte artigo:
Inclusive, existem outras tantas possibilidades dentro do MT5 para manejar o seu capital e expandir as suas estratégias como um Trader Quantitativo. Também há diversas técnicas para manipular dados do mercado e facilitar a visualização, como explicamos nestes dois artigos:
Técnicas de visualização de dados financeiros no Trading Quantitativo
Candlesticks e Time Bars: por que você deveria parar de usá-los nas suas estratégias
Boa leitura e, em caso de dúvida, deixe-a nos comentários!
Cursos de programação gratuitos com certificado
Aprenda a programar e desenvolva soluções para o seu trabalho com Python para alcançar novas oportunidades profissionais. Aqui na Asimov você encontra:
- Conteúdos gratuitos
- Projetos práticos
- Certificados
- +20 mil alunos e comunidade exclusiva
- Materiais didáticos e download de código
Comentários