[SERVICE DESK] Errore nell'ottenere il tempo del TF senior nel timer! - pagina 6

 
Mi piacerebbe molto sentire cosa ne pensano gli sviluppatori.
 
 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:

Sembra che la soluzione più affidabile sia proprio quella di aspettare la chiamata di OnCalculate() con controllo obbligatorio della connessione al server commerciale. Se non controlliamo la connessione (IsConnected()), allora anche in OnCalculate() la otterremo al caricamento del terminale:

Tuttavia, non elimina tutte le domande:

1. Perché non c'è scritto nella documentazione di IsConnected() che deve essere necessariamente chiamato prima di ricevere i dati (almeno) dal TF senior in OnCalculate()?

2. Perché IsConnected() in OnTimer() non funziona? Il fatto di stabilire una connessione con un server commerciale non dovrebbe dirci che i dati possono essere ottenuti?

3. Una volta che abbiamo stabilito una connessione con il server commerciale e stiamo cercando di ricevere dati in OnTimer(), le funzioni iTime(), iBarShift(), SeriesInfoInteger() e funzioni simili a loro non dovrebbero restituire errori se i dati di questo particolare server commerciale, da cui prendono informazioni, non sono ancora sincronizzati? Altrimenti viene fuori qualche sciocchezza, come se vi restituiamo l'errore 4066 una volta e poi potete usare i dati che avete.

Ho parlato con gli sviluppatori e con uno dei miei amici lì e ho detto loro quanto segue: 1 Cosa devo fare?

1 Sciocchezze, si può chiamare in qualsiasi momento e da qualsiasi luogo.

2 IsConnected può essere chiamato da qualsiasi punto del codice e funziona, ma è una funzione che non scrive nulla sullo stack degli errori, restituisce vero/falso e basta. Considerando che la procedura di connessione è abbastanza lunga (minimo 1 sec.) e che IsConnected viene attivata al momento del login, è necessario controllare lo stato di connessione e aspettare l'inizio del flusso di citazioni all'avvio del terminale.

3 Queste funzioni non scrivono nulla nello stack degli errori, restituiscono il risultato da sole.

Perché abbiamo ottenuto 4066? Quell'errore è stato causato dalla funzione TimeCurrent. Terminale loggato e tempo richiesto dal server a seconda della qualità della connessione ci vuole anche un po' di tempo, quindi abbiamo un timer veloce. E poi abbiamo ottenuto 4066 sulla nostra richiesta da TimeCurrent. E poi abbiamo ottenuto il tempo e le nostre funzioni hanno iniziato a lavorare normalmente e loro stesse restituiscono un errore come risultato del loro lavoro bypassando lo stack degli errori.

Come raccomandazione in tale situazione, timer veloce e avvio del terminale, assicuratevi di controllare che abbiamo iniziato a ricevere dati dal server. La mia versione è un po' arzigogolata, sarebbe corretto ottenere un segnale da OnCalculate per iniziare a ricevere dati.

 
È più semplice di così.
 
Alexey Kozitsyn:

