Especialistas: Diff_TF_MA_EA

 

Diff_TF_MA_EA:

EA baseado no indicador Diff_TF_MA.


Autor: Scriptor

 

Em alguns pontos, ele cortava o código.

//+------------------------------------------------------------------+
//| Retorna o nome do período de tempo|
//+------------------------------------------------------------------+
string NameTimeframe(int timeframe=PERIOD_CURRENT)
  {
   if(timeframe==PERIOD_CURRENT) timeframe=Period();
   switch(timeframe)
     {
      case 1      : return "M1";
      case 2      : return "M2";
      case 3      : return "M3";
      case 4      : return "M4";
      case 5      : return "M5";
      case 6      : return "M6";
      case 10     : return "M10";
      case 12     : return "M12";
      case 15     : return "M15";
      case 20     : return "M20";
      case 30     : return "M30";
      case 16385  : return "H1";
      case 16386  : return "H2";
      case 16387  : return "H3";
      case 16388  : return "H4";
      case 16390  : return "H6";
      case 16392  : return "H8";
      case 16396  : return "H12";
      case 16408  : return "D1";
      case 32769  : return "W1";
      case 49153  : return "MN1";
      default     : return (string)(int)Period();
     }
  }
Tente isso
string NameTimeframe( const ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT )
{
  return(StringSubstr(EnumToString(timeframe == PERIOD_CURRENT ? Period() : timeframe), 7));
}
 
//+------------------------------------------------------------------+
//|| Preenche as matrizes de bilhetes de posição|
//+------------------------------------------------------------------+
void FillingListTickets(void)
  {
   list_tickets_buy.Clear();
   list_tickets_sell.Clear();
   total_volume_buy=0;
   total_volume_sell=0;
//---
   int total=PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket=PositionGetTicket(i);
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      if(PositionGetInteger(POSITION_MAGIC)!=InpMagic)   continue;
      if(PositionGetString(POSITION_SYMBOL)!=symb)       continue;
      double volume=PositionGetDouble(POSITION_VOLUME);
      if(type==POSITION_TYPE_BUY)
        {
         list_tickets_buy.Add(ticket);
         total_volume_buy+=volume;
        }
      else if(type==POSITION_TYPE_SELL)
        {
         list_tickets_sell.Add(ticket);
         total_volume_sell+=volume;
        }
     }
  }

Não há verificação de PositionGetTicket.

"else if" pode ser apenas "else".

O tipo não é obtido após o continue.

 

Não há ordens pendentes no Expert Advisor, por isso essa condição é correta apenas para POSITION_TYPE_BUY.

double price=(order_type==ORDER_TYPE_BUY ? symbol_info.Ask() : symbol_info.Bid());

Essa condição está correta apenas para POSITION_TYPE_BUY.

 
fxsaber:

Não há ordens pendentes no Expert Advisor, portanto, essa

Essa condição é correta somente para POSITION_TYPE_BUY.

Por quê?

