OnDeinit negli indicatori - pagina 7

 

Sviluppatori, avete un errore da qualche parte.

void OnDeinit(const int reason)
{
 //Comment("");
 Comment(ArrayInitialize(body_down,EMPTY_VALUE),"  ",body_down[0],"  ",body_down[1],"  ",body_down[2],"  ",body_down[3]);
}

Guardate lo screenshot di Comment dopo aver chiuso il terminale e averlo aperto dopo 1 minuto.

Numero di elementi inizializzati e che il primo, secondo, terzo e quarto elemento del buffer è vuoto.

L'indicatore conta solo il buffer 0. Allora perché 2 candele?


 
Oh, sì. L'aiuto inglese dice anche cheArrayInitialize non restituisce nulla.

 
eevviill:

Sviluppatori, avete un errore da qualche parte.

Guardate lo screenshot di Comment dopo aver chiuso il terminale e averlo aperto dopo 1 minuto.

Numero di elementi inizializzati e che il primo, secondo, terzo e quarto elemento del buffer è vuoto.

L'indicatore conta solo il buffer 0. Allora perché 2 candele?


Perché quando si analizza per una nuova barra, non si controlla il numero di barre, ma solo il tempo. Quando si avvia il terminale o si interrompe la connessione con il server durante l'operazione, prima che arrivino le barre mancanti (alla storia completa), arriva un tick. A questo tick, una nuova candela viene creata, ma c'è un gap (storia mancante) tra essa e la storia nel terminale, che verrà scaricata dal server e inserita al suo posto. Dopo l'apertura di una nuova barra scomparirà.
 
mql5:
Perché quando si analizza una nuova barra, non si controlla il numero di barre, ma ci si limita a controllare il tempo. Quando si avvia il terminale o si interrompe la connessione con il server durante l'operazione, arriva un segno di spunta prima che arrivino le barre mancanti (alla cronologia completa). A questo tick viene creata una nuova candela, ma c'è un gap (storia mancante) tra essa e la storia nel terminale, che verrà scaricata dal server e inserita nel sistema, e dato che non si analizza il numero di barre, si penserà che non ci sia una nuova barra nel calcolo successivo, ed è allora che appare la seconda candela. Dopo l'apertura di una nuova barra scomparirà.

E non importa che in deinit l'azzeramento avvenga quando il terminale è chiuso?

 

Vasily, esegui un indicatore di test che stampa il numero di barre.

//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

datetime lb;
int      rates_;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   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[])
  {
//---
   
//--- return value of prev_calculated for next call
   if(NewBar(PERIOD_CURRENT, lb))
    {
     Print("rates_total = ", rates_total);
     rates_ = rates_total;
    }
   return(rates_total);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//if(reason == REASON_CLOSE)
Print("OnDeinit сработал ", rates_);
}

bool NewBar(int tf, datetime &lastbar)
{
   datetime curbar = iTime(_Symbol, tf, 0);
   if(lastbar != curbar)
    {
     lastbar = curbar;
     return (true);
    }
   else return(false);
}//******************************************************************|

Questo è ciò che viene stampato nel log.

0       22:52:04.765    Custom indicator Test\test EURUSD.z,M1: loaded successfully
0       22:52:04.795    test EURUSD.z,M1: initialized
0       22:52:04.795    test EURUSD.z,M1: rates_total = 75183
0       22:52:11.902    test EURUSD.z,M1: rates_total = 75184
0       22:52:28.712    test EURUSD.z,M1: uninit reason 9
0       22:52:28.712    test EURUSD.z,M1: OnDeinit сработал 75184
0       22:52:28.832    Custom indicator test EURUSD.z,M1: removed
0       22:57:10.366    Custom indicator Test\test EURUSD.z,M1: loaded successfully
0       22:57:10.396    test EURUSD.z,M1: initialized
0       22:57:10.396    test EURUSD.z,M1: rates_total = 75184
0       22:57:14.972    test EURUSD.z,M1: rates_total = 75185
0       22:57:59.167    test EURUSD.z,M1: rates_total = 75190 
// Локальное время наверное отстаёт от серверного на несколько секунд. На сервере было уже 58 минут.
0       22:58:34.237    test EURUSD.z,M1: uninit reason 1
0       22:58:34.237    test EURUSD.z,M1: OnDeinit сработал 75190
0       22:58:34.247    Custom indicator test EURUSD.z,M1: removed


Forse questo ti dirà da dove viene il problema...

 
eevviill:

Si prega di chiedere agli sviluppatori una risposta semplice.

Quando il terminale viene chiuso, viene eseguita la funzione DeInit() nei programmi collegati al grafico?

In senso stretto, no.

OnDeinit viene eseguito. DeInit sarà eseguito solo se lo chiamate esplicitamente da OnDeinit.

Se vi riferite alla vecchia funzione deinit, tenete anche presente che i nomi delle funzioni sono sensibili alle maiuscole. Cioè, deInit è una funzione sconosciuta, deinit è un punto di ingresso standard sulla deinizializzazione (come OnDeinit)

 
eevviill:

E non importa che in deinit l'azzeramento avvenga quando il terminale è chiuso?

Chi se ne frega? Quando il terminale viene chiuso, questi buffer non sono più necessari, perché saranno immediatamente rilasciati quando il programma viene scaricato, che avviene subito dopo OnDeinit

Prova a cambiare solo l'intervallo di tempo. OnDeinit funzionerà, i buffer rimarranno (perché il programma non viene scaricato in questo caso), ma nessuno garantisce il loro contenuto dalla "vita passata"

Leggete finalmente la documentazione! https://docs.mql4.com/ru/runtime/running e https://docs.mql4.com/ru/runtime /event_fire#deinit

 
stringo:

Chi se ne frega? Quando si chiude il terminale, questi buffer non sono più necessari, perché saranno immediatamente rilasciati quando il programma viene scaricato, che avviene subito dopo OnDeinit

Prova a cambiare solo l'intervallo di tempo. OnDeinit funzionerà, i buffer rimarranno (poiché lo scarico del programma non avviene in questo caso), ma nessuno garantisce il loro contenuto dalla "vita passata"

Leggete finalmente la documentazione! https://docs.mql4.com/ru/runtime/running e https://docs.mql4.com/ru/runtime /event_fire#deinit

Quindi, nel mio caso, i buffer vengono già divisi quando il grafico viene riaperto?
 
eevviill:
Quindi nel mio caso, i buffer sono biforcati quando il grafico viene riaperto?

Non avete una biforcazione del buffer.

Questo è il modo in cui riempite il vostro buffer da soli. La prima volta, quando si disegna; la seconda volta, quando si ottiene una porzione di dati. Entrambe le volte si opera con lo stesso valore di Time[0].

 
stringo:

Non state avendo un buffer split.

È così che si riempie il proprio buffer. La prima volta al rendering e la seconda all'arrivo dei dati. Entrambe le volte si opera con lo stesso valore di Time[0].

OK.

Si prega di correggere l'aiuto inglese e questo è tutto.

Anche l'aiuto inglese dice cheArrayInitialize non restituisce nulla.