Boa noite,
Senhores,
Estou tentando utilizar o método Buy para criar uma ordem no metatrader, porém ao utilizar a função a mesma cria duas ordens iguais, sendo que a função está sendo chamada apenas 1 vez para que seja criada apenas uma ordem.
Em anexo segue o trecho do código que estou utilizando e também uma imagem do testador de estratégia com o resultado da execução.
Se alguém souber como me ajudar, ficarei grato.
Sua premissa está errada.
O mundo Real nunca é o que acontece nos testes, você não pode fazer esse checking no OnTick(). Volte pra prancheta e estude sobre o que realmente faz o OnTick() e quando ele é executado.
Depois estude sobre o OnTradeTransaction().
Sua premissa está errada.
O mundo Real nunca é o que acontece nos testes, você não pode fazer esse checking no OnTick(). Volte pra prancheta e estude sobre o que realmente faz o OnTick() e quando ele é executado.
Depois estude sobre o OnTradeTransaction().
Boa noite,
Flávio,
Sou um iniciante no desenvolvimento de softwares com mql 5 para Experts Trader, vindo de outra área de desenvolvimento focada no ramo industrial. Sou grato pelo comentário e pela informação, mesmo que um tanto quanto abrupta.
Já que a minha premissa está errada, poderia ao menos me indicar um caminho/direção para executar de melhor forma ?
Obrigado pela atenção, por enquanto um abraço!
Olá Felipe,
primeiro uma observação, a premissa é que 99,99% o erro é de código, ou seja não é do compilador ou computador...
Então vamos ao erro, você emitiu duas ordens de compra.
1º no Trade(buy)
2º no OrderSend()
Anexa o fonte, Alt-S e cole o código, vou arrumar as coisas para você dar mais uns passos.Olá Rogerio,
Boa tarde, obrigado pelo comentário.
Em relação ao erro, estou utilizando apenas o método trade.buy da biblioteca CTrade, ao abrir o fonte da biblioteca percebi que a mesma sempre utiliza o método trade.PositionOpen para realizar a ordem do tipo a mercado mesmo que eu esteja utilizando trade.Buy, fazendo está chamada internamente na biblioteca. O que ainda não entendi é como ele realiza as duas operações através do trade.Buy e outra através do OrderSend() como mencionou.
Segue o código,
Grato pela, resposta e pelo auxilio.
//+------------------------------------------------------------------+ //| Teste.mq5 | //| Filipe Lopes | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Filipe Lopes" #property link "https://www.mql5.com" #property version "1.00" #include <Trade\Trade.mqh> CTrade trade; bool realizaOp = false; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- create timer EventSetTimer(60); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- destroy timer EventKillTimer(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { MqlTradeRequest mrequest; MqlTradeResult mresult; if(!realizaOp) { trade.SetAsyncMode(false); trade.SetDeviationInPoints(5); trade.SetExpertMagicNumber(1234); trade.LogLevel(2); trade.SetTypeFilling(ORDER_FILLING_FOK); trade.Buy(5,_Symbol,PRICE_HIGH,NULL,NULL,"Order"); trade.Request(mrequest); trade.Result(mresult); if(!OrderSend(mrequest, mresult)) { PrintFormat("Erro em OrderSend: %d", GetLastError()); PrintFormat("Código de Retorno: %d", mresult.retcode); } if(trade.ResultRetcode() == 10009 || trade.ResultRetcode() == 10008) { Print("Operação realizada. Ticket#: " + IntegerToString(mresult.order) + " Volumes: " + DoubleToString(mresult.volume, 0) + " TakeProfit: " + DoubleToString(mrequest.tp, _Digits) + " StopLoss: " + DoubleToString(mrequest.sl, _Digits)); } else { Print("Operação NÃO realizada. Erro: " + IntegerToString(GetLastError()) + " Volumes: " + DoubleToString(mresult.volume, 0) + " TakeProfit: " + DoubleToString(mrequest.tp, _Digits) + " StopLoss: " + DoubleToString(mrequest.sl, _Digits)); ResetLastError(); } realizaOp = true; } } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- } //+------------------------------------------------------------------+ //| Trade function | //+------------------------------------------------------------------+ void OnTrade() { //--- } //+------------------------------------------------------------------+ //| TradeTransaction function | //+------------------------------------------------------------------+ void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) { //--- } //+------------------------------------------------------------------+
Bom dia Felipe,
você precisa estudar, leia o manual e passe a usar os termos corretos para cada conceito.
...
A Biblioteca padrão do MQL5 é um conjunto de classes e a CTrade é uma classe para facilitar o acesso às funções de negociação.
...
OrderSend()
A função OrderSend() é usada para a execução de operações de negociação enviando solicitações para um servidor de negociação.
...
CTrade Buy()
Buy é o método da classe CTrade para abrir posições compradas. Se você leu o fonte deve ter observado que o Buy() chama o método PositionOpen(), no método PositionOpen() é preparado a estrutura do pedido de negociação ( mrequest ) e é chamada a função de negociação OrderSend().
...
CTrade Request()
Request é o método que obtém a cópia da última estrutura de pedido de negociação.
Eu acho que agora dá para você enxergar que no seu código você copiou a estrutura do pedido preparada no BUY(...) e emitiu um segunda ordem de compra no OrderSend(...)
No fonte abaixo eu só fiz por no lugar os métodos que você usou e tenho algumas observações quando for operar na B3.
Evite modo "Async". O parâmetro DevitationPoint é inúltil pois as ordens são a mercado. O modo de preenchimento FOK só a XP aceita.
//+------------------------------------------------------------------+ //| Teste.mq5 | //| Filipe Lopes | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Filipe Lopes" #property link "https://www.mql5.com" #property version "1.00" #include <Trade\Trade.mqh> CTrade trade; MqlTradeRequest mrequest; MqlTradeResult mresult; bool realizaOp = false; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { trade.SetAsyncMode(false); trade.SetDeviationInPoints(5); trade.SetExpertMagicNumber(1234); trade.LogLevel(2); trade.SetTypeFilling(ORDER_FILLING_FOK); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(!realizaOp) { trade.Buy(5, _Symbol, PRICE_HIGH, NULL, NULL, "Order"); if(trade.ResultRetcode() == 10009 || trade.ResultRetcode() == 10008) { Print("Operação realizada. Ticket#: " + IntegerToString(mresult.order) + " Volumes: " + DoubleToString(mresult.volume, 0) + " TakeProfit: " + DoubleToString(mrequest.tp, _Digits) + " StopLoss: " + DoubleToString(mrequest.sl, _Digits)); } else { Print("Operação NÃO realizada. Erro: " + IntegerToString(GetLastError()) + " Volumes: " + DoubleToString(mresult.volume, 0) + " TakeProfit: " + DoubleToString(mrequest.tp, _Digits) + " StopLoss: " + DoubleToString(mrequest.sl, _Digits)); ResetLastError(); } realizaOp = true; } } //+------------------------------------------------------------------+
Bom dia Rogerio,
Obrigado por todo auxilio e pela distribuição do seu conhecimento, após sua ultima resposta entendi como estava sendo realizada a segunda ordem através do OrderSend(), ao retirar o trecho do código que utilizava a função OrderSend() o mesmo já funcionou como queria realizando apenas uma operação.
Obrigado também pela reestruturação do código, desta forma consigo enxergar melhor onde devemos declarar e definir certas coisas. Grato!
Quanto a alguns parâmetros citados, o parâmetro DevitationPoint estou utilizando por que pretendo utilizar outros tipos de ordens dentro do código não apenas ordens a mercado, o parâmetro SetTypeFilling no momento estou utilizando desta forma pois ao ler o manual vi que se enquadraria mais na forma que quero trabalhar e também atualmente estou utilizando a corretora XP. Qual seria outro parâmetro útil para abranger um número maior de corretoras ?
Por enquanto obrigado por todo auxilio e atenção, sou grato!
Deixo aqui também como resolvido este tópico no escopo inicial, não sei se tem como marcar como resolvido aqui no fórum.
Obrigado! :)
Olá Rogerio,
Boa tarde, obrigado pelo comentário.
Em relação ao erro, estou utilizando apenas o método trade.buy da biblioteca CTrade, ao abrir o fonte da biblioteca percebi que a mesma sempre utiliza o método trade.PositionOpen para realizar a ordem do tipo a mercado mesmo que eu esteja utilizando trade.Buy, fazendo está chamada internamente na biblioteca. O que ainda não entendi é como ele realiza as duas operações através do trade.Buy e outra através do OrderSend() como mencionou.
Segue o código,
Grato pela, resposta e pelo auxilio.
- 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
Boa noite,
Senhores,
Estou tentando utilizar o método Buy para criar uma ordem no metatrader, porém ao utilizar a função a mesma cria duas ordens iguais, sendo que a função está sendo chamada apenas 1 vez para que seja criada apenas uma ordem.
Em anexo segue o trecho do código que estou utilizando e também uma imagem do testador de estratégia com o resultado da execução.
Se alguém souber como me ajudar, ficarei grato.