I mercati predittivi sembrano la cosa più facile del mondo da sottoporre a backtest. Il prezzo è compreso tra [0, 1]. Il payoff è un dollaro oppure niente. Niente leva, funding, basis o stranezze da perpetual swap alle 00:00 UTC. Avevamo già un backtester che gestiva i perpetual crypto con commissioni, funding e impatto, e il piano era dedicarci 2 giorni per adattarlo e poi iniziare a generare strategie.
Ce ne sono voluti 8. Ecco il diario, più o meno in ordine, compreso il giorno in cui la curva del capitale sembrava incredibile. E lo era.
Giorno 1: l’adattatore che doveva essere banale
La mappatura iniziale era uno a uno e sembrava lineare. Un mercato è uno strumento. Il prezzo YES è il prezzo. Comprare YES equivale ad andare long, comprare NO equivale ad andare short. La risoluzione è una chiusura forzata a 1.00 o 0.00. Inseriamo la serie oraria dei prezzi nello stesso event loop e abbiamo finito.
Questa mappatura ha retto circa 90 minuti a contatto con dati reali. La prima cosa a saltare è stata la serie dei rendimenti. Tutto il nostro livello di rischio — dimensionamento delle posizioni, vol targeting, report Sharpe — presupponeva rendimenti logaritmici di uno strumento continuativo. Un mercato che passa da 0.04 a 0.00 ha un rendimento logaritmico indefinito e una perdita totale ben definita. E un mercato a 0.04 3 giorni prima della risoluzione è un oggetto completamente diverso da uno a 0.04 4 minuti prima, anche se in entrambe le righe compare 0.04.
Abbiamo finito per riparametrizzare l’intera serie in funzione del tempo alla risoluzione anziché dell’ora sul calendario, e per trattare il PnL come terminale anziché valutato ai prezzi di mercato. Era la scelta giusta, ma ha invalidato tutto il codice di reporting a valle.
Giorno 2: la formula delle commissioni è la strategia
Su Kalshi la commissione di trading non è una decurtazione in punti base. È quadratica rispetto al prezzo: circa 0.07 × contracts × P × (1−P), arrotondata per eccesso al centesimo a livello di ordine. Questo significa che la commissione è massima proprio dove un mercato da testa o croce è più interessante, e quasi nulla nelle code.
| Prezzo | Commissione per contratto | Vantaggio necessario (punti di probabilità) | Commissione in % della puntata |
|---|---|---|---|
| 5¢ | 0.33¢ | 0.33 | 6.7% |
| 10¢ | 0.63¢ | 0.63 | 6.3% |
| 25¢ | 1.31¢ | 1.31 | 5.3% |
| 50¢ | 1.75¢ | 1.75 | 3.5% |
| 75¢ | 1.31¢ | 1.31 | 1.8% |
| 90¢ | 0.63¢ | 0.63 | 0.7% |
| 95¢ | 0.33¢ | 0.33 | 0.35% |
La terza colonna è quella che conta: per andare in pareggio comprando a 50¢ e mantenendo la posizione fino alla risoluzione, la tua stima della probabilità deve superare quella del mercato di 1.75 punti. Non dell’1.75% in termini relativi: 1.75 punti assoluti. Se esci prima della risoluzione invece di mantenere la posizione, la paghi due volte, oltre allo spread.
Storicamente il CLOB di Polymarket ha avuto una struttura delle commissioni molto diversa, vicina allo zero sulla singola operazione, con i costi concentrati invece nello spread e nella profondità. La stessa logica strategica ha quindi un’economia completamente diversa a seconda della venue, e ogni confronto tra venue che usa un unico modello di commissioni è inventato. Ora usiamo una funzione di calcolo delle commissioni per ogni venue, non un valore scalare.
Se leggi una sola riga di un report di backtest sui mercati predittivi, guarda quella delle commissioni espresse in punti di probabilità. Una strategia che dichiara un vantaggio previsionale di 1.2 punti sui mercati a 50¢ perde su Kalshi ancora prima di considerare qualsiasi altro costo. Questo dato deve essere visibile nella prima pagina, senza che il lettore debba ricavarselo da sé.
Giorno 3: il book è una scala e ha pochi gradini
Il nostro modello d’impatto era una funzione a radice quadrata calibrata sui book dei perpetual BTC. La forma è sbagliata. Con un tick da 1¢ su uno strumento da $1 ci sono solo 99 livelli di prezzo possibili nell’intero book; un mercato con liquidità media può avere qualche centinaio di contratti in attesa al livello superiore e poi un vuoto.
Ecco un’istantanea del lato YES di un mercato sui dati economici che stavamo campionando, circa 30 ore prima della risoluzione:
| Livello | Quantità (contratti) | Costo cumulato dell’acquisto |
|---|---|---|
| 42¢ | 310 | 310 @ 42.0¢ medio |
| 43¢ | 85 | 395 @ 42.2¢ medio |
| 45¢ | 140 | 535 @ 42.9¢ medio |
| 49¢ | 600 | 1,135 @ 46.1¢ medio |
Un ordine da 1,000 contratti — 500 dollari di rischio, un errore di arrotondamento nel mondo crypto — sposta il prezzo effettivo di 4 centesimi. Più del doppio della commissione. Qui non c’è una funzione regolare da approssimare: devi percorrere il book livello per livello, altrimenti stai inventando i dati. Abbiamo eliminato il modello a radice quadrata per questa classe di asset e scritto un algoritmo che percorre il book alla lettera: è più lento, ma corretto.
A un certo punto mi sono accorto che mi irritava il fatto che questi mercati fossero «troppo piccoli per contare». Sono piccoli perché il prezzo riguarda una singola domanda sul mondo reale, con una scadenza, e non sono poi così tante le persone che hanno un’opinione sulle richieste iniziali di sussidi di disoccupazione negli Stati Uniti, un mercoledì. Le dimensioni sono il mercato. Lamentarsene è come lamentarsi che a un tavolo da poker ci siano solo 9 posti.
Giorno 4: il giorno della splendida curva del capitale
Sharpe 4.1 su 1,400 mercati. Lineare. A qualsiasi ricercatore dovrebbe venire un tuffo al cuore, e a me è venuto, anche se solo 40 minuti dopo averne già fatto uno screenshot.
Il bug era nel ricampionatore. La cronologia dei prezzi dei mercati illiquidi arriva con timestamp irregolari, quindi l’abbiamo riallineata a una griglia oraria uniforme. L’ultimo punto di ogni serie archiviata è il valore di settlement, 1.00 o 0.00. Il nostro riallineamento riempiva i valori usando l’osservazione più vicina, senza vincolare la direzione: così, per qualsiasi mercato in cui l’ultimo scambio precedeva la risoluzione di alcune ore, il valore di settlement si propagava all’indietro lungo l’intervallo. Il modello leggeva la risposta di domani nella riga di oggi, proprio per i mercati illiquidi in cui poteva aumentare la posizione senza incorrere nei limiti di profondità.
Riempire i valori con l’osservazione più vicina va bene per uno strumento continuativo. Per uno strumento la cui ultima osservazione è la verità a posteriori, è una macchina per sbirciare nel futuro. Ora imponiamo che ogni riempimento avvenga solo in avanti e che la riga di settlement sia contrassegnata ed esclusa da qualsiasi calcolo delle feature. Questa asserzione è lunga 9 righe ed è il codice più prezioso che abbiamo scritto in tutta la settimana.
Giorni 5–6: 1,412 mercati, circa 180 scommesse
La dimensione del campione nei mercati predittivi è una trappola dall’aspetto innocuo. Risolvi 1,412 mercati, pensi di avere 1,412 osservazioni e calcoli di conseguenza una statistica t. Ma 14 partite NFL della stessa domenica condividono condizioni meteo, pubblicazione dei referti sugli infortuni e flussi comuni di scommesse. I 51 mercati elettorali statali dipendono tutti dalla stessa oscillazione nazionale. «X accadrà entro il 31 marzo» e «X accadrà entro il 30 giugno» sono la stessa scommessa con scadenze diverse, e si risolvono insieme.
Abbiamo raggruppato i mercati per fonte dell’evento sottostante e data di risoluzione: il numero effettivo di osservazioni indipendenti è risultato vicino a 180. Non bastano per distinguere un vantaggio reale dal rumore alle dimensioni dell’effetto che stavamo esaminando, e nessun bootstrap per singolo mercato può risolvere il problema, perché il bootstrap deve ricampionare i gruppi, non le righe. Sbagliare gonfia la significatività di un fattore compreso tra 2 e 3, senza che ci si accorga di nulla.
Giorno 7: anche la risoluzione è una distribuzione di probabilità
Le cose che non avevamo modellato affatto e che abbiamo scoperto a nostre spese:
- Risoluzione anticipata. Un mercato «entro il 31 dicembre» può risolversi il 4 agosto, quando l’evento si verifica davvero. Il capitale torna prima e il periodo di detenzione non è mai stato quello suggerito dal nome del contratto.
- Contestazioni. I mercati risolti tramite oracolo prevedono una finestra per contestare l’esito. Una posizione può restare in sospeso per giorni dopo l’evento e, in pochi casi, l’esito può ribaltarsi rispetto all’interpretazione più ovvia.
- Annullamenti. Dati di fonte ambigui portano all’annullamento del mercato e al rimborso di tutti. Nel nostro campione riguardano meno dell’1% dei mercati, ma si concentrano proprio sulle domande ambigue che un modello tende a giudicare mal prezzate.
- Capitale immobilizzato. Un vantaggio di 3 punti realizzato in 90 giorni e uno realizzato in 6 ore non sono confrontabili; un backtest che riporta il vantaggio totale senza rapportarlo al tempo per cui il capitale è stato impegnato preferirà sempre quello più lento.
Abbiamo aggiunto al simulatore un termine per il costo di mantenimento della posizione e una variazione casuale della data di risoluzione. Nessuno dei due è preciso. Entrambi sono meglio dell’ipotesi implicita che la risoluzione avvenga con certezza esattamente alla data indicata.
Giorno 8: cosa salteremmo e da dove cominceremmo
- Lasceremmo perdere del tutto l’impianto basato sui rendimenti. Non adatteremmo un livello di gestione del rischio con vol targeting a uno strumento con payoff terminale. Scriveremmo un livello di dimensionamento delle scommesse che ragiona in termini di probabilità e puntata. Abbiamo perso 2 giorni cercando di adattare quello vecchio.
- Costruiremmo la funzione delle commissioni prima della strategia. Tracceremmo la curva del vantaggio necessario per andare in pareggio per ogni venue su cui intendiamo operare e la appenderemmo sopra la scrivania. Elimina circa la metà delle idee prima ancora che costino un’esecuzione del backtest.
- Percorreremmo il book fin dal primo giorno. Qualsiasi modello parametrico d’impatto importato da un mercato continuo sarà sbagliato in un modo che ti favorisce.
- Raggrupperemmo prima di contare. Decideremmo come raggruppare i dati per calcolare la dimensione effettiva del campione nello stesso momento in cui definiamo l’universo, non dopo aver trovato uno Sharpe che ci piace.
- Imporremmo la direzione dei riempimenti. Una riga di controllo per ogni join. Se una serie termina con la verità a posteriori, il riempimento all’indietro è per definizione un bug, non qualcosa che speri di notare in revisione.
Quegli 8 giorni sono valsi la pena, soprattutto perché i mercati predittivi eliminano le ambiguità che rendono così facile ingannarsi con i backtest crypto. Niente tasso di funding da liquidare con un’alzata di spalle, niente convenzioni sul mark price da discutere. Solo una domanda, una scadenza e una risposta. Quando il backtest sbaglia qui, puoi indicare esattamente dove.
← Tutti gli articoli

