Discussão do artigo "LifeHack para traders: preparemos "fast-food" de indicadores" - página 3

 
Renat Fatkhullin:

...começa a fazer chamadas com parâmetros diferentes, multiplica indicadores, perde todas as alças e depois se pergunta sobre freios e consumo de memória.

Para ser sincero, não entendi como se pode perder um controle, se ele é armazenado nos bastidores do MetaTrader.

p.s. Em geral, deixe que o autor do artigo participe da discussão e explique alguns pontos sobre sua visão do trabalho com alças de indicadores no MT5.

 
Vasiliy Sokolov:
Para ser sincero, nunca entendi como se pode perder um controle se ele for memorizado nos bastidores do MetaTrader.

Com essa abordagem da qualidade do código, não tenho mais dúvidas.

 
Vasiliy Sokolov:

Não está claro o que você quer dizer com o que falou. Pelo que entendi, os hendles não são fechados em lugar algum( não háchamadas para IndicatorRelease ). Há uma chamada constante para funções padrão de criação de hendles, como iMACD:

Obviamente, todo o jogo aqui se baseia no fato de que o iMACD e funções semelhantes armazenam em cache dentro de si o identificador retornado anteriormente, portanto, não deve haver recriação do indicador.


Sim, eu tive uma ideia inicial para mostrar que em MQL5 você deve trabalhar com indicadores de uma maneira elegante: um identificador deve ser criado em OnInit(), e o acesso aos dados do indicador deve ser obtido por meio de funções CopyXXXX, e se você usar o estilo MQL4 de recriação de identificadores, isso é muito errado e será um desastre: ele vai consumir memória. Mas, durante o processo, descobriu-se que o kernel MQL5 é tão inteligente (obviamente, há um cache interno de handles idênticos) que não permite a recriação de handles.

O efeito colateral é que o kernel da MQL5 é tão bem projetado que permite que a MQL5 funcione de uma forma não moderna.

 
Vasiliy Sokolov:

Não vi nenhuma semelhança.

Ambos os artigos oferecem a mesma coisa: escrever a variante mais simples do estilo MQL4 em MQL5. Compare isso

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

Discussão do artigo "LifeHack para trader: cozinhar fast food a partir de indicadores"

Vassiliy Sokolov, 2018.01.25 16:05

//+------------------------------------------------------------------+
//| Função iMACD em notação MQL4|
//| Os números do buffer são os seguintes: |
//| MQL4 0 - MODE_MAIN, 1 - MODE_SIGNAL|
//| MQL5 0 - MAIN_LINE, 1 - SIGNAL_LINE|
//+------------------------------------------------------------------+
double   iMACD(
               string                     symbol,              // nome do símbolo 
               ENUM_TIMEFRAMES            timeframe,           // período de tempo 
               int                        fast_ema_period,     // período para o cálculo da média rápida 
               int                        slow_ema_period,     // período para cálculo da média lenta 
               int                        signal_period,       // período para o cálculo da média das diferenças 
               ENUM_APPLIED_PRICE         applied_price,       // tipo de preço ou alça 
               int                        buffer,              // buffer 
               int                        shift                // deslocamento
               )
  {
   
   double result=NaN;
//---
   int handle=iMACD(symbol,timeframe,fast_ema_period,slow_ema_period,signal_period,applied_price);
   if(handle==INVALID_HANDLE)
     {
      Print(__FUNCTION__,": INVALID_HANDLE error=",GetLastError());
      return(result);
     }
   double val[1];
   int copied=CopyBuffer(handle,buffer,shift,1,val);
   if(copied>0)
      result=val[0];
   else
      Print(__FUNCTION__,": CopyBuffer error=",GetLastError());
   return(result);
  }

e isso

double iMACDMQL4(string symbol,
                 int tf,
                 int fast_ema_period,
                 int slow_ema_period,
                 int signal_period,
                 int price,
                 int mode,
                 int shift)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   ENUM_APPLIED_PRICE applied_price=PriceMigrate(price);
   int handle=iMACD(symbol,timeframe,
                    fast_ema_period,slow_ema_period,
                    signal_period,applied_price);
   if(handle<0)
     {
      Print("Объект iMACD не создан: Ошибка ",GetLastError());
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,mode,shift));
  }

De fato, é a mesma coisa.

Eles deveriam estar presentes? Acho que o título do artigo (ou melhor, sua descrição) diz claramente apenas sobre indicadores?

Não deveriam, a julgar pelo título. Mas o artigo aborda o trabalho no estilo MQL4 com séries temporais. E, sem isso, temos uma solução incompleta. Quase todo mundo usa "High[i]" em MQL4. Além disso, sua implementação é fácil de encontrar.

Infelizmente, o MQL não oferece suporte a funções com um número arbitrário de parâmetros, portanto, não é possível implementar o iCustom "exatamente como no MT4"

Não acho que seja possível escrever um mecanismo completo que emule totalmente o estilo do MT4 em um único artigo. O tópico foi claramente definido: trabalhar com indicadores no estilo MQL4 (é uma pena que o título do artigo não reflita o tópico, o que é confuso).

O estilo MQL4 ainda é um conceito, mas não uma adesão clara à sintaxe.

 
Vladimir Karputov:

Se você usar a recriação de alças no estilo MQL4, isso é muito errado e causará problemas: a memória será consumida.

É por isso que surge a pergunta: por que eles implementaram um trabalho incorreto quando ele poderia ser feito corretamente e no estilo da MQL4?

A MQL5 não é inteligente, ela apenas tem uma proteção infalível. Caso contrário, qualquer erro acidental levaria a consequências infelizes. Mas a proteção infalível, como mostram as medições de desempenho, foi projetada de tal forma que há uma falha no desempenho. É por isso que é necessário transferir a "recriação do identificador" para o wrapper MQL5, ocultando-o (uma pequena parte dos recursos de OOP) dos olhos do usuário.

 
fxsaber:

... Mas também a proteção contra falhas, como mostram as medições de desempenho, é feita de tal forma que há uma queda no desempenho...

Sim, isso é interessante. Vou medir a velocidade e publicar minhas descobertas aqui.

 
Vasiliy Sokolov:

Medi-lo no mais simples dos espaços em branco.

Nome do especialistaDescrição do desempenhoDesempenho
iMACDtrabalho clássico de hendle no estilo MT5EURUSD,M5: 26189141 ticks, 74266 barras geradas. Ambiente sincronizado em 0:00:01.045. O teste foi aprovado em 0:00:12.121 (incluindo o pré-processamento de ticks em 0:00:01.966).
EA curto no estilo MACD MQL4Trabalho no estilo MQL4EURUSD,M5: 26189141 ticks, 74266 barras geradas. Ambiente sincronizado em 0:00:00.047. Teste aprovado em 0:00:34.960 (incluindo o pré-processamento de ticks em 0:00:01.872).

A sobrecarga é cerca de três vezes. Portanto, sim, o MetaTrader 5 leva muito tempo para encontrar um identificador em cache.


Tive uma ideia para testar isso: um EA semelhante ao"MACD MQL4 style EA short", só que nele você pode abordar não dois, mas três, quatro, cinco indicadores .... Nesse contexto, "indicador" significa (usando o MACD como exemplo) um indicador com parâmetros diferentes, mas com um símbolo cada.

 

Excluí minha postagem anterior porque percebi que o EA estilo MACD MQL4 acessa adicionalmente o subsistema gráfico:

//+------------------------------------------------------------------+
//| Função de tique de especialista|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double macd_main_1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MAIN_LINE,1);
   Comment("MACD, main buffer, index 1: ",DoubleToString(macd_main_1,Digits()+1));
  }

Ou seja, o teste feito foi realizado incorretamente. Depois de comentar a função Comment, o desempenho é quase igual:

EURUSD,M5: 26189141 ticks, 74266 bars generated. Environment synchronized in 0:00:00.047. Test passed in 0:00:15.444 (including ticks preprocessing 0:00:01.872).

Conclusões: O MetaTrader 5 ainda encontra efetivamente o cache criado anteriormente e é possível usar o estilo de código proposto.

fxsaber:

Mas a proteção infalível, como mostram as medições de desempenho, é feita de tal forma que há uma falha de desempenho. É por isso que é necessário transferir a "recriação do identificador" para o wrapper MQL5, ocultando-o (uma pequena parte dos recursos de OOP) dos olhos do usuário.

Se o último teste for realizado corretamente, verifica-se que a mudança para o wrapper OOP não fará nada. As velocidades são praticamente iguais.
 
Vasiliy Sokolov:

O MetaTrader 5 requer bastante tempo para encontrar um controle em cache.

Não há certeza de que um usuário possa acelerar esse processo de forma geral. Obviamente, a sobrecarga é gasta no cálculo da função hash.

Uma variante de tal função de hash de indicador em uma forma geral foi postada aqui

  static string GetMyUniqueName( void )
  {
    const int handle = GetMyHandle();

    MqlParam Params[];
    ENUM_INDICATOR Type;

    const int Total = ::IndicatorParameters(handle, Type, Params);
    ::IndicatorRelease(handle);

    uchar Bytes[];

    for (int i = 1; i < Total; i++)
    {
      ::ArrayCopy(Bytes, _R(Params[i].double_value).Bytes, ::ArraySize(Bytes));
      ::ArrayCopy(Bytes, _R(Params[i].integer_value).Bytes, ::ArraySize(Bytes));
      ::ArrayCopy(Bytes, _R(Params[i].string_value).Bytes, ::ArraySize(Bytes));
    }

    return("::" + (string)::ChartID() + (string)INIT_SYNC::crc64(Bytes) + ::MQLInfoString(MQL_PROGRAM_NAME));
  }

Não me preocupei com o desempenho, mas ficou claro que qualquer entrada de função hash deve ser uma matriz de valores MqlParam. E isso não pode funcionar rapidamente, levando em conta o fato de que há um campo de string lento.

Portanto, escrever uma função hash rápida de indicador universal muito mais rápida do que a incorporada ao MT5 é uma tarefa em aberto. Mas sou categoricamente contra chamar indicadores de algum lugar. É por isso que nem quero entender a questão.


Há outro pensamento sobre a MQL5 inteligente. Há muitos Expert Advisors, onde o mesmo indicador é chamado em cada barra, mas com diferentes parâmetros de entrada. A MQL5 "dispara" alças desnecessárias ao longo do tempo. Mas essa é uma solução universal. E em um Expert Advisor, o autor pode assumir essa responsabilidade, eliminando as alças por si mesmo. É óbvio que é um grande desperdício em termos de recursos computacionais e de memória carregar a bagagem de uma centena de alças em uma centena de barras. Mas não vi EAs no mesmo kodobase que conseguiriam eliminar uma alavanca como essa. Tudo é dado à "inteligência da MQL5", forçando assim os autores a não serem nada inteligentes.


Mas, novamente, indicadores e barras são ruins.

 
fxsaber:

Não há certeza de que um usuário possa acelerar esse processo de forma geral. Obviamente, a sobrecarga é gasta no cálculo da função hash.

Uma variante de tal função de hash de indicador em uma forma geral foi publicada aqui


Bem, você queria despejar muitas informações sobre o leitor em um único artigo. Mas com relação ao seu método - é uma solução direta, você já tentou outras? E comparou o desempenho?