Cosa suggerisci per risolvere il problema (c'è, secondo te)? Aspettare che OnCalculate() sia chiamato 1-2 volte?

Sì, esattamente. In OnInit() chiamate semplicemente i TF richiesti senza controllare il risultato (non potete farci affidamento), e in OnCalculate chiamate la funzione IsTFDataReady(). Non appena viene restituito true per tutti i TF richiesti, è possibile iniziare ad eseguire l'algoritmo dell'indicatore.

 
Alexey Kozitsyn:

1. Perché la documentazione di IsConnected() non dice che deve sempre essere chiamata prima di ricevere dati (almeno) dal TF senior in OnCalculate()?

IsConnected() è una funzione abbastanza complicata. Restituisce lo stato di una sola connessione al server. Ma il terminale usa più di una connessione. Ci sono 8 fili commerciali da soli. Quindi, anche se IsConnected() restituisce true, non è del tutto chiaro cosa significhi. Almeno, non possiamo aspettarci che le serie temporali vengano richieste e costruite. Ma se IsConnected() restituisce false, allora possiamo essere sicuri che il terminale è ancora offline.

Qual è il compito per il quale la presenza della connessione terminale è così cruciale? Per quanto ho capito, l'indicatore è uno strumento di visualizzazione dei dati. I dati che sono disponibili. Quando arrivano nuovi dati, aggiorna la visualizzazione. Non dovrebbe essere richiesto di controllare se i dati sono aggiornati. Questo è il compito del terminale.

 
Igor Makanu:

Immagino che stiamo parlando di MQL5, la preparazione OHLC non è la stessa di MT4

Sto parlando di MT4. Circa 2-3 anni fa stavo prendendo un bug con Time[0]. Gli sviluppatori sembrano averlo risolto, ma poi, col tempo, si è ripresentato. Il problema è che è impossibile riprodurre in modo univoco questo bug.

 
Ihor Herasko:

IsConnected() è una funzione piuttosto complicata. Restituisce solo lo stato di una delle connessioni al server. Ma il terminale usa più di una connessione. Ci sono 8 fili commerciali da soli. Quindi, anche se IsConnected() restituisce true, non è del tutto chiaro cosa significhi. Almeno, non possiamo aspettarci che le serie temporali vengano richieste e costruite. Ma se IsConnected() restituisce false, allora possiamo essere sicuri che il terminale è ancora offline.

Qual è il compito per il quale la presenza della connessione terminale è così cruciale? Per quanto ho capito, l'indicatore è uno strumento di visualizzazione dei dati. I dati che sono disponibili. Quando arrivano nuovi dati, aggiorna la visualizzazione. Non dovrebbe essere richiesto di controllare la pertinenza dei dati. Questo è il compito del terminale.

Per gli indicatori non ricordo la necessità di controllare la connessione con il server, quello che abbiamo nella storia è disegnato, quando la storia viene caricata significa che tutti i buffer degli indicatori vengono ricalcolati

Ho sviluppato e uso la seguente funzione nel mio EA. È generalmente soddisfacente e controlla correttamente la connessione con il server:

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);}

In particolare uso Sleep() per trasmettere il controllo al terminale e poi controllare la connessione al server e la possibilità di fare trading

 
Ihor Herasko:

Sto parlando di MT4. Circa 2-3 anni fa stavo prendendo un bug con Time[0]. Gli sviluppatori sembravano averlo risolto, ma poi, col tempo, si è ripresentato. Il problema è che è impossibile riprodurre in modo univoco questo bug.

Se non è troppo disturbo, ecco l'argomento del topic - scaricamento corretto della storia dal TF maggiore, ecco l'indicatore: "Ho bisogno di disegnare la MA" dal TF maggiore sulle barre del TF minore, l'ho fatto in 5 minuti, funzionerà per il 98% correttamente, dove in questo codice il 2% "insidie" che causerà bug?

Sono interessato al codice corretto per 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:

Ho parlato con gli sviluppatori e con un amico che conosco lì, e vi dirò una cosa alla volta.

1 Sciocchezze, si può chiamare in qualsiasi momento e da qualsiasi luogo.

2 IsConnected può essere chiamato da qualsiasi punto del codice e funziona, ma è una funzione che non mette nulla sullo stack degli errori, restituisce vero/falso e basta. Considerando che la procedura di connessione è abbastanza lunga (minimo 1 sec.) e che IsConnected si attiva al momento del login, è necessario controllare lo stato di connessione e aspettare l'inizio del flusso di citazioni all'avvio del terminale.

3 Queste funzioni non scrivono nulla nello stack degli errori, restituiscono il risultato da sole.

Perché abbiamo ottenuto 4066? Quell'errore è stato causato dalla funzione TimeCurrent. Terminale loggato e tempo richiesto dal server a seconda della qualità della connessione ci vuole anche un po' di tempo, quindi abbiamo un timer veloce. E poi abbiamo ottenuto 4066 sulla nostra richiesta da TimeCurrent. E poi abbiamo ottenuto il tempo e le nostre funzioni hanno iniziato a lavorare normalmente e loro stesse restituiscono un errore come risultato del loro lavoro bypassando lo stack degli errori.

Come raccomandazione in tale situazione, timer veloce e avvio del terminale, assicuratevi di controllare che abbiamo iniziato a ricevere dati dal server. La mia variante è un po' arzigogolata, sarebbe corretto ottenere un segnale da OnCalculate per iniziare a ricevere dati.

1. Leggete attentamente ciò che scrivo. Non è la prima volta che te lo dico! Non ho detto nulla sul fatto di non chiamare da qualche parte!

Sta dicendo che tutte le funzioni iBarShift(), iTime(), SeriesInfo...() richiedono TimeCurrent()?

Motivazione: