Olá senhoras e senhores, bom dia, boa tarde ou boa noite!
Venho cá novamente retirar uma dúvida que me veio em mente enquanto trabalho em meus filhotes por aqui na esperança de que algum ser iluminado possa me auxiliar com meu problema!
Utilizo os códigos PositionsTotal() == 0 e OrdersTotal() == 0 para que meus EA's não realizem duplas operações caso ele encontre o sinal para nova entrada e já exista uma negociação em aberto, porém, ao utilizar estes códigos, isso impossibilita que outro robô execute ordens nesta mesma máquina, pois uma vez que existe uma ordem de um robô x em aberto, caso o robô y esteja com estes códigos, a entrada não será realizada pois PositionsTotal e OrdersTotal != 0 neste momento. Estou testando vários EA's de uma vez e gostaria de saber como posso fazer com que essas duplas entradas não ocorram e que de certo modo isso também não interfira nas entradas de outros robôs.
Segue abaixo a maneira na qual eu utilizo os códigos:
Agradeço mais uma vez pela atenção e pela eventual ajuda.
Atenciosamente,
Christian Alves
Bom dia Christian!!
Para os EAs poderem negociar simultaneamente e sem conflitos você deve utilizar um identificador para as operações. O identificador mais utilizado é o MAGIC NUMBER. Veja exemplos abaixo de como gerenciar suas ordens/posições utilizando o MN:
//+------------------------------------------------------------------+ //| Testes2.mq5 | //| Copyright 2022, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" //=== Classes #include <Trade\Trade.mqh> CTrade m_trade; //--- Funções de negociação //=== Define constants #define MAGIC 11 //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Set Magic Number m_trade.SetExpertMagicNumber(MAGIC); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Local variables int Cnt, pos_nr = 0, ord_nr = 0; ulong TICKET; // . . . //--- Checks orders for(Cnt = OrdersTotal() - 1; Cnt >= 0; Cnt --) { TICKET = OrderGetTicket(Cnt); if(TICKET == 0) { Print("Failed to get order ticket..."); return; } if(OrderGetString(ORDER_SYMBOL) == _Symbol && OrderGetInteger(ORDER_MAGIC) == MAGIC) { //--- Increase the orders number ord_nr ++; if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP) { //--- Checks if deletes/modify pending order // . . . //--- Decrease the orders number ord_nr --; //--- (Caso a ordem seja excluída) } else { if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP) { //--- Checks if deletes/modify pending order // . . . //--- Decrease the orders number ord_nr --; //--- (Caso a ordem seja excluída) } } } } // . . . //--- Checks positions for(Cnt = PositionsTotal() - 1; Cnt >= 0; Cnt --) { //--- Gets the ticket and selects the position TICKET = PositionGetTicket(Cnt); if(TICKET == 0) { Print("Failed to get position ticket..."); return; } if(PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MAGIC) { //--- Increase the positions number pos_nr ++; //--- Checks POSITION_TYPE_BUY if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { //--- Checks if closes position if(CheckCloseLong()) { // . . . //--- Decrease the positions number pos_nr --; //--- (Caso a posição seja encerrada) } else { //--- Checks trailing stop loss // . . . } } //--- POSITION_TYPE_SELL else { //--- Checks if closes position if(CheckCloseShort()) { // . . . //--- Decrease the positions number pos_nr --; //--- (Caso a posição seja encerrada) } else { //--- Checks trailing stop loss // . . . } } } } // . . . //--- Open position - Buy if(pos_nr == 0) { if(!m_trade.Buy(Lot, _Symbol, ASK, SL, TP, COMMENT)) { Print(m_trade.ResultRetcode(), " ", m_trade.ResultRetcodeDescription()); return; } } // . . . //--- Open position - Sell if(pos_nr == 0) { if(!m_trade.Sell(Lot, _Symbol, BID, SL, TP, COMMENT)) { Print(m_trade.ResultRetcode(), " ", m_trade.ResultRetcodeDescription()); return; } } } //+------------------------------------------------------------------+
... É comum também deixar o MN como parâmetro de entrada, ou ainda, se preferir, calcular automaticamente (em OnInit) de acordo com o timeframe que o EA está sendo executado...
EDIT.: Adicionadas as variáveis ord_nr e pos_nr ao código, como uma forma de contar ordens/posições do EA...
. . .
Bom dia Christian!!
Para os EAs poderem negociar simultaneamente e sem conflitos você deve utilizar um identificador para as operações. O identificador mais utilizado é o MAGIC NUMBER. Veja exemplos abaixo de como gerenciar suas ordens/posições utilizando o MN:
... É comum também deixar o MN como parâmetro de entrada, ou ainda, se preferir, calcular automaticamente (em OnInit) de acordo com o timeframe que o EA está sendo executado...
EDIT.: Adicionadas as variáveis ord_nr e pos_nr ao código, como uma forma de contar ordens/posições do EA...
. . .
Boa tarde Vinicius! Tudo certo por ai? Espero que sim!
Obrigado mais uma vez por responder um de meus tópicos criados no fórum, agradeço-lhe por toda ajuda até então! Através da sua ideia comecei a pesquisar mais a respeito do magic number, e através disso cheguei a um vídeo no qual encontrei em um comentário (sim, eu fuço em tudo que é possível) a ideia de utilizar o código PositionSelect para identificar posição aberta de x ativo, e deu certo!
Segue o código que utilizei:
PositionSelect(_Symbol); if(PositionsTotal() == 0){ if(Trade.Buy(Contratos, Symbol(), 0.00, 0.000, 0.000, NULL)){ addTakeStop(Stop_Loss, Take_Profit); } }
Muito obrigado Vini, pois as pesquisas que realizei a respeito do magic number foram apenas possíveis devido ao compartilhamento de vosso conhecimento, e através dele consegui achar outra alternativa que atendia aos resultados em que eu esperava!
Tenha um ótimo fim de tarde por ai, grande abraço!
Atenciosamente,
Christian Alves
Boa tarde Vinicius! Tudo certo por ai? Espero que sim!
Obrigado mais uma vez por responder um de meus tópicos criados no fórum, agradeço-lhe por toda ajuda até então! Através da sua ideia comecei a pesquisar mais a respeito do magic number, e através disso cheguei a um vídeo no qual encontrei em um comentário (sim, eu fuço em tudo que é possível) a ideia de utilizar o código PositionSelect para identificar posição aberta de x ativo, e deu certo!
Segue o código que utilizei:
Muito obrigado Vini, pois as pesquisas que realizei a respeito do magic number foram apenas possíveis devido ao compartilhamento de vosso conhecimento, e através dele consegui achar outra alternativa que atendia aos resultados em que eu esperava!
Tenha um ótimo fim de tarde por ai, grande abraço!
Atenciosamente,
Christian Alves
Olá, Christian!!
Depois que você postou a solução é que fui observar mais atentamente o título do tópico onde você fala "em diferentes ativos"... Realmente, se cada EA negocia um ativo diferente, a solução postada acima é a mais prática, identificando as operações apenas por SÍMBOLO. Mas pra quem utiliza 2 ou mais EAs simultaneamente e que podem negociar (também) o mesmo ativo, então, nesse caso, será necessário utilizar um outro identificador das operações (além do símbolo) para que não haja conflitos entre os EAs (apenas esclarecendo para outras pessoas que possam estar começando e tenham interesse pelo tema).
Mas, Christian, o importante é que você encontrou uma resposta para a sua pergunta e compartilhou aqui a sua solução para ajudar outras pessoas que, agora ou futuramente, venham a ter a mesma dúvida...
Tenha uma boa noite, grande abraço!!
Olá, Christian!!
Depois que você postou a solução é que fui observar mais atentamente o título do tópico onde você fala "em diferentes ativos"... Realmente, se cada EA negocia um ativo diferente, a solução postada acima é a mais prática, identificando as operações apenas por SÍMBOLO. Mas pra quem utiliza 2 ou mais EAs simultaneamente e que podem negociar (também) o mesmo ativo, então, nesse caso, será necessário utilizar um outro identificador das operações (além do símbolo) para que não haja conflitos entre os EAs (apenas esclarecendo para outras pessoas que possam estar começando e tenham interesse pelo tema).
Mas, Christian, o importante é que você encontrou uma resposta para a sua pergunta e compartilhou aqui a sua solução para ajudar outras pessoas que, agora ou futuramente, venham a ter a mesma dúvida...
Tenha uma boa noite, grande abraço!!
Bom dia Vinicius, tudo bem?
Cara, acabei escrevendo em minha resposta que havia encontrado a solução através do código, porém acredito que misturei as coisas e, ao testar no dia de ontem ao vivo, percebi que quando um robô tinha uma posição em aberta, os outros ainda assim não realizavam operações, portanto voltei a estaca 0 para este problema. Estou tentando interpretar os códigos que você encaminhou a cima mas estou com algumas dificuldades, vou tentar estudar um pouco mais a respeito do magic_number e de como utiliza-lo de fato!
Obrigado pelas palavras de qualquer maneira, tenha um ótimo dia por ai, abração!
EDIT: O que seriam essas funções "CheckCloseLong" e "CheckCloseShort"?
Atenciosamente
Christian Alves
Bom dia Vinicius, tudo bem?
Cara, acabei escrevendo em minha resposta que havia encontrado a solução através do código, porém acredito que misturei as coisas e, ao testar no dia de ontem ao vivo, percebi que quando um robô tinha uma posição em aberta, os outros ainda assim não realizavam operações, portanto voltei a estaca 0 para este problema. Estou tentando interpretar os códigos que você encaminhou a cima mas estou com algumas dificuldades, vou tentar estudar um pouco mais a respeito do magic_number e de como utiliza-lo de fato!
Obrigado pelas palavras de qualquer maneira, tenha um ótimo dia por ai, abração!
EDIT: O que seriam essas funções "CheckCloseLong" e "CheckCloseShort"?
Atenciosamente
Christian Alves
Bom dia, Christian!!
Que pena que AINDA não deu certo, mas vai dar... 😊
Esse exemplo que eu postei acima seria um modelo um pouco mais completo para gerenciamento de ordens e posições. As funções CheckCloseLong e CheckCloseShort você teria que criar, e nelas você verificaria, de acordo com os seus critérios, se pelas condições atuais do mercado a posição deveria ser encerrada (CheckCloseLong analisa se encerra posições de compra; CheckCloseShort analisa se encerra posições de venda).
Mas, focando apenas no tema em questão (deixando a parte de gerenciamento mais pra frente), talvez você precise apenas do código abaixo:
//=== Classes #include <Trade\Trade.mqh> CTrade m_trade; //--- Funções de negociação //=== Define constants #define MAGIC 11 //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Set Magic Number m_trade.SetExpertMagicNumber(MAGIC); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Local variables int Cnt, pos_nr = 0, ord_nr = 0; ulong TICKET; // . . . //--- Checks orders for(Cnt = OrdersTotal() - 1; Cnt >= 0; Cnt --) { TICKET = OrderGetTicket(Cnt); if(TICKET == 0) { Print("Failed to get order ticket..."); return; } if(OrderGetString(ORDER_SYMBOL) == _Symbol && OrderGetInteger(ORDER_MAGIC) == MAGIC) { //--- Increase the orders number ord_nr ++; break; } } // . . . //--- Checks positions for(Cnt = PositionsTotal() - 1; Cnt >= 0; Cnt --) { //--- Gets the ticket and selects the position TICKET = PositionGetTicket(Cnt); if(TICKET == 0) { Print("Failed to get position ticket..."); return; } if(PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MAGIC) { //--- Increase the positions number pos_nr ++; break; } } // . . . //--- Open position - Buy if(pos_nr == 0) { if(!m_trade.Buy(Lot, _Symbol, ASK, SL, TP, COMMENT)) { Print(m_trade.ResultRetcode(), " ", m_trade.ResultRetcodeDescription()); return; } } // . . . //--- Open position - Sell if(pos_nr == 0) { if(!m_trade.Sell(Lot, _Symbol, BID, SL, TP, COMMENT)) { Print(m_trade.ResultRetcode(), " ", m_trade.ResultRetcodeDescription()); return; } } }
No caso, claro, pra cada EA você define um valor diferente pro MAGIC...
Qualquer dúvida, poste aí... 😊👍
EDIT.: se pos_nr > 0, já existe posição aberta; se ord_nr > 0, já existe ordem colocada.
Bom dia, Christian!!
Que pena que AINDA não deu certo, mas vai dar... 😊
Esse exemplo que eu postei acima seria um modelo um pouco mais completo para gerenciamento de ordens e posições. As funções CheckCloseLong e CheckCloseShort você teria que criar, e nelas você verificaria, de acordo com os seus critérios, se pelas condições atuais do mercado a posição deveria ser encerrada (CheckCloseLong analisa se encerra posições de compra; CheckCloseShort analisa se encerra posições de venda).
Mas, focando apenas no tema em questão (deixando a parte de gerenciamento mais pra frente), talvez você precise apenas do código abaixo:
No caso, claro, pra cada EA você define um valor diferente pro MAGIC...
Qualquer dúvida, poste aí... 😊👍
EDIT.: se pos_nr > 0, já existe posição aberta; se ord_nr > 0, já existe ordem colocada.
... E, Christian, se quiser utilizar apenas o PositionSelect(), tente o seguinte:
if(!PositionSelect(_Symbol)) { if(!Trade.Buy(Contratos, _Symbol, 0.00, Stop_Loss, Take_Profit, NULL)) { Print(Trade.ResultRetcode(), " ", Trade.ResultRetcodeDescription()); return; } }
... Acho que funciona também (se cada EA negocia um ativo diferente).
Bom dia, Christian!!
Que pena que AINDA não deu certo, mas vai dar... 😊
Esse exemplo que eu postei acima seria um modelo um pouco mais completo para gerenciamento de ordens e posições. As funções CheckCloseLong e CheckCloseShort você teria que criar, e nelas você verificaria, de acordo com os seus critérios, se pelas condições atuais do mercado a posição deveria ser encerrada (CheckCloseLong analisa se encerra posições de compra; CheckCloseShort analisa se encerra posições de venda).
Mas, focando apenas no tema em questão (deixando a parte de gerenciamento mais pra frente), talvez você precise apenas do código abaixo:
No caso, claro, pra cada EA você define um valor diferente pro MAGIC...
Qualquer dúvida, poste aí... 😊👍
EDIT.: se pos_nr > 0, já existe posição aberta; se ord_nr > 0, já existe ordem colocada.
... E, Christian, se quiser utilizar apenas o PositionSelect(), tente o seguinte:
... Acho que funciona também (se cada EA negocia um ativo diferente).
Bom dia Vinicius, tudo certo por ai? Espero que sim!
Fiquei um tempo testando o código aqui no simulador ao vivo para ver se de fato estava dando certo, e cara, funcionou! Usei o conceito do magic number, porém fiz um pouco diferente do que você mandou, mas acredito que conceitualmente é a mesma coisa, segue o que fiz abaixo para que isso ajude também outras pessoas que tiverem esta mesma dúvida:
//=========GLOBAL========== #include <Trade\Trade.mqh> CTrade Trade; input ulong magic_number = 456; //Magic Number bool posAberta; //Verificar posição aberta int OnInit() { Trade.SetExpertMagicNumber(magic_number); return(INIT_SUCCEEDED); } void OnTick() { //=============================GreenGo================================== posAberta = false; for(int i = PositionsTotal()-1; i>=0; i--) { string symbol_trade = PositionGetSymbol(i); ulong magic = PositionGetInteger(POSITION_MAGIC); if(symbol_trade == _Symbol && magic == magic_number) { posAberta = true; break; } } if(posAberta == false) { if(...) Trade.Buy(Contratos, Symbol(), 0.00, 0.000, 0.000, NULL); } }
Agradeço mais uma vez por ter me ajudado com vosso conhecimento meu irmão, tenha um ótimo dia por ai e uma boa semana! Abração.
Atenciosamente,
Christian Alves
Bom dia Vinicius, tudo certo por ai? Espero que sim!
Fiquei um tempo testando o código aqui no simulador ao vivo para ver se de fato estava dando certo, e cara, funcionou! Usei o conceito do magic number, porém fiz um pouco diferente do que você mandou, mas acredito que conceitualmente é a mesma coisa, segue o que fiz abaixo para que isso ajude também outras pessoas que tiverem esta mesma dúvida:
Agradeço mais uma vez por ter me ajudado com vosso conhecimento meu irmão, tenha um ótimo dia por ai e uma boa semana! Abração.
Atenciosamente,
Christian Alves
Beleza, Christian!! Fica melhor mesmo com o identificador magic number, mais completo...
Grande abraço e boa semana!!
Olá senhoras e senhores, bom dia, boa tarde ou boa noite!
Venho cá novamente retirar uma dúvida que me veio em mente enquanto trabalho em meus filhotes por aqui na esperança de que algum ser iluminado possa me auxiliar com meu problema!
Utilizo os códigos PositionsTotal() == 0 e OrdersTotal() == 0 para que meus EA's não realizem duplas operações caso ele encontre o sinal para nova entrada e já exista uma negociação em aberto, porém, ao utilizar estes códigos, isso impossibilita que outro robô execute ordens nesta mesma máquina, pois uma vez que existe uma ordem de um robô x em aberto, caso o robô y esteja com estes códigos, a entrada não será realizada pois PositionsTotal e OrdersTotal != 0 neste momento. Estou testando vários EA's de uma vez e gostaria de saber como posso fazer com que essas duplas entradas não ocorram e que de certo modo isso também não interfira nas entradas de outros robôs.
Segue abaixo a maneira na qual eu utilizo os códigos:
Agradeço mais uma vez pela atenção e pela eventual ajuda.
Atenciosamente,
Christian Alves
Depois de ver que o pessoal te ajudou com a questão dos identificadores, eu fico na dúvida se voce conseguiu realizar as operações com robos diferentes no mesmo ativo conforme queria. Me pergunto isso por causa que ninguem chamou atenção para o fato de esse comportamento necessitar de contar hedging e não a conta netting (que é a mais habitual). Na conta hedging, cada posição vai ser mantida separada e, com isso, cada robo consegue identificar a sua conforme espera. Já na conta netting, o que vai acontecer é que se um segundo robo vier operar o mesmo ativo esta atualização de posição muda o identificador de toda a posicao para essa última.
- 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
Olá senhoras e senhores, bom dia, boa tarde ou boa noite!
Venho cá novamente retirar uma dúvida que me veio em mente enquanto trabalho em meus filhotes por aqui na esperança de que algum ser iluminado possa me auxiliar com meu problema!
Utilizo os códigos PositionsTotal() == 0 e OrdersTotal() == 0 para que meus EA's não realizem duplas operações caso ele encontre o sinal para nova entrada e já exista uma negociação em aberto, porém, ao utilizar estes códigos, isso impossibilita que outro robô execute ordens nesta mesma máquina, pois uma vez que existe uma ordem de um robô x em aberto, caso o robô y esteja com estes códigos, a entrada não será realizada pois PositionsTotal e OrdersTotal != 0 neste momento. Estou testando vários EA's de uma vez e gostaria de saber como posso fazer com que essas duplas entradas não ocorram e que de certo modo isso também não interfira nas entradas de outros robôs.
Segue abaixo a maneira na qual eu utilizo os códigos:
Agradeço mais uma vez pela atenção e pela eventual ajuda.
Atenciosamente,
Christian Alves