Discussão do artigo "Expert Advisor multiplataforma: Sinais" - página 2

 

Obrigado, Enrico,

Estou tentando entender se posso usar um sinal como um filtro adicional para outro sinal...

Por exemplo, tenho um sinal principal e ele emite um sinal de entrada Long. Em seguida, o segundo sinal é verificado. E se ele também for longo, o sinal total será longo. Mas se o segundo sinal der Long, mas o primeiro for neutro, o sinal total também deverá ser neutro, pois o segundo sinal é apenas um filtro adicional para o primeiro sinal e não é um sinal de entrada por si só.

Além disso, existe alguma maneira de controlar o gerenciamento de dinheiro com base em um sinal específico. Por exemplo, com esse sinal, o lote seria 1, com outro sinal, o lote seria 2 e assim por diante. Em relação à minha primeira pergunta, o lote padrão seria para o primeiro sinal, mas caso haja uma confirmação do segundo sinal, o lote seria dobrado, por exemplo.

Obrigado.

 
mbjen:

Estou tentando entender se posso usar um sinal como um filtro adicional para outro sinal...

Por exemplo, tenho um sinal principal e ele emite um sinal de entrada Long. Em seguida, o segundo sinal é verificado. E se ele também for longo, o sinal total será longo. Mas se o segundo sinal der Long, mas o primeiro for neutro, o sinal total também deverá ser neutro, pois o segundo sinal é apenas um filtro adicional para o primeiro sinal e não é um sinal de entrada por si só.

Isso é possível. A maneira mais direta é combinar os dois sinais em uma única instância do descendente CSignal. Você também pode criar uma instância de CSignals dentro do descendente CSignal e fazer com que os subfiltros modifiquem o sinal pai de acordo.

mbjen:

Além disso, existe alguma maneira de controlar o gerenciamento de dinheiro com base em um sinal específico? Por exemplo, com esse sinal, o lote seria 1, com outro sinal, o lote seria 2 e assim por diante. Em relação à minha primeira pergunta, o lote padrão seria para o primeiro sinal, mas caso haja uma confirmação do segundo sinal, o lote seria dobrado, por exemplo.

Sim, isso é possível. O contêiner da instância do CSignals é uma instância do CExpertAdvisor, enquanto cada instância do CSignal tem a mesma instância do CSignals como seu pai. Você só precisa continuar obtendo o pai/contêiner até chegar à instância do CExpertAdvisor, obter o ponteiro para seu gerenciador de dinheiro e, em seguida, atribuir o método de gerenciamento de dinheiro desejado por índice ou nome.

 
Enrico Lambino:

Isso é possível. A maneira mais direta é combinar os dois sinais em uma única instância do descendente CSignal. Você também pode criar uma instância de CSignals dentro do CSignal descendente e fazer com que os subfiltros modifiquem o sinal pai de acordo.

Sim, isso é possível. O contêiner da instância do CSignals é uma instância do CExpertAdvisor, enquanto cada instância do CSignal tem a mesma instância do CSignals como seu pai. Você só precisa continuar obtendo o pai/contêiner até chegar à instância do CExpertAdvisor, obter o ponteiro para seu gerenciador de dinheiro e, em seguida, atribuir o método de gerenciamento de dinheiro desejado por índice ou nome.


Obrigado, Enrico, vou tentar fazer isso.

 

Acabei de começar a usar a estrutura de EA de plataforma cruzada.

Apliquei os indicadores TEMA e MA em um SignalTEMA_MA combinado. O Calculate e o LongCondition e ShortCondition são os seguintes. Também anexei o código do EA.


bool SignalTEMA_MA::Calculate(void)
{
   int   tema_ma_state_current=0;
   bool  ret;
   
   if(m_ma.Main(m_signal_bar) >= m_tema.Main(m_signal_bar))
      tema_ma_state_current = 1;
   else
      tema_ma_state_current = -1;

   if (m_tema_ma_state != tema_ma_state_current) {
      ret = m_tema_ma_state == 0 ? false : true;
      m_tema_ma_state = tema_ma_state_current;
   }
   else {
      ret = false;
   }
   return ret;      
}

