Erros, bugs, perguntas - página 3027

 
Сергей Таболин:

Os indicadores são o meu ponto mais fraco ))))

Mas!

Ou não percebo nada, ou está um pouco enganado.

Tanto quanto sei, o pré-cálculo é um contador de dados não-calculados. E, uma vez contados os dados recebidos, esse contador é reiniciado. Tipo, é isso, meu, não há mais dados novos para calcular.... )))

E por que razão o indicador deve recalcular completamente em tal caso - não sei!

---------------

Mentiu um pouco ))))

Não são os indicadores que são recalculados, mas os "índices" são recalculados para que fiquem "bonitos" na história ;)

o contador é reiniciado por razões fora do controlo do programador, como se o indicador tivesse sido iniciado pela primeira vez!

Não gostaria que a minha mensagem se perdesse no meio de explicações incompreensíveis, mas finalmente chegou aos criadores.



Precisamos de notar a ligação entre o valor retornado por OnCalculate() e o segundo parâmetro de entrada pré_calculado. Ao chamar a função, o parâmetro pré_calculado contém um valor devolvido pela OnCalculate() na chamada anterior. Isto permite algoritmos económicos para calcular o indicador personalizado, a fim de evitar cálculos repetidos para as barras que não mudaram desde a chamada anterior desta função.

-esta é da documentação. Um cálculo que não funciona correctamente quebra todo o conceito de cálculos económicos.
 
Andrey Dik:
O contador é reiniciado por razões fora do controlo do programador, como se o indicador estivesse a funcionar pela primeira vez!

Não queria que a minha mensagem se perdesse nos aplausos incompreensíveis, mas chegou aos estimados criadores.

É assim em todos os bares novos? Eles estão a ser tranquilizados, não estão?

Se não for cada barra, há diferentes razões para reiniciar o pré_calc.

 

Fórum sobre comércio, sistemas automatizados de comércio e testes de estratégia comercial

Insectos, insectos, perguntas

Andrey Dik, 2021.05.27 13:53

isto é, o contador pré_calculado é zerado assim que a nova barra de tempo aparece. isto significa que o indicador é recalculado novamente como se tivesse sido lançado pela primeira vez.

é uma construção tão familiar para si?

if (rates_total == prev_calculated) return rates_total;
  
int startInd = rates_total - prev_calculated;

for (int i = startInd; i >= 0; i--)
{
  //тут считаем индикатор, который обращается к другому индикатору на старшем ТФ
}

o problema não está na lógica da EA (redesenhar, não redesenhar, subdesenhar ou o que quer que seja) mas no facto de que o pré_cálculo é reiniciado enquanto ninguém lhe pede para o fazer!

Penso que o problema é:

if (rates_total == prev_calculated) return rates_total;

Não se deixa o indicador chamado noutro TF calcular cada tick, e depois chama-o e o histórico é sincronizado e o cálculo a partir do zero desse indicador


criei um teste. o indicador chamado conta tudo e não reinicia para pré_calculado == 0

Fechei no indicador e desenrolei o evento com uma nova barra e prev_calculei == 0 :

// tst.mq5

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   int start;
   static datetime t = 0;
   if(t != time[rates_total-1])
   {
      t = time[rates_total-1];
      Print(MQLInfoString(MQL_PROGRAM_NAME), " New bar ", t);
   }
   
   if(prev_calculated == 0)
   {
      start = 0;
      ArrayInitialize(Buffer, EMPTY_VALUE);
      Print(MQLInfoString(MQL_PROGRAM_NAME), " prev_calculated == 0");
   }
   else start = prev_calculated - 1;


   for(int i = start; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}

chame este indicador (obtenha os 2 últimos valores do tampão) e também se aproxime da sua TF:

input ENUM_TIMEFRAMES TF = PERIOD_M5;
int OnInit()
{
//--- indicator buffers mapping
   SetIndexBuffer(0, Buffer, INDICATOR_DATA);
   ind_handle = iCustom(NULL, TF, "NewFolder\\tst");
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   int start;
   static datetime t = 0;
   if(t != time[rates_total-1])
   {
      t = time[rates_total-1];
      Print(MQLInfoString(MQL_PROGRAM_NAME), " New bar ", t);
   }

   if(prev_calculated == 0)
   {
      start = 0;
      ArrayInitialize(Buffer, EMPTY_VALUE);
      Print(MQLInfoString(MQL_PROGRAM_NAME), " prev_calculated == 0");
   }
   else start = prev_calculated - 1;


   for(int i = start; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }
   double buf[];
   if(CopyBuffer(ind_handle, 0, 0, 2, buf) < 0) Print("Error CopyBuffer # ",GetLastError());
//--- return value of prev_calculated for next call
   return(rates_total);
}


correu o último indicador no M1 , log:

2021.05.27 21:48:34.196 tst_tf (EURUSD,M1) tst_tf Novo bar 2021.05.27 21:48:00

2021.05.27 21:48:34.197 tst_tf (EURUSD,M1) tst_tf prev_calculado == 0

2021.05.27 21:48:34.197 tst_tf (EURUSD,M1) Error CopyBuffer # 4806

2021.05.27 21:48:34.197 tst (EURUSD,M5) tst Novo bar 2021.05.27 21:45:00

