Discussão do artigo "Preparação de indicadores com vários símbolos/períodos"

 

Novo artigo Preparação de indicadores com vários símbolos/períodos foi publicado:

Neste artigo, examinaremos os princípios para criar indicadores com vários símbolos/períodos e recuperar dados deles dentro de EAs e indicadores. Veremos as nuances mais importantes ao usar multi-indicadores em EAs e indicadores, e sua plotagem mediante buffers de indicador personalizado.

Após a compilação do indicador de teste, vamos executá-lo em um gráfico com o período M1, nas configurações escolheremos o símbolo atual e o período de cálculo do indicador M5. Neste caso, serão criados dois indicadores de médias móveis selecionados nas configurações. Um será calculado com base nos dados do gráfico atual, e o outro com base nos dados do período gráfico de cinco minutos. Alternando o timeframe do gráfico, será possível ver como no M1 são desenhadas duas linhas: uma corresponderá à média móvel calculada no M1, e a outra à média móvel calculada no M5. Se mudarmos o gráfico para M5, apenas um indicador será criado, pois o segundo será idêntico ao primeiro e não será criado. Se mudarmos o gráfico para M15, um indicador será calculado no M15, e o outro no M5, e também será exibido no gráfico.


Como podemos ver, a funcionalidade anunciada funciona ao exibir no janela principal do gráfico indicadores com um buffer.

Autor: Artyom Trishkin

 

Obrigado ao autor. Há algo em que pensar...

Na minha opinião, se a classe for básica, seu nome deveria ser CBaseIndMSTF. Ou até mesmo CBaseIndMSMTF. MSMTF - multi-symbol multi-timeframe.

Por nome.

ENUM_IND_CATEGORY é bom.

Os seguintes não são tão bons.

ENUM_COMPARE_MODE --> ENUM_IND_COMPARE_MODE

ENUM_LINE_STATE --> ENUM_IND_LINE_STATE

ENUM_ERR_TYPE --> ENUM_IND_CALC_ERR_TYPE


enum ENUM_ERR_TYPE            // Tipo de erro nos cálculos do indicador
  {
   ERR_TYPE_NO_ERROR,         // Nenhum erro
   ERR_TYPE_NO_CYNC,          // Dados não sincronizados
   ERR_TYPE_NO_DATA,          // Dados não carregados
   ERR_TYPE_NO_CALC,          // Cálculo não concluído
  };

ERR_TYPE_NO_CYNC --> ERR_TYPE_NO_SYNC

 
Denis Kirichenko multi-symbol multi-timeframe.

Por nomes.

ENUM_IND_CATEGORY é adequado.

Os seguintes não são bons.

ENUM_COMPARE_MODE --> ENUM_IND_COMPARE_MODE

ENUM_LINE_STATE --> ENUM_IND_LINE_STATE

ENUM_ERR_TYPE --> ENUM_IND_CALC_ERR_TYPE


ERR_TYPE_NO_CYNC --> ERR_TYPE_NO_SYNC

Concordo comeste. Os outros são específicos

 
para sincronizar/ sincronizar
 
Denis Kirichenko #:
to sync/to synchronize

Não consigo entender isso. Dois "s" estão destacados, e daí?

"No Sync" - não sincronizado. O que há de errado? "Error: No Synchronized" (Erro: Não sincronizado)

Aaah!

Eu vi C em vez de S no último minuto... Ok. Obrigado. Vou consertar isso.

 

Artem, executei o indicador TestMSTFMovingAverages no gráfico EURUSD. Dia de folga. Tf1 = M15, Tf2 = H1.

Parâmetros de entrada:

InpIndicator=26
InpSymbol=
InpTimeframe=16385
InpPrice=1
InpMethod=0
InpShift=0
InpAsSeries=true

O resultado foi o seguinte:

Registros:

HD      0       20:22:12.149    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(10) indicator (handle 10) added to the collection
PJ      0       20:22:12.150    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(EURUSD,H1:10) indicator (handle 11) added to the collection
CG      0       20:22:12.179    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Start downloading data by EURUSD/H1. Waiting for the next tick...
OG      0       20:22:12.179    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data not loaded
HQ      0       20:22:12.179    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
QH      0       20:22:12.224    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::DataToBuffer::MA(EURUSD,H1:10) First start, or historical data has been changed. Initialize Buffer(0)


Destacou a vela às 23:00 com uma cruz. Você pode ver que a linha vermelha da SMA10 altera seu valor somente na próxima vela após as 23:00. Ou seja, temos uma transição de valores às 23:00 e 23:15.

No meu entendimento, a transição do valor atual para o próximo valor no Tf2 deve ocorrer às22:45 e 23:00.


Então, foi isso que obtive. Executei o indicador SMA10 com offset = 1 em um gráfico EURUSD-H1 separado.

Abro um novo gráfico e executo o TestMSTFMovingAverages. E, por milagre, vejo que a imagem parece estar corrigida.


Registros:

2023.10.29 20:38:42.583 TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(10) indicator (handle 10) added to the collection
2023.10.29 20:38:42.584 TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(EURUSD,H1:10) indicator (handle 11) added to the collection
2023.10.29 20:38:42.622 TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::DataToBuffer::MA(10) First start, or historical data has been changed. Initialize Buffer(0)
2023.10.29 20:38:42.654 TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::DataToBuffer::MA(EURUSD,H1:10) First start, or historical data has been changed. Initialize Buffer(0)


E tanto no primeiro caso quanto no segundo caso, no painel às 23:00, o valor de MA(EURUSD,H1:10) = 1,056959. O que, na minha opinião, está correto. Aparentemente, no primeiro caso, algo está errado com o preenchimento do buffer para MA(EURUSD,H1:10).

 
Denis Kirichenko gráfico EURUSD-H1 separado.

Abri um novo gráfico e executei o TestMSTFMovingAverages. E, por milagre, vejo que a imagem parece estar corrigida.


Registros:


Além disso, tanto no primeiro caso quanto no segundo caso no painel às 23:00, o valor de MA(EURUSD,H1:10) = 1,056959. O que, na minha opinião, está correto. Aparentemente, no primeiro caso, algo está errado com o preenchimento do buffer para MA(EURUSD,H1:10).

Obrigado, Denis. Vou dar uma olhada mais tarde - estou ocupado continuando este tópico e, infelizmente, ainda não tenho tempo.
 

...При работе с данными не текущего графика для исключения "освобождения" таймсерии, необходимо не реже. чем раз в две минуты обращаться к этой таймсерии. В этом случае будет происходить "удержание" таймсерии, что ускорит к ней обращение (не нужно будет каждый раз дожидаться синхронизации данных)...

Como você obteve esse valor de frequência? Ele foi determinado experimentalmente?

 
Denis Kirichenko #:

Como você obteve esse valor de frequência? Ele foi determinado experimentalmente?

Mensagem dos desenvolvedores no fórum.

 

Essa estrutura existe:

//--- struct
struct SBuffer                // Estrutura do buffer do indicador
  {
   double            array[];    // Buffer de matriz de indicadores
   double            init_value; // Inicialização do valor
   int               shift;      // Deslocar o buffer horizontalmente
   string            descript;   // Descrição do buffer
   //--- (1) Define, (2) retorna o valor de inicialização,
   void              SetInitValue(const double value) { init_value=value;                             }
   double            InitValue(void)                  { return init_value;                            }
   //--- (1) Define, (2) Retorna o deslocamento do buffer
   void              SetShift(const int value)        { shift=value;                                  }
   int               Shift(void)                      { return shift;                                 }
//--- (1) Altera o tamanho da matriz do buffer, (2) retorna o tamanho da matriz do buffer,
//--- (3) inicializa a matriz com o valor "vazio" definido
   bool              BuffResize(const int new_size)   { return(ArrayResize(array,new_size)==new_size);}
   uint              BufferSize(void)                 { return array.Size();                          }
   int               InitBuffer(void)                 { return ArrayInitialize(array,init_value);     }
  };

Como existem set\get-methods, então, na minha opinião, o especificador de acessoprivado está faltando:

//--- struct
struct SBuffer                // Estrutura do buffer do indicador
   {
   private:
      double            array[];    // Buffer de matriz de indicadores
      double            init_value; // Inicialização do valor
      int               shift;      // Deslocar o buffer horizontalmente
      string            descript;   // Descrição do buffer
   public:
      //--- (1) Define, (2) retorna o valor de inicialização,
      void              SetInitValue(const double value)
         {
         init_value = value;
         }
      double            InitValue(void)
         {
         return init_value;
         }
      //--- (1) Define, (2) Retorna o deslocamento do buffer
      void              SetShift(const int value)
         {
         shift = value;
         }
      int               Shift(void)
         {
         return shift;
         }
//--- (1) Altera o tamanho da matriz do buffer, (2) retorna o tamanho da matriz do buffer,
//--- (3) inicializa a matriz com o valor "vazio" definido
      bool              BuffResize(const int new_size)
         {
         return(ArrayResize(array, new_size) == new_size);
         }
      uint              BufferSize(void)
         {
         return array.Size();
         }
      int               InitBuffer(void)
         {
         return ArrayInitialize(array, init_value);
         }
   };


E também precisamos de métodos para trabalhar com o buffer...

 
Denis Kirichenko #:

Essa estrutura existe:

Como existem set\get-methods, então, na minha opinião, o especificador de acessoprivado está faltando:


E também precisamos de métodos para trabalhar com o buffer...

Inicialmente, tentei não complicar as coisas.