bool SignalTEMA_MA::LongCondition(void)
  {
   return m_tema.Main(m_signal_bar) > m_ma.Main(m_signal_bar);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool SignalTEMA_MA::ShortCondition(void)
  {
   return m_tema.Main(m_signal_bar) < m_ma.Main(m_signal_bar);
  }


O EA parece funcionar, mas recebo um atraso indesejado entre o cruzamento do indicador TEMA/MA e a ordem, como pode ser visto abaixo.
Este exemplo foi feito com o período de 15 minutos do MT5 EURUSD de 4 a 6 de dezembro de 2017.

Minha pergunta é: como posso fazer com que a ordem seja inserida o mais próximo possível do cruzamento?

Depois de passar por isso, continuarei a implementar a estratégia do EA para que se torne lucrativa com condições e filtros adicionais de entrada/saída, além de gerenciamento de dinheiro.

/Karl


Arquivos anexados:
 

Oi Karl,

Você pode usar >= e <= em vez de < e > em suas condições de negociação:

bool SignalTEMA_MA::LongCondition(void)
  {
   return m_tema.Main(m_signal_bar) >= m_ma.Main(m_signal_bar);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool SignalTEMA_MA::ShortCondition(void)
  {
   return m_tema.Main(m_signal_bar) <= m_ma.Main(m_signal_bar);

No terceiro círculo destacado em sua captura de tela, o EA realizou a negociação a descoberto tarde demais. O código acima fará com que essa operação de venda entre uma barra antes.

Se você quiser que ela seja negociada na própria cruz (2 barras atrás, a vela onde está o círculo destacado), poderá usar as mesmas configurações, mas com m_signal_bar = 0 (barra atual). Isso garantiria que a negociação fosse inserida o mais próximo possível do cruzamento, mas os dados nessa barra são frequentemente repintados. Os indicadores podem ter cruzado enquanto a barra está se formando, podem manter isso até o fechamento dessa barra ou não.

 
Enrico Lambino:

Oi Karl,

Você pode usar >= e <= em vez de < e > em suas condições de negociação:

No terceiro círculo destacado em sua captura de tela, o EA realizou a negociação a descoberto tarde demais. O código acima fará com que essa operação de venda entre uma barra antes.

Se você quiser que ela seja negociada na própria cruz (2 barras atrás, a vela onde está o círculo destacado), poderá usar as mesmas configurações, mas com m_signal_bar = 0 (barra atual). Isso garantiria que a negociação fosse inserida o mais próximo possível do cruzamento, mas os dados nessa barra são frequentemente repintados. Os indicadores podem ter cruzado enquanto a barra está se formando, podem manter isso até o fechamento dessa barra ou não.


Olá, Enrico,

Muito obrigado pela resposta rápida, vou tentar suas recomendações.

/Karl

 
Karl Klang:


Oi Enrico,

Muito obrigado pela resposta rápida, vou tentar suas recomendações.

/Karl

Olá novamente, Enrico,

Fiz alguns testes neste fim de semana. Alterei as condições de negociação para >= e <=, como você disse, mas, infelizmente, a negociação não se move uma barra antes (veja o trecho abaixo)


Também tentei definir signal_bar=0. Agora ele negocia na própria cruz, mas recebo muitas negociações indesejadas, mesmo que one_trade_per_candle=true e position_reverse=true na chamada expert.Init (veja o trecho abaixo).

O arquivo de origem do Expert atual está anexado.

Arquivos anexados:
 

Talvez a condição a seguir em CExpertAdvisorBase::OnTick(void) esteja errada?

   if((checkopenlong || checkopenshort)
      && (m_every_tick || IsNewBar(m_symbol_name,m_period))
      && (!CheckPointer(m_times) || m_times.Evaluate()) 
      && (!m_one_trade_per_candle || m_last_trade_time<Time(0))
   )

Deveria ser assim?

   if((checkopenlong || checkopenshort)
      && (m_every_tick || m_last_trade_time<Time(0))
      && (!CheckPointer(m_times) || m_times.Evaluate()) 
      && (!m_one_trade_per_candle || IsNewBar(m_symbol_name,m_period))
   )


Então recebo o seguinte :



 
Karl Klang:

Talvez a condição a seguir em CExpertAdvisorBase::OnTick(void) esteja errada?

Deveria ser assim?


Então recebo o seguinte :



Olá, Karl,

Isso geralmente é um problema com indicadores como o TEMA. Os valores fornecidos por esses indicadores são tão planos que, às vezes, é muito difícil confirmar um cruzamento. Por exemplo, na sua primeira captura de tela (fundo branco), a primeira e a segunda negociações, se você observar atentamente, duas barras atrás, antes dessas negociações, o sinal ainda está na direção oposta. Isso faz com que a barra 1 candle atrás seja o primeiro candle a dar um sinal de reversão (o que resultou na negociação na barra seguinte). Quanto à terceira negociação, não posso confirmar a menos que tenhamos os valores dos indicadores impressos nos registros. Visualmente, os indicadores parecem contínuos, mas, na realidade, os dados são discretos.

Com relação a CExpertAdvisorBase::OnTick(void), certifique-se de que, se você definir a barra de sinal = 0, o consultor especialista terá m_every_tick = true. A verificação de um novo candle é diferente de manter uma única negociação por candle.

 

Olá, Enrico,

Encontrei uma maneira de lidar com a função Calcular, agora incluindo um recurso de histerese que parece funcionar quando o indicador MA e TEMA se cruzam.

No entanto, encontrei um problema com o Order Manager. Isso acontece quando executo o testador de estratégia para alguns loops durante a otimização. Nos primeiros loops, ele funciona bem, mas depois de alguns loops, uma ordem é colocada para cada candle.

Aqui funciona bem:


Mas aqui o Order Manager começa a colocar várias ordens:


Quando depurei a seguinte parte do código do COrderManager, a instrução orders_total = OrdersTotal(); torna-se 1 quando funciona, mas torna-se 0 quando falha, o que faz com que a condição if m_max_order>orders_total sempre seja avaliada como verdadeira.

bool COrderManager::TradeOpen(const string symbol,ENUM_ORDER_TYPE type,double price,bool in_points=true)
  {
   bool ret=false;
   double lotsize=0.0;
   int trades_total =TradesTotal();
   int orders_total = OrdersTotal();
   m_symbol=m_symbol_man.Get(symbol);
   if(!IsPositionAllowed(type))
      return true;
   if(m_max_orders>orders_total && (m_max_trades>trades_total || m_max_trades<=0))

Espero que você possa ajudar a resolver isso.

Atenciosamente/
Karl