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

 
Vitaly Gorbunov:
Il metodo iBarShift vi permette di trovare dei buchi nella storia, ma dovete controllare la storia a intervalli. Ho scritto una procedura per me stesso che fa questo, e dopo ho dimenticato le lacune dei programmi MtF.
Non si trattava di rilevare dei "buchi". La persona voleva ottenere l'ultima barra della storia, e questa non è necessariamente la barra attuale nel tempo.
 
Vitaly Gorbunov:
I dati vengono caricati con l'errore 4066, e poi è colpa dei methaquotov, molto probabilmente i dati ricevuti vengono elaborati per questa situazione, l'errore non è stato inventato. E fino a quel punto, tutto ha un senso.

Se un errore è "non inventato", non significa che non esiste.

 
Alexey Navoykov:
Non si tratta di rilevare "buchi". La persona voleva ottenere l'ultima barra della storia, e questa non è necessariamente la barra del tempo corrente.

Non si tratta di iBarShift(). Invia gli stessi errori di iTime() e SeriesInfoInteger(). La stampella qui sta nel confrontare il tempo ottenuto durante l'inizializzazione e poi confrontarlo con il tempo del timer. Questo è ciò che ha permesso di ottenere dati reali corretti quando si carica il terminale, non IBarShift().

Sì, e se l'ora è 15:00:45 (per esempio), e non c'è ancora un tick sulla barra delle 15:00 e se l'ora di apertura della barra dell'ultima ora è 14:00 - tutto è corretto, credo. E se il sistema restituisce 13:00 - questo è un problema.

 
Alexey Kozitsyn:

1. Igor, hai guardato il codice? Dove trovo qualcosa in OnInit()?

Nel vostro caso una o più chiamate OnTimer vengono eseguite subito dopo OnInit(). Non c'è ancora un evento OnCalculate().

2. Quali controlli? Dove sta scritto che l'indicatore deve usare OnCalculate() almeno una volta per funzionare correttamente?

Qui dobbiamo capire la logica del terminale. OnInit() viene chiamato immediatamente quando si collega l'indicatore al grafico. Quando si avvia il terminale, la connessione dell'indicatore al grafico viene eseguita subito dopo la creazione della finestra del grafico. In questo momento, il terminale non ha ancora inviato la richiesta al server.

La prima OnCalculate() viene chiamata dopo che le citazioni disponibili sono state lette localmente. In alcuni rari casi succede che non c'è niente a livello locale. In questo caso, quando ci si rivolge a Time[0], gli indicatori escono dall'array. Pertanto, è meglio usare la funzione iTime e altre funzioni simili.

Il secondo e il prossimo OnCalculate() si verificano al caricamento della storia o all'arrivo dei tick reali.

 
Ihor Herasko:

La prima OnCalculate() viene chiamata dopo aver letto le quotazioni disponibili localmente. In alcuni rari casi succede che non c'è niente a livello locale. In questo caso, quando si fa riferimento a Time[0], gli indicatori escono dall'array. Pertanto, è meglio usare la funzione iTime o simili.

Immagino che stiamo parlando di MQL5, la preparazione di OHLC è diversa da quella di MT4

Ho scritto indicatori basati su un modello per molto tempo:

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;
   if(prev_calculated==0)
     {
      limit=rates_total-1;    //--- Первый вызов индикатора или смена таймфрейма или подгрузка данных из истории
     }
   else limit=rates_total-prev_calculated+1;
   for(i=limit;i>=0;i--)      //---- Основной цикл расчета
     {                        
     }
   return(rates_total);
  }

Non ho mai avuto un "crash dell'indicatore" sugli array OHLC in MT4, penso che MT4 non eseguirà OnCalculate() finché un grafico non è preparato per la prima volta, e se la storia è caricata, non l'ho controllato, ma prev_calculated==0 , in MT5 sarà come hai scritto - hai bisogno di controlli aggiuntivi per vedere se i dati OHLC sono già preparati

 
Ihor Herasko:

Nel vostro caso una o più chiamate OnTimer saranno eseguite subito dopo OnInit(). Non c'è ancora un evento OnCalculate().

Qui è necessario capire la logica del terminale. OnInit() viene chiamato immediatamente quando si collega l'indicatore al grafico. Quando si avvia il terminale, la connessione dell'indicatore al grafico viene eseguita subito dopo la creazione della finestra del grafico. In questo momento, il terminale non ha ancora inviato la richiesta al server.

La prima OnCalculate() viene chiamata dopo che le citazioni disponibili sono state lette localmente. In alcuni rari casi succede che non c'è niente a livello locale. In questo caso, quando ci si rivolge a Time[0], gli indicatori escono dall'array. Pertanto, è meglio usare la funzione iTime e altre funzioni simili.

