Servizi, nuove funzionalità nell'architettura MT5, il funerale di MT4 è proprio dietro l'angolo. - pagina 8

 

dall'ing.

dati

alimentazione

datafeed -- fonte di dati (anche se la parola "fonte" non è del tutto corretta)


alimentatore -- alimentatore, alimentatore, alimentatore

 

О датафидах. Сколько встречал этот термин, сложилось ощущение, что этим словом обозначают источник данных (котировок). Буквально "заполнитель данных". Когда речь идет о собственных инструментах, понимаю так, что мы сможем вычислять котировки, например, никем не котируемого MXNRUB по известным курсам MXNUSD и USDRUB, выгруженным из терминала в .csv формат, и легализовать для терминала новые котировки, указав файл .csv как новый датафид. Возможно, будет реализовано и более изящное решение, без выгрузки в файлы, путем онлайновых операций */ над тиками (MXNRUB =  MXNUSD * USDRUB). И это будет новый датафид.

Hanno già importato le quotazioni .csv in tick per MT5?
 
Andrey Khatimlianskii:

Non è rimasto nessun link a una discussione, un rapporto di bug o qualcosa del genere? O solo la sensazione che ce ne fosse uno, ma non l'ho controllato ora?

Per quanto ricordo, i tick raccolti in OnCalculate corrispondevano a quelli richiesti tramite CopyTix.

Ora l'ho controllato di proposito... come sospettavo, ho ottenuto qualche schifezza, ma non quella che mi aspettavo :)

2017.05.22 12:47:10.591 (RTS-6.17,M1)   OnCalculate: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.591 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.599 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.605 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.617 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.637 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.649 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.683 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.765 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.771 (RTS-6.17,M1)   OnCalculate: 2017.05.22 10:47:11.193 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 88
2017.05.22 12:47:10.781 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.193 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 88
2017.05.22 12:47:10.843 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.244 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 0
2017.05.22 12:47:10.843 (RTS-6.17,M1)   OnBookEvent: Время последнего OnCalculate = 2017.05.22 10:47:11.193 ms (88), время последнего OnBookEvent = 2017.05.22 10:47:11.244 ms (0)
2017.05.22 12:47:10.859 (RTS-6.17,M1)   OnCalculate: 2017.05.22 10:47:11.282 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 88
2017.05.22 12:47:10.863 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.282 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 88

OnBookEvent() cattura i tick con il flag 0...

 

E questo è quello che mi aspettavo di vedere:

2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.253 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.253 (RTS-6.17,M1)   OnCalculate: Время последнего STick = 2017.05.22 11:24:38.704 ms (TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME ), время последнего CopyTicks = 2017.05.22 11:24:38.697 ms (TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME )
2017.05.22 13:24:38.253 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.253 (RTS-6.17,M1)   OnCalculate: Время последнего STick = 2017.05.22 11:24:38.704 ms (TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME ), время последнего CopyTicks = 2017.05.22 11:24:38.697 ms (TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME )
2017.05.22 13:24:38.254 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.255 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.255 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.255 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.261 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.261 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.261 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.262 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.262 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.270 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.280 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.730 ms v = 2, bid = 108550, ask = 108560, last = 108560, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.280 (RTS-6.17,M1)   OnCalculate: Время последнего STick = 2017.05.22 11:24:38.730 ms (TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME ), время последнего CopyTicks = 2017.05.22 11:24:38.719 ms (TICK_FLAG_BID )
2017.05.22 13:24:38.282 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 11:24:38.730 ms v = 2, bid = 108550, ask = 108560, last = 108560, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.283 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.730 ms v = 2, bid = 108550, ask = 108560, last = 108560, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
Come potete vedere, quando si richiede l'ultimo tick su ogni chiamata a OnCalculate() con SymbolInfoTick() - c'è un salto in alcuni dei tick che CopyTicks() restituisce.
 

Codice da controllare:

#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
MqlTick _tick;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Подписываемся на стакан
   MarketBookAdd(_Symbol);
