[Erro em obter o tempo do TF sênior no temporizador! - página 6

 
Eu gostaria muito de ouvir o que os desenvolvedores pensam sobre isso.
 
 ResetLastError();
      if(iBarShift(Symbol(),PERIOD_M15,TimeCurrent(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
      //---
      if(GetLastError()==ERR_NO_ERROR)
        {
         ResetLastError();
         //--- Запоминаем время открытия бара
         _m15OpenTime=iTime(NULL,PERIOD_M15,0);
         //---
         Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
         //--- Возвращаем истину
         return( true );
        }
 
Alexey Kozitsyn:

Parece que a solução mais confiável é realmente esperar pela chamada da OnCalculate() com verificação obrigatória da conexão ao servidor comercial. Se não verificarmos a conexão (IsConnected()), então, mesmo em OnCalculate(), a obteremos no carregamento do terminal:

No entanto, ela não elimina todas as dúvidas:

1. Por que não diz na documentação da IsConnected() que ela deve ser necessariamente chamada antes de receber dados (pelo menos) da TF sênior na OnCalculate()?

2. Por que IsConnected() no OnTimer() realmente não funciona? O fato de estabelecer conexão com um servidor comercial não deveria nos dizer que os dados podem ser obtidos?

3. Uma vez estabelecida uma conexão com o servidor de negociação e tentando receber dados no OnTimer(), as funções iTime(), iBarShift(), SeriesInfoInteger() e funções similares a elas retornam erros se os dados deste servidor de negociação em particular, do qual retiram informações, ainda não estiverem sincronizados? Caso contrário, acontece algum absurdo, como se devolvêssemos o erro 4066 uma vez e depois você pudesse usar os dados que possui.

Falei com os desenvolvedores e um dos meus amigos de lá e lhes digo o seguinte: 1 O que eu faço?

1 Bobagem, você pode chamá-lo quando e de qualquer lugar.

2 IsConnected pode ser chamado de qualquer lugar no código e funciona, mas é uma função que não escreve nada na pilha de erros que retorna verdadeiro/falso e é isso mesmo. Considerando que o procedimento de conexão é bastante longo (mínimo de 1 segundo) e IsConnected é acionado no momento do login, é necessário verificar o status da conexão e aguardar o início do fluxo de cotações ao iniciar o terminal.

3 Estas funções não escrevem nada na pilha de erros, elas mesmas retornam o resultado.

Por que tivemos 4066? Esse erro foi causado pela função TimeCurrent. Terminal logado e tempo solicitado do servidor dependendo da qualidade da conexão também leva algum tempo, por isso temos um temporizador rápido. E depois recebemos 4066 a pedido da TimeCurrent. E então conseguimos o tempo e nossas funções começaram a funcionar normalmente e eles mesmos retornam um erro como resultado de seu trabalho contornando a pilha de erros.

Como uma recomendação nesta situação, temporizador rápido e terminal de partida, certifique-se de verificar se começamos a receber dados do servidor. Minha versão é um pouco muleta, seria correto receber um sinal da OnCalculate para começar a receber dados.

 
É mais simples do que isso.
 
Alexey Kozitsyn:

O que você sugere para resolver o problema (existe, em sua opinião)? Espere até que OnCalculate() seja chamado 1-2 vezes?

Sim, exatamente. No OnInit() basta chamar os TFs necessários sem verificar o resultado (você não pode confiar nele), e no OnCalculate chamar a função IsTFDataReady(). Assim que a verdade for devolvida para todos os TFs solicitados, você pode começar a executar o algoritmo do indicador.

 
Alexey Kozitsyn:

1. Por que a documentação da IsConnected() não diz que ela deve ser sempre chamada antes de receber dados (pelo menos) da TF sênior na OnCalculate()?

IsConnected() é uma função bastante complicada. Ele retorna o estado de apenas uma conexão ao servidor. Mas o terminal utiliza mais de uma conexão. Existem 8 fios de comércio por si só. Portanto, mesmo que IsConnected() retorne verdadeiro, não é bem claro o que significa. Pelo menos, não podemos esperar que as séries temporais sejam solicitadas e construídas. Mas se IsConnected() retorna falso, então podemos ter certeza de que o terminal ainda está offline.

Qual é a tarefa, para a qual a presença da conexão terminal é tão crucial? Tanto quanto sei, o indicador é uma ferramenta de visualização de dados. Os dados que estão disponíveis. Quando novos dados chegarem, ele atualizará a visualização. Não deve ser exigido que se verifique se os dados estão atualizados. Essa é a tarefa do terminal.

 
Igor Makanu:

Acho que estamos falando da preparação da MQL5, OHLC não é a mesma que na MT4

Estou falando do MT4. Há cerca de 2-3 anos atrás eu estava pegando um bug com o Time[0]. Os desenvolvedores parecem tê-lo consertado, mas depois, com o tempo, ele apareceu novamente. O problema é que é impossível reproduzir de forma inequívoca este bug.

 
Ihor Herasko:

IsConnected() é uma função bastante complicada. Ele só retorna o status de uma das conexões ao servidor. Mas o terminal utiliza mais de uma conexão. Só existem 8 fios comerciais. Portanto, mesmo que IsConnected() retorne verdadeiro, não é bem claro o que significa. Pelo menos, não podemos esperar que as séries temporais sejam solicitadas e construídas. Mas se IsConnected() retorna falso, então podemos ter certeza de que o terminal ainda está offline.

Qual é a tarefa, para a qual a presença da conexão terminal é tão crucial? Tanto quanto sei, o indicador é uma ferramenta de visualização de dados. Os dados que estão disponíveis. Quando novos dados chegarem, ele atualizará a visualização. Não deve ser exigido que se verifique a relevância dos dados. Esta é a tarefa do terminal.

Para os indicadores não me lembro da necessidade de verificar a conexão com o servidor, o que temos no histórico é desenhado, quando o histórico é carregado significa que todos os buffers indicadores são recalculados

Desenvolvi e uso a seguinte função em meu EA. É geralmente satisfatória e verifica a conexão com o servidor corretamente:

bool ServerDisable(int count=10){
   if(IsTesting()||IsOptimization())return(false);
   for(int i=0;i<count;i++){
      if(IsConnected())
         if(IsTradeAllowed())
            if(!IsTradeContextBusy()){RefreshRates(); return(false);}
      Sleep(157);
   }
   Print(__FUNCTION__," Торговый сервер не отвечает");
return(true);}

Utilizo especificamente o Sleep() nele para transmitir o controle ao terminal e depois verificar a conexão com o servidor e a possibilidade de negociar

 
Ihor Herasko:

Estou falando do MT4. Há cerca de 2-3 anos atrás eu estava pegando um bug com o Time[0]. Os desenvolvedores pareciam tê-lo consertado, mas depois, com o tempo, ele apareceu novamente. O problema é que é impossível reproduzir de forma inequívoca este bug.

Se não for muito trabalho, aqui está o tópico do tópico - download correto da história do TF principal, aqui está o indicador: "Eu preciso tirar o MA" do TF principal nas barras do TF menor, eu fiz isso em 5 minutos, funcionará por 98% corretamente, onde neste código 2% "armadilhas" que causarão bugs?

Estou interessado no código correto para o MT4

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot line1
#property indicator_label1  "line1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input ENUM_TIMEFRAMES   TimeFrame   =  PERIOD_H4;
input int               MAPeriod    =  25;
//--- indicator buffers
double         BufMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   double cl[];
//--- indicator buffers mapping
   SetIndexBuffer(0,BufMA);
   IndicatorDigits(Digits);
// запускаем подгрузку истории и выходим, даже не проверяя подгружена она или нет, история тут еще не нужна
   CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),cl);
//---
   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 i,limit,resultcopy;
   double closetf[];
   if(prev_calculated==0)
     {
      resultcopy=CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),closetf);
      if(resultcopy<0)
        {
         Print("Подгрузка истории....");
         return(0);
        }
      if(resultcopy<MAPeriod)
        {
         Comment("Большой период МА!!!, в истории доступно ", resultcopy," баров");
         return(resultcopy);
        }
      limit=resultcopy-1;
        }else{
      resultcopy=CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),closetf);
      if(resultcopy<0)
        {
         Print("Подгрузка истории....");
         return(0);
        }
      if(resultcopy<MAPeriod)
        {
         Comment("Большой период МА!!!, в истории доступно ", resultcopy," баров");
         return(resultcopy);
        }
      limit=resultcopy-prev_calculated+1;
     }
   limit = fmin(rates_total-1,limit);