Il secondo e il prossimo OnCalculate() si verificano al caricamento della storia o all'arrivo dei tick reali.

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

 
Alexey Kozitsyn:

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

Potete provare acopiare il valoreprev_calculated==0in una variabile nell'ambito globale e vedere in OnTimer() se l'indicatore è stato calcolato.OnCalculate() - sarà calcolato in ogni caso, sospetto che se i dati TF non erano pronti, allorareturn(rates_total) restituirà 0, che sarà nella prossima chiamata diOnCalculate() indicandoprev_calculated==0, approssimativamente:

void OnTimer(){
   if(Global_prev_calculated==0)return;
}
 
Igor Makanu:

potete provare acopiare il valoreprev_calculated==0in una variabile nell'ambito globale e vedere in OnTimer() se l'indicatore è stato calcolato; ho scritto sopra che non ho mai visto nessun bug con calcolo errato in MT4OnCalculate() - sarà calcolato in ogni caso, sospetto che se i dati TF non erano pronti, allorareturn(rates_total) restituirà 0, che sarà nella prossima chiamata diOnCalculate() un segnoprev_calculated==0

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 la otterremo anche in OnCalculate() quando il terminale viene caricato:

2018.09.21 23:45:27.128 test_isNewDayInOnCalculate_iBarShift() EURGBP.e,M1: test_isNewDayInOnCalculate_iBarShift().mq4: Актуальное время открытия бара М15 = 2018.09.21 21:30. Ошибка #0
2018.09.21 23:45:25.990 test_isNewDayInOnCalculate_iBarShift() EURGBP.e,M1: initialized
2018.09.21 23:45:25.975 Custom indicator test_isNewDayInOnCalculate_iBarShift() EURGBP.e,M1: loaded successfully

Tuttavia, non elimina tutte le domande:

1. Perché non è 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 sembra senza senso, come se restituissimo l'errore 4066 una volta e poi usassimo i dati presenti in qualsiasi modo si voglia.

 
Alexey Kozitsyn:

Tuttavia, questo non elimina tutte le domande:

1. Perché la documentazione di IsConnected() non dice che deve necessariamente essere chiamata prima di ricevere 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 sembra senza senso, come se restituissimo un errore 4066 una volta e poi trattassimo i dati esistenti nel modo che volete.

1. Beh, nessuno ha cancellato il caso della chiamata dell'indicatore su dati storici, se hai bisogno di lavorare online, allora controlla la connessione, se no, o piuttosto non è importante, allora la mia versione del modello funziona. Il gruppo di funzioni IsConnected() è in realtà un po' complicato, incrociano IsTradeContextBusy() e IsConnected() stesso a volte e IsTradeAllowed()... Penso che si incasinino sul lato server e disconnettano i terminali al momento delle notizie o di altre manipolazioni

2,3. funziona, ma si dimentica che GetLastError() resetta il suo stato dopo una chiamata e forse per aggiornare lo stato GetLastError() ha bisogno di trasferire il controllo al terminale, forse il terminale non ha avuto il tempo di reimpostare lo stato IsConnected() in GetLastError() prima della vostra chiamata dal timer.... Credo che la funzione OnTimer() non sia destinata a ricevere dati: "MQL4 Reference / Status Check - OnTimer() sarà chiamato, ma le variabili dell'ambiente del terminale non sono aggiornate, esuCalculate() è garantito di preparare tutti i dati dal terminale quando arriva il tick

 
Igor Makanu:

1. beh, nessuno ha cancellato il caso di chiamare l'indicatore su dati storici...

2,3. funziona, ma si dimentica che GetLastError() resetterà il suo stato dopo la chiamata, e forse per aggiornare lo stato GetLastError() ha bisogno di passare il controllo al terminale, forse il terminale non ha tempo di reimpostare lo stato IsConnected() in GetLastError() prima della vostra chiamata da timer.... Credo che la funzione OnTimer() non sia destinata a ricevere dati: "Il MQL4 Reference / Status Check - OnTimer() sarà chiamato, ma le variabili dell'ambiente del terminale non vengono aggiornate, ed è garantito che il terminale preparerà tutti i dati quando arriva il tick-OnCalculate().

1. Pensate che se la barra numero 0 ha un tempo errato, il resto della storia avrà un tempo corretto?)

2,3. Se le funzioni di accesso ai dati non hanno abbastanza tempo per impostare qualche errore significativo - lasciate che lo segnalino in qualche modo, ma certamente non restituendo il codice di errore = 0 (nessun errore). Il resto dei "forse" sono solo congetture. E senza prove non c'è niente di cui parlare.

La funzione OnTimer() non è destinata a recuperare dati...

Nessun commento.

OnTimer() sarà chiamato ma le variabili d'ambiente del terminale non sono necessariamente aggiornate

A cosa ci serve l'errore 4066?
Motivazione: