Discussão do artigo "Expert Advisor Multiplataforma: Stops"

 

Novo artigo Expert Advisor Multiplataforma: Stops foi publicado:

Este artigo discute uma implementação dos níveis de stop em um expert advisor para torná-lo compatível com as duas plataformas - MetaTrader 4 e MetaTrader 5.

O funcionamento geral da criação dos níveis de stop é exibido na figura a seguir:

Operação geral de criação dos níveis de stop

Autor: Enrico Lambino

 

Qual método deve ser usado para definir SL/TP para um valor específico, mas não como uma distância do preço de abertura?

 
Esses seriam os métodos StopLossCustom e TakeProfitCustom. Esses métodos serão discutidos no próximo artigo.
 

Tentei usar alguns stops em meu EA. Adicionei sua função manage_trades() e foi isso que obtive após a ativação do último stop (posição fechada):

2017.09.10 09:48:25.706 2017.01.03 17:50:23   failed market buy 0.00 EURUSD [Invalid volume]
2017.09.10 09:48:25.706 2017.01.03 17:50:23   CTrade::OrderSend: market buy 0.00 EURUSD [invalid volume]
2017.09.10 09:48:25.706 2017.01.03 17:50:23   position #2  is already closed, closing object..
2017.09.10 09:48:25.706 2017.01.03 17:50:23   failed market buy 0.00 EURUSD [Invalid volume]
2017.09.10 09:48:25.706 2017.01.03 17:50:23   CTrade::OrderSend: market buy 0.00 EURUSD [invalid volume]
2017.09.10 09:48:25.707 2017.01.03 17:50:23   position #2  is already closed, closing object..
2017.09.10 09:48:25.707 2017.01.03 17:50:23   failed market buy 0.00 EURUSD [Invalid volume]
2017.09.10 09:48:25.707 2017.01.03 17:50:23   CTrade::OrderSend: market buy 0.00 EURUSD [invalid volume]

Usando 3 stops, todos eles virtuais.

Isso tem a ver com o lote. Eu uso o lote fixo 0,1. Após o primeiro fechamento, o volume restante é de 0,06. Após o último fechamento (stop principal sem volume especificado), recebo o erro acima.

Quando o lote é maior, está tudo bem. O mesmo acontece com seus exemplos de EA.

 
mbjen:

Tentei usar alguns stops em meu EA. Adicionei sua função manage_trades() e foi isso que obtive após a ativação do último stop (posição fechada):

Usando 3 stops, todos eles virtuais.

Isso tem a ver com o lote. Eu uso o lote fixo 0,1. Após o primeiro fechamento, o volume restante é de 0,06. Após o último fechamento (stop principal sem volume especificado), recebo o erro acima.

Quando o lote é maior, está tudo bem. O mesmo acontece com seus exemplos de EA.

Verifique se você está usando a versão mais recente da biblioteca (a que está anexada neste artigo). Além disso, se você puder anexar o código-fonte do seu EA aqui, isso seria de grande ajuda.

 
Enrico Lambino:

Certifique-se de que esteja usando a versão mais recente da biblioteca (a que está anexada neste artigo). Além disso, se você puder anexar o código-fonte do seu EA aqui, isso será de grande ajuda.


Sim, atualizei todos os arquivos com a versão anexada a este artigo. Mas não sei se você o atualizou novamente.

Você poderia tentar com seu exemplo stops_ha_ma2 alterando o MM para lote fixo e alterando o tamanho do lote para um valor pequeno?

 
mbjen:

Sim, atualizei todos os arquivos com o anexo a este artigo. Mas não sei se você o atualizou mais uma vez.

Você poderia tentar com seu exemplo stops_ha_ma2 alterando o MM para lote fixo e alterando o tamanho do lote para um valor pequeno?

Você poderia postar aqui o código-fonte do EA que está apresentando o problema? Nossa conversa é pública, e o erro que você postou acima é um problema sério para um EA. Gostaria que outros leitores também aprendessem com essa conversa, dando-lhes a oportunidade de testar seu código.
 
Enrico Lambino:
Você poderia postar aqui o código-fonte do EA que está apresentando o problema? Nossa conversa é pública, e o erro que você publicou acima é um problema sério para um EA. Gostaria que outros leitores também aprendessem com essa conversa, dando-lhes a oportunidade de testar seu código.

O problema não está relacionado ao meu EA, pois obtive o mesmo erro com seu EA. De qualquer forma, eu o instalei em outra cópia do terminal e ele está funcionando bem agora. Não há mais erros. Talvez houvesse algo errado com minha biblioteca padrão ou algo mais...

Obrigado.

 
mbjen:

Não está relacionado ao meu EA, pois obtive o mesmo erro com seu EA. De qualquer forma, eu o instalei em outra cópia do terminal e está tudo certo agora. Não há mais erro. Talvez houvesse algo errado com minha biblioteca padrão ou algo mais...

