Librerie: SuTickMulti - pagina 5

 
Stanislav Korotky #:

Per poter realizzare un test case completo, avrei bisogno di capire il contesto pratico: operiamo esclusivamente su tick il cui tempo coincide con una precisione al millisecondo?

No. L’obiettivo è avere sempre un ambiente aggiornato per tutti i simboli. Nel mio esempio, in OnTimer la condizione di aggiornamento è sempre soddisfatta. L’apertura della posizione è solo a scopo dimostrativo.
 
fxsaber #:
No. L'obiettivo è quello di avere sempre un contesto aggiornato per tutti i simboli. Nel mio esempio, in OnTimer la condizione di aggiornamento viene sempre soddisfatta. L'apertura della posizione è solo a scopo dimostrativo.

Va bene.

Per ora non è chiaro dove l'implementazione sull'evento OnTickMulti "perda" il tick o, in altre parole, come mai SymbolInfoTick restituisce prezzi diversi da quelli previsti (in precedenza avevo ipotizzato che probabilmente ci fosse un ritardo dovuto alla gestione degli eventi personalizzati dell'indicatore) - proverei senza l'indicatore "spia" per la purezza dell'esperimento - semplicemente SymbolInfoTick/CopyTicks su tutti i simboli dal normale OnTick, almeno per lo stesso timestamp.

Per quanto riguarda OnTimer, mi solleva alcune perplessità (correggetemi se sbaglio):

void OnTimer()
{
  if (TimeMsc++ == 1759280400081) // 01/10/2025 01:00:00.081
    PositionOpen();
}

Non abbiamo alcuna garanzia che il handler venga eseguito in meno di un millisecondo, quindi un semplice incremento del contatore non garantisce il mantenimento della sincronizzazione iniziale, ovvero la sincronizzazione con l’ora del server deve essere eseguita correttamente al volo ogni volta (dopo l’apertura di una posizione o altri calcoli più complessi dell’incremento, se presenti). In altre parole, l’approccio ottimizzato sopra descritto non funzionerà quando sarà necessario aprire molte posizioni.

Inoltre, anche la sincronizzazione iniziale (inizializzazione del contatore) non è al 100% perfetta, a mio parere.

ulong TimeMsc = TimeTradeServer() * 1000 + (inTimer && EventSetMillisecondTimer(1));

Supponiamo che nel tester l’ora del server inizi effettivamente senza millisecondi, ma come funzionerebbe un codice del genere in ambiente online? E perché aggiungiamo 1 millisecondo? Io preferirei comunque ricavare l’ora del server dai tick.

Non si tratta di pignoleria, ma semplicemente di dubbi riguardo al «rispetto costante della condizione di attualità».

 
Stanislav Korotky #:

un semplice incremento del contatore non garantisce il mantenimento della sincronizzazione iniziale

Nel Tester è garantito.

Ma come funzionerà questo codice in modalità online?

Online questo problema non si presenta, poiché tutti i dati che arrivano al terminale sono indicativi: non aggiornati a causa dei ritardi.

E perché aggiungiamo 1 millisecondo?

Perché il primo OnTimer verrà attivato dopo un intervallo prestabilito, e non immediatamente.

 
Stanislav Korotky #:

Per ora non è chiaro dove l'implementazione dell'evento OnTickMulti "perda" un tick o, in altre parole, come mai SymbolInfoTick restituisca prezzi diversi da quelli previsti

OnTickMulti non c’entra di certo, poiché la stessa SymbolInfoTick predefinita restituisce il tick corretto per uno dei simboli, ma non per gli altri.


La causa risiede esclusivamente nella sequenza di invio dei tick.

Forum sul trading, sui sistemi di trading automatici e sul test delle strategie di trading

Librerie: OnTickMulti

fxsaber, 30/09/2025 09:24

I tick con lo stesso tempo non arrivano contemporaneamente. Arrivano tutti in sequenza. E se il tick su EURUSD con il tempo maggiore è arrivato per primo, in quel momento non si sa nulla del tick con lo stesso tempo su GBPUSD, che arriverà per secondo. Pertanto, al momento dell’arrivo del primo tick EURUSD, il secondo tick GBPUSD semplicemente non c’è, ma sono disponibili i dati del tick GBPUSD precedente.
 
fxsaber #:

Perché il primo OnTimer verrà attivato dopo un intervallo prestabilito, e non immediatamente.

Ho ideato un metodo rapido per aggiornare tutti i dati.

#include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/it/code/47647

#include <MT4Orders.mqh> // https://www.mql5.com/it/code/16006

void PositionOpen()
{
  for (uint i = ArraySize(OnTickMultiObject.Symbols); (bool)i--;)
  {
    const string SymbName = OnTickMultiObject.Symbols[i];
    
    OrderSend(SymbName, OP_BUY, 1, SymbolInfoDouble(SymbName, SYMBOL_ASK), 0, 0, 0);
  }
}

long CurrentTime = 0;

// OnTick multicarattere.
void OnTickMulti( const string &Symb, const uint &Index )
{  
  MqlTick Tick;
  
  if (SymbolInfoTick(Symb, Tick) && (Tick.time_msc > CurrentTime))
  {
    CurrentTime = Tick.time_msc;
    
    EventSetMillisecondTimer(1);
  }  
}

void OnTimer()
{
  if (CurrentTime == 1759280400081) // 01/10/2025 01:00:00.081
    PositionOpen();
    
  EventKillTimer();
}

Questo meccanismo permette, anche in modalità standard (monovaluta senza OnTickMulti), di lavorare solo con dati aggiornati. Ad esempio, per la coppia EURUSD ci sono diversi tick con lo stesso orario. L'aggiornamento permette di lavorare con il tick più recente, ovvero l'ultimo di quella sequenza.


P.S. Questo è un altro motivo per creare simboli personalizzati: inserire nella cronologia solo l’ultimo tick delle sequenze con lo stesso orario. In questo caso, in modalità monovaluta l’aggiornamento sarà sempre garantito.

Библиотеки: TicksShort
Библиотеки: TicksShort
  • 2025.09.26
  • www.mql5.com
Статьи и техническая библиотека по автоматическому трейдингу: Библиотеки: TicksShort
 
Rorschach #:

Ma i prezzi di apertura sono gli stessi, anche se l'orario di apertura è identico per tutti i titoli.

E a causa di questo comportamento, è impossibile testare correttamente una serie di sistemi.

Mi sono ricordato della modalità del tester basata sui prezzi di apertura. Il punto è che, nonostante il nome, in questa modalità il tester genera 4 tick OHLC, e non 1 come ci si aspetterebbe intuitivamente dal nome. Di questi 4 punti di controllo, per gli expert advisor viene preso solo il primo (O) e viene chiamato OnTick, mentre per gli indicatori, in aggiunta, per HLC o LHC (a seconda della direzione della barra) viene chiamato 3 volte OnCalculate con i tick relativi ai prezzi corrispondenti. I tempi per questi tre punti aggiuntivi vengono impostati artificialmente pari agli ultimi tre secondi della barra. Ne consegue che l’indicatore spia invia più eventi per i simboli invece di uno solo. Probabilmente, chi utilizza la modalità basata sui prezzi di apertura dovrebbe tenerne conto.

Ho inoltre osservato un artefatto (aggiungendo il debug al mio indicatore "spia" analogo tratto dal libro): l’evento relativo al tick del simbolo aggiuntivo della barra precedente, per qualche motivo, si ripete sulla nuova barra, solo che poi viene chiamato il metodo OnCalculate dello spia e arriva l'evento relativo al nuovo tick del simbolo aggiuntivo con il prezzo aggiornato. Di conseguenza, per avere il prezzo aggiornato dei simboli aggiuntivi è necessario che gli eventi stessi contengano un timestamp e non elaborare nuovamente gli eventi già elaborati. Io lo faccio nel mio codice al momento dell’invio in questo modo:

int OnCalculate(const int rates_total, const int prev_calculated, const int, const double &price[])
{
   MqlTick tick;
   SymbolInfoTick(_Symbol, tick);
   EventChartCustom(Chart, Message, Index, (double)tick.time_msc, NULL);
  
   return rates_total;
}

E in fase di ricezione (viene mostrato il caso di un singolo simbolo aggiuntivo, per molti è necessario un array timestamp[]!):

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
   if(id == CHARTEVENT_CUSTOM + Message)
   {
      static long timestamp;
      long event = (long)dparam;
      if(event > timestamp)
      {
         OnSymbolTick((int)lparam);
         timestamp = event;
      }
   }
}

Va notato che, in presenza di tick con lo stesso valore in millisecondi, viene eseguito il primo di essi, non l’ultimo.

 
Rorschach #:
Il modo più semplice per sincronizzare
Pensavo che la sincronizzazione delle serie temporali fosse un problema ben studiato e che esistessero algoritmi già pronti, ma quando ho cercato su Internet non ho trovato nulla