É possivel fechar um EA utilizando outro EA?

 

Consegui escrever um código que um EA fecha todas as ordens com o mesmo magic number e usa a função ExpertRemove() para remover todos os Eas, porém, essa função só remove 1 EA e não os dois.

Eu básicamente estou abrindo duas telas iguais de EURUSD. Em uma tela eu coloco o EA "A" e na segunda tela eu coloco o EA "B". Quando uma candle fecha o preço abaixo ou acima da váriavel PriceTest o EA "B" fecha todas as ordens e fecha somente o EA "B" o EA "A" continua em execução. Gostaria de remover os dois EA's mas a função ExpertRemove() não funciona. Alguem sabe outra forma de fazer isso?


extern int     TimeFrame = 0;
extern double  PriceTest = 0.0; 
extern double  PriceStop = 0.0; //price to close all orders and EA's
extern int     Magic=0;

extern bool    AlertAbove  = true,
               AlertBelow  = true,
               EmailAlertAbove=false,
               EmailAlertBelow=false,
               SendPushNotificationAbove=false,
               SendPushNotificationBelow=false,
               PlaySoundAbove=false,
               PlaySoundBelow=false;
extern string  SoundFileAbove="alert.wav",
               SoundFileBelow="alert2.wav";
               


int init()
  {

 if (TimeFrame==0) TimeFrame=Period();
//----
   return(0);
  }

int deinit()
  {
//----
   
//----
   return(0);
  }

int start()
  {
//----
      string msg;
      static int AlertPrevTime = 0;
      if (Time[0] <= AlertPrevTime) { 
      return;
      }
      double testclose = iClose(NULL,TimeFrame,1);
      
      if(testclose>PriceTest && PriceTest!=0 && testclose<PriceStop)
       {
        msg=Symbol() + " Price Has Closed Above "+ DoubleToStr(PriceTest,MarketInfo(Symbol(),MODE_DIGITS)) + " On "+ TimeFrame+" Minute Bar";
        if(AlertAbove)Alert(msg);
        if(EmailAlertAbove)SendMail(Symbol() + " Price Close Alert!",msg); CloseOrders(Magic); ExpertRemove();
        if(PlaySoundAbove) PlaySound(SoundFileAbove);
        if(SendPushNotificationAbove) SendNotification(msg);
        AlertPrevTime  = Time[0];
       } 
         
      if(testclose<PriceTest && PriceTest!=0 && testclose>PriceStop)
       {
        msg=Symbol() + " Price Has Close Below "+ DoubleToStr(PriceTest,MarketInfo(Symbol(),MODE_DIGITS)) + " On "+ TimeFrame+ " Minute Bar";
        if(AlertBelow)Alert(msg);
        if(EmailAlertBelow)SendMail(Symbol() + " Price Close Alert!",msg); CloseOrders(Magic); ExpertRemove();
        if(PlaySoundBelow) PlaySound(SoundFileBelow);
        if(SendPushNotificationBelow) SendNotification(msg);       
        AlertPrevTime  = Time[0];
       }
//----
  return(0);
  }
  
  int CloseOrders(int Magic)
{
  int total  = OrdersTotal();
  
  for (int cnt = total-1 ; cnt >= 0 ; cnt--)
  {
    OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
    if (OrderMagicNumber() == Magic)
    {
      if (OrderType()==OP_BUY)
      {
        OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3);
      }
      
      if (OrderType()==OP_SELL)
      {
        OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3);
      }
    }
  }
  return(0);
}
 
Seria interessante vc implementar essa estratégia em somente um EA.
 

A função ExpertRemove() realmente só vai fechar o próprio EA onde ela é executada.

Concordo com o colega acima que seria melhor e mais simples vc implementar a estratégia em 1 único EA.

Porém, se vc realmente precisar fazer um EA fechar outro, um jeito simples é criar um evento customizado (leia a documentação aqui).

Funcionaria assim:

1) O EA que for tomar a iniciativa de fechar o outro chama a função EventChartCustom() e em seguida "se suicida" chamando ExpertRemove().

2) A função  EventChartCustom() chamada pelo primeiro EA vai gerar um evento que vai acionar a função OnChartEvent() no segundo EA.

3) Dentro da função OnChartEvent() do segundo EA vc verifica o id do evento e, quando for o id do evento customizado acionado pelo primeiro EA, vc chama ExpertRemove(), o que fará o segundo EA também "se suicidar".

Dessa forma vc pode fazer um EA fechar um ou mais outros EA's.

 
Lucas Santana:

Consegui escrever um código que um EA fecha todas as ordens com o mesmo magic number e usa a função ExpertRemove() para remover todos os Eas, porém, essa função só remove 1 EA e não os dois.

Eu básicamente estou abrindo duas telas iguais de EURUSD. Em uma tela eu coloco o EA "A" e na segunda tela eu coloco o EA "B". Quando uma candle fecha o preço abaixo ou acima da váriavel PriceTest o EA "B" fecha todas as ordens e fecha somente o EA "B" o EA "A" continua em execução. Gostaria de remover os dois EA's mas a função ExpertRemove() não funciona. Alguem sabe outra forma de fazer isso?


Olá  Lucas Santana, concordo com a análise dos colegas, note que a função ExpertRemove() é um recurso de exceção, extremo, e não vejo lógica de utilizar ele como lógica de sua estratégia, ainda mais se pode tudo rodar em um único EA. Na verdade, quando você remove o EA do gráfico perde todo e qualquer controle, o que também questiono se é uma boa prática, pois se precisa fazer isso é sinal que algo não está bem no ambiente. 

Outro ponto que gostaria de comentar é que parece que você adaptou um código existente para MT4 agregando as funções "CloseOrders(Magic); ExpertRemove();" ao final de duas das linhas, e talvez essa seja sua maior dificuldade, pois se começar criando sua própria lógica não ficará dependendo de soluções de contorno como a de remover o EA para fazer o código original se comportar como deseja.

Além disso note que a própria rotina de fechamento de posições não faz nenhum teste da execução da função OrderClose(), e qualquer falha ou problema que acontecer no mundo real, com roteamento real, não existirá nenhum tratamento ou verificação, e as posições poderão ficar abertas. Nesse caso, permanentemente abertas, já que você mandaria remover o EA, ou seja, o pior dos mundos.

Dessa forma, recomendo repensar novamente todo seu código.

Sds.,
Rogério Figurelli

Razão: