[Dúvida] Como realizar operações em diferentes EA's, em diferentes ativos, no mesmo tempo?

 

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:


  if(PositionsTotal() == 0 && OrdersTotal() == 0){
   if(Trade.Sell(Contratos, Symbol(), 0.00, 0.000, 0.000, NULL)){
    addTakeStop(Stop_Loss, Take_Profit);
         }


Agradeço mais uma vez pela atenção e pela eventual ajuda.


Atenciosamente,

Christian Alves

 
Christian Alves:

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...


. . .

 
Vinicius de Oliveira #:


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

 
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!!

 
Vinicius de Oliveira #:


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

 
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 CheckCloseLongCheckCloseShort 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.

 
Vinicius de Oliveira #:


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 CheckCloseLongCheckCloseShort 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).

 
Vinicius de Oliveira #:


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 CheckCloseLongCheckCloseShort 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.

Vinicius de Oliveira #:




... 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

 
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!!

 
Christian Alves:

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.