Il bug di temporizzazione più pericoloso in un backtest può sfuggire anche a un controllo perfetto dei timestamp. Due eventi possono riportare entrambi le 10:00:00.000 e tuttavia essersi verificati in un ordine che il simulatore ha indovinato.
È importante ogni volta che una strategia reagisce a qualcosa di più delle barre completate: un aggiornamento di quotazione, uno scambio, un avviso di funding, una variazione dello stato dell’exchange o la conferma di un proprio ordine. Un timestamp indica quando è stato etichettato un evento. Non necessariamente quando la strategia avrebbe potuto agire.
Cosa cambia con l’ordinamento degli eventi?
Immagina una strategia che compra quando il miglior ask scende sotto $100.00. Nello stesso millisecondo, il feed registra un aggiornamento dell’ask a $99.99 e uno scambio a $99.99. Se il backtest elabora prima lo scambio e poi la quotazione, la strategia vede il nuovo ask e invia un ordine. Anche elaborare prima la quotazione può andare bene, purché l’evento fosse effettivamente disponibile. Ma se lo scambio ha consumato la liquidità esposta prima dell’arrivo dell’ordine, un’esecuzione a $99.99 è inventata.
Ordinare le righe solo per timestamp lascia al simulatore la scelta della sequenza degli eventi con orari identici. L’ordine nel file, quello dei simboli o il piano di esecuzione di una query al database possono diventare per caso regole di esecuzione. La curva azionaria può cambiare anche se i dati sottostanti sono gli stessi.
Ecco un modo efficace per vedere quanto possa essere arbitraria la cosa: ordina gli eventi con lo stesso orario per nome del simbolo invece che per sequenza di arrivo. Una strategia multi-asset può comportarsi diversamente solo perché un ticker viene prima di un altro nell’ordinamento.
Quali orari dovrebbe conservare un backtest?
I dati di mercato e la gestione degli ordini spesso coinvolgono diversi orari distinti. Conserva i campi forniti dalla fonte e definisci con precisione cosa rappresentano. Per molti feed sono utili sia il timestamp dell’exchange sia quello di ricezione locale; nessuno dei due rappresenta una verità universale su ciò che hanno visto tutti i partecipanti.
| Orario | Cosa registra | Cosa non può dimostrare da solo |
|---|---|---|
| Orario dell’evento sull’exchange | Quando, secondo la piattaforma, si è verificato un evento | L’ordine in cui un altro feed o il tuo processo l’ha osservato |
| Orario di ricezione | Quando il tuo sistema di raccolta ha ricevuto il messaggio | Quando la strategia ha finito di elaborarlo |
| Orario della decisione | Quando il codice ha valutato il segnale | Che il prezzo quotato fosse ancora disponibile |
| Orario di arrivo dell’ordine | Quando la piattaforma poteva agire sull’ordine | Un’esecuzione, a meno che le regole di matching e la liquidità non la consentano |
Per i dati storici senza orari di ricezione, dichiara le ipotesi adottate. Un backtest potrebbe elaborare gli eventi dell’exchange in sequenza e applicare un ritardo fisso di 5 ms tra la decisione e l’arrivo dell’ordine. È un modello, non una ricostruzione della storia. Se non hai numeri di sequenza per gli eventi con timestamp identici, anche la regola per risolvere i pareggi è un’ipotesi.
Come modello gli eventi con lo stesso orario?
Per prima cosa, conserva i numeri di sequenza della fonte, quando ci sono. Un numero di sequenza stabilisce l’ordine all’interno del proprio feed meglio di un timestamp, anche se gli spazi di sequenza possono essere distinti tra canali o prodotti.
Poi rendi esplicita la regola di elaborazione del simulatore. Per ogni evento, stabilisci se può aggiornare le informazioni della strategia, modificare la liquidità disponibile, attivare un ordine o confermare un ordine. Sono azioni diverse: accorparle in un unico «elabora riga» è il modo in cui si insinuano esecuzioni impossibili.
- Applica solo le informazioni di mercato arrivate entro l’orario della decisione della strategia.
- Genera l’ordine, poi portalo avanti fino all’orario di arrivo previsto sulla piattaforma.
- Consenti l’esecuzione solo contro liquidità idonea dopo l’arrivo, secondo le ipotesi di esecuzione previste per quel tipo di ordine.
- Registra gli input, l’ordinamento degli eventi e il ritardo usati per ogni esecuzione simulata.
Per una strategia basata su barre, tutto questo potrebbe essere più complesso di quanto richieda la domanda. Se il segnale usa barre da 1-minute completate e gli ordini vengono eseguiti all’apertura della barra successiva con un modello dei costi prudente, è improbabile che l’ordinamento al millisecondo cambi la conclusione della ricerca. L’obiettivo è adeguare il livello di dettaglio temporale all’affermazione che il backtest fa.
Posso fidarmi di un backtest senza dati sugli orari di arrivo?
Puoi comunque usarlo, ma tieni ben presenti i limiti. Se la strategia opera lentamente e ha limiti di rischio ampi, qualche millisecondo può essere irrilevante. Se reagisce a quotazioni fugaci, compete per la posizione in coda o dipende da un segnale lead-lag tra exchange, l’assenza degli orari di arrivo può essere determinante per il risultato.
Chi critica questo approccio ha ragione nel dire che una temporizzazione precisa degli eventi può creare una falsa precisione. I feed storici sono incompleti, gli orologi hanno derive e i timestamp delle piattaforme non rivelano ogni passaggio di rete. Anche un simulatore con campi al nanosecondo può basarsi su un’ipotesi di esecuzione approssimativa.
Perciò verifica la sensibilità invece di dichiarare certezze: ripeti la simulazione con criteri plausibili per risolvere i pareggi tra eventi e con diversi ritardi degli ordini, poi confronta il numero di operazioni, il prezzo di esecuzione e quali segnali resistono. Se il risultato dipende da una sequenza che i dati non permettono di stabilire, questa dipendenza va riportata nella relazione di ricerca. Un backtest può essere utile anche con un orologio imperfetto. Deve solo ammettere quali orari conosce davvero.
← Tutti gli articoli


