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

 
Karl Klang:

Oi Enrico,

Descobri uma maneira de lidar com a função Calcular, que agora inclui 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 seja sempre avaliada como verdadeira.

Espero que você possa me ajudar a resolver isso.

Com os melhores cumprimentos/
Karl

Olá, Karl,

Nunca encontrei esse problema antes. O método OrdersTotal() simplesmente conta o número de objetos COrder ativos. Se houver algo errado com a estratégia codificada, isso deverá ser corrigido. Caso contrário, deve haver algum problema na forma como as instâncias de ordem são gerenciadas (criadas/destruídas) e/ou como são contadas. Eu o informarei assim que me deparar com esse problema.

 

Olá, Enrico,

Uma pesquisa no Google sobre problemas com o OrdersTotal() do mt5 revela que outras pessoas também têm problemas. Por exemplo testador de estratégia com essa estratégia. O Expert Set também foi carregado para que você possa executar o testador de estratégia com a mesma entrada que eu fiz.

Atenciosamente/
Karl

How to use the OrdersTotal() correctly?
How to use the OrdersTotal() correctly?
  • 2010.09.09
  • www.mql5.com
I tried many times to check OrdersTotal(), but I found it did not work...
 
Karl Klang:

Oi Enrico,

Uma pesquisa no Google sobre problemas com o OrdersTotal() do mt5 revela que outras pessoas também têm problemas. Por exemplo testador de estratégia com essa estratégia. O Expert Set também foi carregado para que você possa executar o testador de estratégia com a mesma entrada que eu fiz.

Com os melhores cumprimentos/
Karl

Obrigado pelos arquivos, Karl. Encontrei o problema que você está descrevendo.

No arquivo de inclusão principal, altere este (OnInit):

file.Open(savefile,FILE_READ);
if(!experts.Load(file.Handle()))
   return(INIT_FAILED);
file.Close();

para isto:

#ifdef __MQL5__
if (!(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION)))
#else
if (!(IsTesting() || IsOptimization()))
#endif
{
   file.Open(savefile,FILE_READ);
   if(!experts.Load(file.Handle()))
      return(INIT_FAILED);
   file.Close();
}


E isto (OnDeinit):

file.Open(savefile,FILE_WRITE);
experts.OnDeinit(reason,file.Handle());
file.Close();

para isto:

#ifdef __MQL5__
if (!(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION)))
#else
if (!(IsTesting() || IsOptimization()))
#endif
{
  file.Open(savefile,FILE_WRITE);
  experts.OnDeinit(reason,file.Handle());
  file.Close();
}

Por algum motivo, os dados salvos de sessões anteriores estão sendo recarregados para sessões futuras. É por isso que o problema só existe após o backtest inicial, às vezes com algum vazamento de memória. Com base em meus testes, o problema parece existir somente no modo de compensação, não no modo de cobertura do MT4 ou do MT5. Mas informe-me se você continuar a ter esse problema. O código acima impede o carregamento e o salvamento de dados durante o backtesting e a otimização (esqueci de mencionar isso ao escrever o artigo final).

 

Além disso, com relação ao OrdersTotal() no MT5, ele conta apenas as ordens pendentes (não o equivalente ao OrdersTotal do MT4). O código no TradeOpen para o OrderManager:

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();

usa o método OrdersTotal() da classe, que é apenas um wrapper do método COrders (também com o mesmo nome). COrders estende CArrayObj, portanto, não está realmente usando a função OrdersTotal() nativa do MT5. O que foi dito acima também é equivalente a usar:

int orders_total = this.OrdersTotal();

Por outro lado, se usarmos:

int orders_total = ::OrdersTotal();

isso chama explicitamente a função nativa do MT5. É possível que você já esteja familiarizado com isso, mas apenas para o caso de outras pessoas encontrarem um problema semelhante.

 

Obrigado, Enrico. O problema desapareceu.

/Karl

 
Enrico Lambino:
#ifdef __MQL5__
if (!(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION))) // Código MQL4, não apenas MQL5.
#else
if (!(IsTesting() || IsOptimization()))
#endif
MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION) == MQLInfoInteger(MQL_TESTER)
 
fxsaber:
Estou vendo. Sim, você está certo.
 

Olá, Enrico,

No Github, em iceron/MQLx, há um aviso de alteração de m_new_signal e m_new_signal_close.

O m_signal_new pode ser alterado pelo método void CSignalsBase::NewSignal(const bool value), mas não há nenhum método disponível para alterar o m_new_signal_close.

Você poderia explicar melhor o uso de m_new_signal e m_new_signal_close?

   if(m_invert)
     {
      CSignal::SignalInvert(m_signal_open);
      CSignal::SignalInvert(m_signal_close);
     }
   if(m_new_signal)
     {
      if(m_signal_open==m_signal_open_last)
         m_signal_open = CMD_NEUTRAL;      
     }
   if(m_new_signal_close)
     {
      if(m_signal_close==m_signal_close_last)
         m_signal_close = CMD_NEUTRAL;      
     }

Com os melhores cumprimentos/

Carlos

iceron - Overview
iceron - Overview
  • github.com
Sign up for your own profile on GitHub, the best place to host code, manage projects, and build software alongside 36 million developers. Sign up
 

Esses métodos funcionam com seu MT5Bridge?

 

Olá, mestres!

Estou com um problema sério para entender a "contagem de velas" (primeiro, segundo, terceiro = idx, idx++, ...) no código de sinal Mql a seguir, que pertence à classe SignalAC.

Alguém poderia me ajudar a penetrar no número idx ao mover os códigos para baixo?

Desde já agradeço.

//+------------------------------------------------------------------+
//| "Votando" que o preço crescerá.|
//+------------------------------------------------------------------+
int CSignalAC::LongCondition(void)
  {
   int result=0;
   int idx   =StartIndex();
//--- se a primeira barra analisada for "vermelha", não "vote" na compra
   if(DiffAC(idx++)<0.0)
      return(result);
//--- a primeira barra analisada é "verde" (o indicador não faz objeções à compra)
   if(IS_PATTERN_USAGE(0))
      result=m_pattern_0;
//--- se a segunda barra analisada for "vermelha", não há condição de compra
   if(DiffAC(idx)<0.0)
      return(result);
//--- a segunda barra analisada é "verde" (a condição para compra pode ser cumprida)
//--- se a segunda barra analisada for menor que zero, precisamos analisar a terceira barra
   if(AC(idx++)<0.0)
     {
      //--- se a terceira barra analisada for "vermelha", não há condição de compra
      if(DiffAC(idx++)<0.0)
         return(result);
     }
//--- há uma condição para a compra
   if(IS_PATTERN_USAGE(1))
      result=m_pattern_1;
//--- se a barra analisada anteriormente for "vermelha", a condição de compra acaba de ser cumprida
   if(IS_PATTERN_USAGE(2) && DiffAC(idx)<0.0)
      result=m_pattern_2;
//--- retornar o resultado
   return(result);
  }