A chamada dessa função está presente em dois lugares no código:

   //--- Abertura de posições por sinais
      if(open_long)
        {
         if(num_s>0) CloseSell();
         if(num_b==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_BUY,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_BUY,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_BUY);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_BUY,ll))
              {
               if(trade.Buy(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }
      if(open_short)
        {
         if(num_b>0) CloseBuy();
         if(num_s==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_SELL,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_SELL,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_SELL);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_SELL,ll))
              {
               if(trade.Sell(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }

Assim, se apenas o programador que escreveu esse código enviar tolamente o tipo de ordem errado para a função, então, sim, haverá um erro. No caso desse código, não haverá erro.

 
Artyom Trishkin:

Por quê?

A chamada para essa função está presente em dois lugares no código:

Dessa forma, se apenas o programador que escreveu esse código tolamente enviar o tipo de ordem errado para a função, então, sim, haverá um erro. No caso desse código, não haverá erro.

Porque pode haver uma visão diferente sobre a KB

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

MT4 ou MT5. Quais são as vantagens e desvantagens?

Renat Fatkhullin, 2018.01.31 14:28

  1. 4300 programas e 870 especialistas inclusive, no código-fonte, com conhecimento suficiente para aprender e desenvolver suas próprias ideias

Não se afirma que haverá um bug nesse caso específico. Mas as funções migram de um código para outro. Um possível erro em uma função migratória é como uma arma pendurada na parede.

Você pode, é claro, deixá-lo passar por entre seus dedos. Mas vejo aqui que é melhor avisá-lo.

 
fxsaber:

Porque pode haver uma perspectiva diferente sobre o QB


Não se afirma que haverá um bug nesse caso específico. Mas as funções migram de um código para outro. Um possível erro em uma função migratória é como uma arma pendurada na parede.

Você pode, é claro, deixá-lo passar por entre seus dedos. Mas vejo aqui que é melhor avisar.

Você está certo, o aviso está correto.
O autor provavelmente quis remover verificações desnecessárias - em alguns casos, a versatilidade é desnecessária. Você deve ter ficado confuso com a enumeração de ENUM_ORDER_TYPE. Se houvesse ENUM_POSITION_TYPE, não haveria dúvidas.

Nem sua sugestão de cortar o texto. O switch não é mais rápido?

 
Artyom Trishkin:

O autor provavelmente quis remover verificações desnecessárias - em alguns casos, a universalidade é desnecessária. Aqui você deve ter ficado confuso com a enumeração ENUM_ORDER_TYPE. Se ENUM_POSITION_TYPE estivesse lá, não haveria dúvidas.

Aqui, você deveria ter corrigido a própria função e suas chamadas. O autor não se deu conta disso totalmente desde o MT4.

Assim como sua sugestão de cortar o texto. O switch não é mais rápido?

Essas construções de switch são exatamente o que você não deve fazer. Quanto à velocidade, você não precisa dela para essa função. Mas o exemplo é realmente bastante ilustrativo. Pelo menos será interessante.

 
fxsaber:

A função em si e suas chamadas deveriam ter sido corrigidas aqui. O autor não se deu conta disso completamente desde o MT4.

Mas essas construções de troca são exatamente o que não deve ser feito. Quanto à velocidade, essa função não precisa dela de forma alguma. Mas o exemplo é realmente bastante ilustrativo. No mínimo, será interessante.

Interessante. E, em sua opinião, o que há de errado com a abordagem do cálculo padrão da distância mínima para a definição de ordens stop?

//+------------------------------------------------------------------+
//| Retorna o StopLoss correto em relação ao StopLevel
//+------------------------------------------------------------------+
double CorrectStopLoss(const ENUM_ORDER_TYPE order_type,const int stop_loss)
  {
   if(stop_loss==0) return 0;
   double pt=symbol_info.Point();
   double price=(order_type==ORDER_TYPE_BUY ? symbol_info.Ask() : symbol_info.Bid());
   int lv=StopLevel(),dg=symbol_info.Digits();
   return
   (order_type==ORDER_TYPE_BUY ?
    NormalizeDouble(fmin(price-lv*pt,price-stop_loss*pt),dg) :
    NormalizeDouble(fmax(price+lv*pt,price+stop_loss*pt),dg)
    );
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Retorna o StopLevel calculado|
//+------------------------------------------------------------------+
int StopLevel(void)
  {
   int sp=symbol_info.Spread();
   int lv=symbol_info.StopsLevel();
   return(lv==0 ? sp*size_spread : lv);
  }
//+------------------------------------------------------------------+

Não estou vendo nenhum erro aqui. Explique. E qual é a diferença entre o cálculo da distância mínima para o MT4 e o MT5?

 

Na verdade, há mais erros no código. Por exemplo, está bem demonstrado que o uso do CSymbolInfo apenas para fins de estilo SB é ruim.

Fechar posições por meio de uma lista de tíquetes previamente coletada é ruim. Esse é um erro muito comum.

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Erros, bugs, perguntas

fxsaber, 2018.01.23 09:39 pm.

Essa é a lógica errada. Após um OrderSend com falha e sucesso, o ambiente de negociação atual deve ser completamente lido novamente. Essa regra deve ser sempre aplicada.

Sobre os códigos de retorno. Eu não os analiso em meus Expert Advisors de forma alguma. Na minha opinião, a lógica de negociação não deve depender deles.

 
Artyom Trishkin:

Interessante. O que você acha que há de errado com a abordagem do cálculo padrão da distância mínima das ordens stop?

Não vejo nenhum erro aqui. Explique. E qual é a diferença entre o cálculo da distância mínima para o MT4 e o MT5?

O erro está na entrada e na chamada do enum, não na distância mínima. Mas mesmo ela é calculada incorretamente, porque

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação.

Expert Advisors: Diff_TF_MA_EA

fxsaber, 2018.02.01 21:38

Está bem demonstrado que o uso do CSymbolInfo apenas por causa do estilo SB é ruim.