2021.05.27 21:48:34.197 tst (EURUSD,M5) tst prev_calculado == 0

2021.05.27 21:49:01.636 tst_tf (EURUSD,M1) tst_tf bar novo 2021.05.27 21:49:00

2021.05.27 21:50:00.149 tst_tf (EURUSD,M1) tst_tf Novo bar 2021.05.27 21:50:00

2021.05.27 21:50:00.149 tst_tf (EURUSD,M5) tst Novo bar 2021.05.27 21:50:00

2021.05.27 21:51:01.789 tst_tf (EURUSD,M1) tst_tf Novo bar 2021.05.27 21:51:00

2021.05.27 21:52:02.832 tst_tf (EURUSD,M1) tst_tf Novo bar 2021.05.27 21:52:00

2021.05.27 21:53:00.920 tst_tf (EURUSD,M1) tst_tf Novo bar 2021.05.27 21:53:00

2021.05.27 21:54:02.778 tst_tf (EURUSD,M1) tst_tf Novo bar 2021.05.27 21:54:00

2021.05.27 21:55:00.308 tst_tf (EURUSD,M1) tst_tf Novo bar 2021.05.27 21:55:00

2021.05.27 21:55:00.308 tst_tf (EURUSD,M5) tst Novo bar 2021.05.27 21:55:00

2021.05.27 21:56:00.118 tst_tf (EURUSD,M1) tst_tf Novo bar 2021.05.27 21:56:00

2021.05.27 21:57:00.419 tst_tf (EURUSD,M1) tst_tf Novo bar 2021.05.27 21:57:00

 
Andrey Khatimlianskii:

É assim em todos os bares novos? São demasiado seguros ou algo assim...

Se não em cada barra, há diferentes razões para reiniciar o pré_calc.

exactamente em cada novo bar da maior TF.

Por exemplo, se o indicador funcionar em M1 e aceder ao indicador em M5, então a cada 5 minutos o indicador será completamente recalculado.

 
Igor Makanu:

Penso que o problema é:

Não se deixa o indicador chamado em outro TF calcular cada tick e depois chama-o e o histórico sincroniza e calcula a partir do zero desse indicador


criei um teste. o indicador chamado conta tudo e não reinicia para pré_calculado == 0

Fechei no indicador e desenrolei o evento com uma nova barra e prev_calculei == 0 :

chame este indicador (obtenha os 2 últimos valores do tampão) e também se aproxime da sua TF:

Verifico a sincronização dos dados na TF superior solicitada (M5) e a prontidão do indicador na mesma, se não estiver pronto, então saia.

Como resultado, o indicador funciona apenas uma vez na barra M1 aberta, e não a cada tick:


//проверка готовности данных и индикатора на другом TF
if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))
{
  if (iBars (Symbol (), tf) != BarsCalculated (handleFr)) return 0;
}
else return 0;

//проверка на наличие нового бара
if (rates_total == prev_calculated) return rates_total;

Espero que os criadores ouçam os meus pedidos.

 
Andrey Dik:

Verifico a sincronização dos dados na TF superior solicitada (M5) e a prontidão do indicador na mesma, se não estiver pronto, então saia.

Como resultado, o indicador funciona apenas uma vez na abertura da barra M1, e não a cada tic tac:


Espero que os criadores ouçam os meus pedidos.

isto não deve funcionar correctamente nos indicadores:

if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))

se não estou enganado, na ajuda há uma passagem do guião para a paginação de dados para todas as TFs e deve haver um aviso de que os dados históricos não podem ser solicitados ao indicador devido ao facto de o indicador funcionar de forma assíncrona

e recomenda-se usar BarsCalculated() uma vez depois de atar a pega


UPD: guião para paginação da história e explicação porque não funciona em indicadores:https://www.mql5.com/ru/docs/series/timeseries_access

 
Andrey Dik:

Verifico a sincronização dos dados na TF superior solicitada (M5) e a prontidão do indicador na mesma, se não estiver pronto, então saia.

Como resultado, o indicador funciona apenas uma vez na abertura da barra M1, e não a cada tic tac:


Tenho mesmo de usar o meu pré-calc? Espero que os programadores ouçam os meus pedidos.

Para que serve tal verificação?

//проверка готовности данных и индикатора на другом TF
if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))
{
  if (iBars (Symbol (), tf) != BarsCalculated (handleFr)) return 0;
}
else return 0;

Seria muito mais simples escrever return 0; sem condição e pronto.

Em cada nova barra, a condição será cumprida e todas as barras serão recalculadas independentemente da sincronização. Escreveu um código irreflectido e finge que é um bug terminal.

 
Um erro de compilação:
union X1 { //(1) нормально
        char x11[INT_MAX/2+1];
};
union X2 { //(2) Error: 'X2' - struct is too large
        char x21[INT_MAX/2+1];
        char x22[INT_MAX/2+1];
};
Qual é a diferença fundamental entre (1) e (2) ?
 
União com um único campo é uma coisa estranha.
 
Alexey Viktorov:

Qual é o objectivo de tal verificação?

Seria mais fácil escrever o retorno 0; sem condições e pronto...

A condição será preenchida em cada nova barra e todas as barras serão recalculadas independentemente da sincronização. Escreveu um código errático e passou-o como um bug terminal.

pensar de novo.