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

 

Realizei um pequeno teste de estresse. Desliguei a Internet e lancei o indicador com o painel no gráfico. Já forneci os parâmetros acima. Em seguida, liguei a Internet e obtive o seguinte resultado:

CL      0       22:29:43.402    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(10) indicator (handle 10) added to the collection
OS      0       22:29:43.402    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(EURUSD,H1:10) indicator (handle 11) added to the collection
DQ      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
QL      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
IO      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
PQ      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
LN      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
KE      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
JH      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
RK      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
OD      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
CR      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
GE      0       22:30:04.495    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::OnTimer::MA(EURUSD,H1:10): Tick emulation. Attempt 1 of 3 ...
II      0       22:30:34.092    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
LD      0       22:30:34.092    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
DH      0       22:30:34.092    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
NH      0       22:30:34.093    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
RG      0       22:30:34.093    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
JM      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
KP      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
CD      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
FL      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
RK      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
OM      0       22:30:37.935    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for a new tick and when the indicator will be calculated...
PI      0       22:30:37.935    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Calculation not completed
ND      0       22:30:37.935    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
PN      2       22:30:39.604    TestMSTFMovingAverages (EURUSD,M15)     array out of range in 'TestMSTFMovingAverages.mq5' (211,34)


O indicador travou.

 

Também notei algo estranho. Gráfico M15 no USDCHF.



Se olharmos para o gráfico do USDCHF, ou melhor, para a curva vermelha do indicador MA(USDCHF, H1), então, nas últimas 7 horas, a transição para o próximo valor ocorreu aos 00 minutos 5 vezes. Eu a destaquei com verticais vermelhas. E somente nas últimas 2 horas tudo está normal. Verticais azuis. Na minha opinião, um erro claro com o preenchimento do buffer....

 
Denis Kirichenko #:

Realizei um pequeno teste de estresse. Desliguei a Internet e lancei o indicador com o painel no gráfico. Já forneci os parâmetros acima. Em seguida, liguei a Internet e obtive o seguinte resultado:


O indicador travou.

Denis Kirichenko #:

Também notei algumas coisas estranhas. Gráfico M15 do USDCHF.



Se olharmos para o gráfico do USDCHF, ou melhor, para a curva vermelha do indicador MA(USDCHF, H1), então, nas últimas 7 horas, a transição para o próximo valor ocorreu aos 00 minutos 5 vezes. Eu a destaquei com verticais vermelhas. E somente nas últimas 2 horas tudo está normal. Verticais azuis. Na minha opinião, um erro claro com o preenchimento do buffer....

Obrigado, vou dar uma olhada nisso
 
Denis Kirichenko #:

Realizei um pequeno teste de estresse. Desliguei a Internet e lancei o indicador com o painel no gráfico. Já forneci os parâmetros acima. Em seguida, liguei a Internet e obtive o seguinte resultado:


O indicador travou.

Na linha 211, na posição 34 do cursor, a matriz predefinida time[] é acessada:

DrawData(mouse_bar_index,time[mouse_bar_index]);

Acontece que o índice passado para a matriz está incorreto.

Ele dificilmente pode ser maior que rates_total-1, provavelmente é igual a -1, porque recebe seus valores no manipulador OnChartEvent pela função iBarShift(), que pode retornar -1:

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- Trabalhando com o painel
//--- Chame o manipulador de eventos do painel
   panel.OnChartEvent(id,lparam,dparam,sparam);

//--- Se o cursor se mover ou o gráfico for clicado
   if(id==CHARTEVENT_MOUSE_MOVE || id==CHARTEVENT_CLICK)
     {
      //--- Declare variáveis para armazenar as coordenadas de tempo e preço nelas
      datetime time=0;
      double price=0;
      int wnd=0;
      //--- Se as coordenadas do cursor forem convertidas em data e hora
      if(ChartXYToTimePrice(ChartID(),(int)lparam,(int)dparam,wnd,time,price))
        {
         //--- escreva o índice da barra onde o cursor está localizado na variável global
         mouse_bar_index=iBarShift(Symbol(),PERIOD_CURRENT,time);
         //--- Exibir dados de barra sob o cursor no painel
         DrawData(mouse_bar_index,time);
        }
     }

//--- Se recebermos um evento de usuário, enviaremos uma mensagem para o registro sobre ele
   if(id>CHARTEVENT_CUSTOM)
     {
      //--- Aqui pode estar o tratamento do clique do botão Fechar no painel
      PrintFormat("%s: Event id=%ld, object id (lparam): %lu, event message (sparam): %s",__FUNCTION__,id,lparam,sparam);
     }
  }


Em DrawData(), um valor de índice inválido é tratado chamando CopyRates(), que não obterá nenhum dado se o índice for negativo e, em seguida, sairá de DrawData():

//--- Se os dados da barra pelo índice especificado não puderem ser obtidos - exit
   if(CopyRates(Symbol(),PERIOD_CURRENT,index,1,rates)!=1)
      return;

Portanto, antes de acessar a matriz time[], é necessário verificar o índice da barra passado para a matriz (na linha 211):