//---
   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[])
  {
//---
   ResetLastError();
//--- Проверяем получение параметров тика
   if(!SymbolInfoTick(_Symbol,_tick))
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": параметры тика не получены!");
   else
      Print(__FUNCTION__,": "+GetMsToStringTime(_tick.time_msc)+" v = ",_tick.volume,", bid = "+DoubleToString(_tick.bid,_Digits)+
            ", ask = "+DoubleToString(_tick.ask,_Digits)+", last = "+DoubleToString(_tick.last,_Digits)+", flags = '"+GetStrFlags(_tick.flags)+"'");
//---
   ResetLastError();
//---
   MqlTick t[1];
   if(CopyTicks(_Symbol,t,COPY_TICKS_ALL,0,1)!=1)
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": Последний тик не получен!");
   else
     {
      if(t[0].time_msc!=_tick.time_msc)
        {
         Print(__FUNCTION__,": Время последнего STick = "+GetMsToStringTime(_tick.time_msc)+" ("+GetStrFlags(_tick.flags)+")"+
               ", время последнего CopyTicks = "+GetMsToStringTime(t[0].time_msc)+" ("+GetStrFlags(t[0].flags)+")");
        }
     }
//---
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
//---
   if(symbol!=_Symbol)
      return;
//--- Структура - приемник последнего тика
   MqlTick tick;
//---
   ResetLastError();
//--- Проверяем получение параметров тика
   if(!SymbolInfoTick(_Symbol,tick))
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": параметры тика не получены!");
   else
      Print(__FUNCTION__,": "+GetMsToStringTime(tick.time_msc)+" v = ",tick.volume,", bid = "+DoubleToString(tick.bid,_Digits)+
            ", ask = "+DoubleToString(tick.ask,_Digits)+", last = "+DoubleToString(tick.last,_Digits)+", flags = '"+GetStrFlags(tick.flags)+"'");
//--- Сравниваем последний тик OnCalculate с последним тиком OnBookEvent
   if(tick.time_msc!=_tick.time_msc)
     {
      Print( __FUNCTION__,": Время последнего OnCalculate = "+GetMsToStringTime( _tick.time_msc )+" ("+GetStrFlags( _tick.flags )+")"+
            ", время последнего OnBookEvent = "+GetMsToStringTime( tick.time_msc )+" ("+GetStrFlags( tick.flags )+")" );
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Отписываемся от стакана
   MarketBookRelease(_Symbol);
  }