// основной цикл расчета индикатора
   for(i=limit; i>=0 && !IsStopped(); i--)
     {
      BufMA[i]=iMA(_Symbol,TimeFrame,MAPeriod,0,MODE_SMA,PRICE_CLOSE,i);
     }
//---
   return(resultcopy);

  }
 
Vitaly Gorbunov:

Falei com os desenvolvedores e com um amigo que conheço lá, e lhe direi uma coisa de cada vez.

1 Bobagem, você pode chamá-la quando e de qualquer lugar.

2 IsConnected pode ser chamado de qualquer lugar no código e funciona, mas é uma função que não coloca nada na pilha de erros, retorna verdadeiro/falso e é isso. Considerando que o procedimento de conexão é bastante longo (mínimo de 1 segundo) e IsConnected é acionado no momento do login, é necessário verificar o estado da conexão e aguardar o início do fluxo de cotações ao iniciar o terminal.

3 Estas funções não escrevem nada na pilha de erros, elas mesmas retornam o resultado.

Por que tivemos 4066? Esse erro foi causado pela função TimeCurrent. Terminal logado e tempo solicitado do servidor dependendo da qualidade da conexão também leva algum tempo, por isso temos um temporizador rápido. E depois recebemos 4066 a pedido da TimeCurrent. E então conseguimos o tempo e nossas funções começaram a funcionar normalmente e eles mesmos retornam um erro como resultado de seu trabalho contornando a pilha de erros.

Como uma recomendação nesta situação, temporizador rápido e terminal de partida, certifique-se de verificar se começamos a receber dados do servidor. Minha variante é um pouco mudo, seria correto obter um sinal da OnCalculate para começar a receber dados.

1. Leia atentamente o que escrevo. Não é a primeira vez que eu lhe digo isso! Eu não disse nada sobre não ligar para algum lugar!

Você está dizendo que todas as funções iBarShift(), iTime(), SeriesInfo...() solicitam TimeCurrent()?