//--- Exibir dados da barra sob o cursor no painel (ou a barra atual se o cursor estiver fora do gráfico)
   if(mouse_bar_index>WRONG_VALUE && mouse_bar_index<rates_total)
      DrawData(mouse_bar_index,time[mouse_bar_index]);


Em geral - teoria. Não testei isso, pois estou ocupado desenvolvendo a continuação do tema (buffers coloridos de vários indicadores e assim por diante). Depois que o próximo artigo sobre esse tópico for publicado, eu o verificarei e testarei (se você não o testar antes de mim com as alterações na página 211).

 
Artyom Trishkin #:

Na linha 211, a matriz predefinida time[] é acessada na posição 34 do cursor:

Parece que o índice da matriz é passado incorretamente.

Ele dificilmente pode ser maior que rates_total-1, provavelmente é igual a -1, porque recebe seus valores no manipulador OnChartEvent pela função iBarShift(), que pode retornar -1:


Em DrawData(), um valor de índice inválido é tratado chamando CopyRates(), que não obterá nenhum dado se o índice for negativo e, em seguida, sairá de DrawData():

Portanto, antes de acessar a matriz time[], é necessário verificar o índice da barra passado para a matriz (na linha 211):


Em geral - teoria. Não testei isso, pois estou ocupado desenvolvendo a continuação do tópico (buffers coloridos de vários indicadores e assim por diante). Depois que o próximo artigo sobre esse tópico for publicado, eu o verificarei e testarei (se você não o testar antes de mim com as alterações na pág. 211).

Artem, o índice da barra pode ser atual, iBarShift() retorna 0. Mas você não pode colocar menos de 1 em CopyRates(). É por isso que provavelmente devemos escrever iBarShift()+1 em qualquer variante, já que o número da barra e o número de barras não são iguais.

 
Alexey Viktorov #:

Artem, o índice da barra pode ser atual, iBarShift() retorna 0. Mas você não pode colocar menos de 1 em CopyRates(). Portanto, provavelmente deveríamos escrever iBarShift()+1 em qualquer variante, já que o número da barra e o número de barras não são iguais.

Nesse contexto: o índice é o número da barra

 
Artyom Trishkin #:

Nesse contexto: o índice é o número da barra

Artem, índice - sim, ele pode ser zero. Mas o número de elementos copiados

int  CopyRates( 
   string           symbol_name,       // nome do caractere 
   ENUM_TIMEFRAMES  timeframe,         // período 
   int              start_pos,         // onde começaremos 
   int              count,             // o quanto copiamos 
   MqlRates         rates_array[]      // matriz onde os dados serão copiados 
   );

não pode ser igual a zero.

Assim como o número de itens e o índice na lista de itens...

 
Alexey Viktorov #:

Artem, o índice - sim, ele pode ser zero. Mas o número de elementos copiados

não pode ser igual a zero.

Assim como o número de itens e o índice na lista de itens...

Bem aqui:

if(CopyRates(Symbol(),PERIOD_CURRENT,index,1,rates)!=1)

para onde aponta o índice?

 
Artyom Trishkin #:

Está bem aqui:

para onde aponta o índice?

É isso, vou me calar. Eu não olhei o código da função DrawData(mouse_bar_index,time); por isso me enganei...

 

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

Discussão do artigo "Preparando indicadores de vários símbolos e vários períodos"

Artyom Trishkin, 2023.11.01 04:46 AM

...Depois de publicar o próximo artigo sobre esse tópico, vou verificar e testar (se você não me testar antes com as alterações na página 211).


Para testar algo, você precisa estar no paradigma do que está acontecendo))

Percebi que é mais fácil para mim esboçar minha própria versão, pois não estou próximo da abordagem atual. Em particular, parece-me que a classe CIndMSTF é um tipo de superclasse. Em seguida, várias classes de indicadores são criadas com base nela. Assustador - o arquivo IndMSTF.mqh tem 4 mil linhas de código)) Optei por usar uma instância da classe CIndicators como uma coleção de indicadores . É muito conveniente. Você não precisa inventar uma bicicleta.

Então, por que a classe CIndMSTF deveria armazenar dados em buffers (SBuffer m_buffers[])? Nós os calculamos uma vez em OnCalculate() e isso é suficiente. Ou seja, aceitos como parâmetro por referência, calculados e fornecidos....

Escreverei mais tarde sobre o que não concordo quando terminar minha versão....

Sim, gosto do fato de haver esse mecanismo:

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


Artem, mais uma coisa. Se os artigos forem escritos como um manual, que há um desejo de estudar, então, na minha opinião, não há esquemas suficientes de relacionamentos dessas classes, que o desenvolvedor cria....

Então, por que colocar o código de todos os indicadores no material do artigo? Refiro-me a esta seção - "A complete list of all inheritor classes of the base class of the multisymbol multi-period indicator" (Uma lista completa de todas as classes herdeiras da classe base do indicador multiperíodo com vários símbolos).

Aqui está o início:

E aqui está o fim:


Quase 2 mil. Uau!