//+------------------------------------------------------------------+
//| Получаем строку времени из миллисекунд                                                                      |
//+------------------------------------------------------------------+
string GetMsToStringTime(const ulong ms)
  {
   const int MS_KOEF=1000;               // Коэффициент перевода секунд в миллисекунды
   return( TimeToString( ms/MS_KOEF, TIME_DATE|TIME_SECONDS )+"."+string( ms%MS_KOEF )+" ms" );
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string GetStrFlags(const uint flags)
  {
   string s="";
//---
   if(( flags&TICK_FLAG_ASK)==TICK_FLAG_ASK)
      s+="TICK_FLAG_ASK ";
   if(( flags&TICK_FLAG_BID)==TICK_FLAG_BID)
      s+="TICK_FLAG_BID ";
   if(( flags&TICK_FLAG_BUY)==TICK_FLAG_BUY)
      s+="TICK_FLAG_BUY ";
   if(( flags&TICK_FLAG_SELL)==TICK_FLAG_SELL)
      s+="TICK_FLAG_SELL ";
   if(( flags&TICK_FLAG_LAST)==TICK_FLAG_LAST)
      s+="TICK_FLAG_LAST ";
   if(( flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME)
      s+="TICK_FLAG_VOLUME ";
//---
   return( s );
  }
//+------------------------------------------------------------------+
 
Alexey Kozitsyn:

Codice da testare:

Lascerei solo la scrittura dei tick su file quando OnCalculate è chiamato, per essere sicuro (non per testare OnBookEvent e CopyTicks, maOnCalculate, come previsto).

E poi per script avrebbe generato lo stesso file, ottenendo i tick tramite CopyTicks. La differenza sarebbe più evidente, e indicherebbe o dei tick mancati in OnCalculate o un funzionamento errato di CopyTicks.

 
Andrey Khatimlianskii:

Per essere sicuri (non per testare OnBookEvent e CopyTicks, ma OnCalculate, come previsto), lascerei solo i tick a scrivere nel file quando OnCalculate viene chiamato.

E poi per script avrebbe generato lo stesso file, ottenendo i tick tramite CopyTicks. La differenza sarebbe molto più chiara, e indicherebbe o il salto di tick in OnCalculate o il lavoro errato di CopyTicks.

Con un calcolo così semplice non vedo il motivo di preoccuparsi. C'è un confronto specifico tra due chiamate: SymbolInfoTick() e CopyTicks(). E tutte le chiamate di SymbolInfoTick() sono chiaramente mostrate. E si può vedere chiaramente che CopyTicks() ha restituito il tick, che non è stato ricevuto nella chiamata SymbolInfoTick() da OnCalculate(). E qui ci possono essere due ragioni per l'errore: 1. O OnCalculate() perde un tick, o 2. SymbolInfoTick() restituisce la cosa sbagliata da qualche parte.

Sì, questa è una parte del registro, che è stato raccolto per circa 30 secondi... quindi immaginate il numero di zecche mancanti.

 
Alexey Kozitsyn:

Il nostro dialogo con il service desk:

Salto di tick in OnCalculate
Aperto, Iniziato: 2017.05.22 14:52, #1751442

Guarda per non perderti:https://www.mql5.com/ru/forum/190129/page8#comment_5081300 e i prossimi 2 post.

CopyTicks dall'indicatore dà un tick che l'indicatore non ottiene in OnCalculate (né prima né dopo).

Squadra di supporto2017.05.23 09:44
Stato:Non elaboratoAperto
La tua domanda è stata accettata per la revisione.
Squadra di supporto2017.05.23 09:46

OnCalculate viene chiamato ad ogni tick.

Le zecche sono aggiunte al database in un thread separato. Cioè in modo asincrono. Non il fatto che con CopyTicks avrete lo stesso tick che ha chiamato OnCalculate.

Andrey Khatimlianskii 2017.05.23 14:08

Non si tratta di questo.

Con CopyTicks è possibile ottenere un tick, che non era in OnCalculate (lo apprendiamo in OnCalculate su un tick, il cui tempo è più lungo del mancato).

Date un'occhiata ai registri.

Squadra di supporto2017.05.23 14:13

Questo è esattamente ciò di cui stiamo parlando.

È arrivata una partita di zecche. Due thread iniziano ad elaborare questo pacchetto - un thread nel ciclo esegue OnCalculate su ogni tick del pacchetto; un altro thread mette l'intero pacchetto in un database di tick. Questi due thread non sono sincronizzati tra loro in alcun modo ed è sconosciuto quale thread elaborerà un pacchetto di tick più velocemente

Andrey Khatimlianskii 2017.05.23 14:26

Ma ogni tick del pacchetto dovrebbe essere elaborato da OnCalculate. E questo non sta accadendo.

Non c'è nessun tic con quel tempo. C'è un segno di spunta con meno tempo e un segno di spunta con più tempo. E non c'è nessuna chiamata OnCalculate in mezzo.

Squadra di supporto2017.05.23 14:33

komposter

Ma ogni tick del pacchetto deve essere gestito da OnCalculate. E questo non sta accadendo.

Non c'è nessun tic con quel tempo. C'è un segno di spunta con meno tempo e un segno di spunta con più tempo. E non c'è nessuna chiamata di OnCalculate tra di loro.

Ogni segno di spunta nel pacchetto viene elaborato a OnCalculate. Non ci sono salti. Il ciclo è scritto in questo modo.

Per scoprire quale tick viene elaborato in OnCalculate, usateSymbolInfoTick- qui tutto è chiaro. Il tick è applicato alle informazioni del simbolo e poi tutti gli indicatori di questo simbolo sono chiamati, tutto in un thread

Andrey Khatimlianskii 2017.05.23 14:36

Si prega di dare un'occhiata al registro al link.

SymbolInfoTick da OnCalculate non vede il tick, che può essere ottenuto da CopyTicks.

Ecco perché ho scritto

Squadra di supporto2017.05.23 14:40

Dobbiamo fare esattamente come hai suggerito inhttps://www.mql5.com/ru/forum/190129/page8#comment_5082755

Io, per essere sicuro (per testare OnCalculate invece di OnBookEvent e CopyTicks, come previsto), lascerei solo la scrittura dei tick nel file quando OnCalculate viene chiamato.

E poi per script avrebbe generato lo stesso file, ottenendo i tick tramite CopyTicks. La differenza sarebbe molto più chiara, e indicherebbe o il salto di tick in OnCalculate o un lavoro errato di CopyTicks.

Ed esattamente in questo modo abbiamo controllato una volta la correttezza di CopyTicks. Gli script di test e gli indicatori sono rimasti, li controlleremo di nuovo.

 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Bug, bug, domande

fxsaber, 2017.02.07 13:41

SymbolInfoTick negli indicatori funziona in modo abbastanza diverso rispetto agli EA.

In un indicatore restituisce sempre il tick che è stato l'iniziatore della chiamata OnCalculate. E questi tick iniziatori nell'indicatore non dovrebbero essere saltati - questa è l'ideologia degli sviluppatori. Il problema è nella formazione della coda di queste zecche.

In Expert Advisor, il SymbolInfoTick in OnTick non restituisce il tick che ha iniziato la chiamata di OnTick, ma fa una richiesta completa dello stato attuale.

Forum sul trading, sistemi di trading automatico e test di strategia

Caratteristiche del linguaggio mql5, sottigliezze e trucchi

fxsaber, 2017.03.29 22:32

L'evento Calcola viene generato su OGNI tick. Quindi c'è una coda di tick per gli indicatori. Se raggiunge un certo numero, c'è un avviso nel registro che l'indicatore è troppo lento.

Le barre stesse sono indicatori per natura e sono generate da Calculate-events. Quindi, se TF M1 ed è 10:15:00.020 e arriva un pacchetto di 50ms, il primo tick in esso ha ancora il tempo 10:14:59.970. E tutti gli indicatori sono chiamati prima su questo evento Calculate - prima l'indicatore delle serie temporali e poi gli indicatori personalizzati con queste serie temporali. Cioè in questa disposizione la barra delle 10:15 non è ancora formata come la barra zero. E la barra zero è 10:14.


Poi, quando il pacchetto inizia a srotolarsi tramite gli eventi Calculate, apparirà anche la barra delle 10:15. Credo di averla descritta in dettaglio.

Forum sul trading, sistemi di trading automatico e test di strategia

Caratteristiche del linguaggio mql5, sottigliezze e trucchi

fxsaber, 2017.03.29 22:41

Di conseguenza, è abbastanza normale per un EA ottenere un tick di una barra che non si è ancora formata. Ma questo è un punto così sottile che ci vuole uno sforzo per riprodurlo anche di proposito. In generale, è più teorico che pratico.


Se siamo paranoici sulla velocità, usare gli indicatori (e le barre, ovviamente) non è un'opzione. Tutto è nell'EA.

 
Andrey Khatimlianskii:

Il nostro dialogo con il Service Desk:

Service Desk è, purtroppo, nel loro repertorio. Non hanno bisogno di mettere un link quando si parla di discussione. Ma per fare un esempio concreto, sulle loro dita. Non è di questo che stanno parlando. Vale a dire, dicono che SymbolInfoTick() restituisce il tick corrente da controllare, e poiché OnCalculate() gestisce ogni tick - risulta che l'output dovrebbe essere di ogni tick. E CopyTicks() ci dice il contrario. Bene... E si dice, non guardare CopyTicks() :). Circa due fili hanno spiegato anche a me, quando stavano sistemando CopyTicks() alla fine dell'anno. Solo che non è il problema qui (anche se, forse, anche in esso, non so).

Non ha chiesto loro dei tick con bandiera 0 quando vengono ricevuti da OnBookEvent()?