Com um EA modificado feito a partir de partes de um dos EAs de exemplo. Inicialmente, fiquei imaginando o que havia de errado com seu código. Mas como você mencionou que não há erros agora, não tenho certeza do que causou o problema que você teve. Se você encontrar o problema novamente, avise-me aqui ou por MP.
 

Olá, Enrico,


Só gostaria de salientar que encontrei alguns erros em seu código. No ExpertAdvisorBase, a função Time está como abaixo;

datetime CExpertAdvisorBase::Time(const int index=0)
  {
   if(index>=0)
     {
      double time[];
      if(CopyTime(m_symbol_name,m_period,index,1,time)>0)
         return(time[0]);
     }
   return(-1);
  }

O tipo de tempo acima é double em vez de datetime.

datetime CExpertAdvisorBase::Time(const int index=0)
  {
   if(index>=0)
     {
      datetime time[];
      if(CopyTime(m_symbol_name,m_period,index,1,time)>0)
         return(time[0]);
     }
   return(-1);
  }

Além disso, a função Evaluate do TimesBase não passa o valor padrão;

bool CTimesBase::Evaluate(datetime current) const

Se for alterada para o valor abaixo, deverá ser;

bool CTimesBase::Evaluate(datetime current) const

Ao compilar a pasta Base\Order, os arquivos geram muitos erros.

Por exemplo, a função CreateStops no OrderBase, abaixo;

void COrderBase::CreateStops(CStops *stops)
  {
   if(!CheckPointer(stops)) return;
   if(stops.Total()>0)
     {
      for(int i=0;i<stops.Total();i++)
        {
         CStop *stop=stops.At(i);
         if(CheckPointer(stop)==POINTER_INVALID) continue;
         m_order_stops.NewOrderStop(GetPointer(this),stop);
        }
     }
  }

Lança 'operator=' - nenhuma das sobrecargas pode ser aplicada à chamada da função OrderBase.mqh

'At' - ponteiro de objeto esperado OrderBase.mqh

O Base\Stop também apresenta os mesmos problemas de lançamento de vários erros relacionados a Stops, Types etc.

Obrigado por seu bom trabalho, Shep

 
Oi Shep,
Shephard Mukachi:

Olá, Enrico,


Só gostaria de salientar que encontrei alguns erros em seu código. No ExpertAdvisorBase, a função Time está como abaixo;

Quando deveria ser como abaixo. O tipo de tempo acima é double em vez de datetime.

Shephard Mukachi:

Olá, Enrico,


Além disso, a função Evaluate do TimesBase não passa o valor padrão;

Se for alterada para o valor abaixo, ela deverá passar;

Obrigado por apontar esses problemas. Eu não havia notado isso até agora. Atualizarei o código.

Shephard Mukachi:

Ao compilar a pasta Base\Order, os arquivos geram muitos erros.

Por exemplo, a função CreateStops em OrderBase, abaixo;

Lança 'operator=' - nenhuma das sobrecargas pode ser aplicada à chamada da função OrderBase.mqh

'At' - ponteiro de objeto esperado OrderBase.mqh

O Base\Stop também apresenta os mesmos problemas de lançamento de vários erros relacionados a Stops, Types etc.

Obrigado por seu bom trabalho, Shep

Sim, estou ciente disso. Isso ainda se deve às declarações de encaminhamento. O CStop requer instâncias de COrder e COrderStop em seus métodos. O mesmo acontece quando você tenta compilar o CStop. Todas essas classes que requerem umas às outras devem ser compiladas juntas. Haveria erros se cada uma fosse compilada isoladamente. Por exemplo:

class Object1
{
public:
   Object2 *m_object2;
   Object1(){}
  ~Object1(){}
};

class Object2
{
public:
   Object1 *m_object1;
   Object2(){}
  ~Object2(){}
};

Isso não será compilado. Você precisa fazer uma declaração forward para que o compilador reconheça o membro da classe m_object2 dentro da classe object1:

class Object2;
class Object1
{
public:
   Object2 *m_object2;
   Object1(){}
  ~Object1(){}
};

class Object2
{
public:
   Object1 *m_object1;
   Object2(){}
  ~Object2(){}
};

Isso é aceitável se Object1 e Object2 estiverem no mesmo arquivo. Se eles estiverem em dois arquivos separados, você precisará fazer uma declaração forward para Object2 no arquivo de classe de Object1 e para Object1 no arquivo de classe Object 2. Isso é verdade, até que você adicione métodos a uma das duas classes.

A versão atual do compilador reconhece as declarações de encaminhamento, mas não os métodos listados da classe declarada de forma encaminhada. É por isso que você não recebe mensagens de erro como "CStop - declaração sem tipo", mas recebe mensagens de erro do compilador para os métodos, como o que você postou acima. O compilador reconhece a classe, mas não os métodos da classe que foi declarada antecipadamente.