Pubblicato come Idea TradingView su ETHUSDT. Guarda il grafico su TradingView
Se vi è mai capitato di portare un indicatore in Python per fargli un backtest, o di fidarvi di uno script perché arrivava con una verifica, qui si parla del vuoto che quelle due cose lasciano aperto.
Abbiamo ricostruito tre dei nostri indicatori perché un backtest potesse girarci sopra. Tutte e tre le ricostruzioni contenevano una costante sbagliata. Tutte e tre hanno superato la loro validazione. Nemmeno una è stata intercettata da un test.
Perché ricostruire un indicatore, poi
Uno script Pine gira sul vostro grafico. Non percorre sei anni di storico in un ciclo, e non risponde alla domanda se un segnale paghi davvero. Per porre quella domanda lo si ricostruisce in qualcosa che si possa eseguire migliaia di volte.
È in quella ricostruzione che un indicatore smette silenziosamente di essere lo stesso indicatore.
Il bug che è costato di più, ed è una barra
Una delle lunghezze dentro Volume Oracle è derivata dal timeframe:
target bars = 36 hours × 60 / 240 minutes = 9
regime length = round(9 × 2.5) = round(22.5)
Il math.round di Pine risolve i pareggi allontanandosi dallo zero. Dà 23. Il round() di Python 3 usa l'arrotondamento bancario, che risolve i pareggi verso il numero pari. Dà 22.
Entrambe sono implementazioni corrette dell'arrotondamento. Sono semplicemente convenzioni diverse, e nulla vi avverte che siete passati dall'una all'altra.
Ogni lookback derivato da quel numero si è spostato con lui. Il risultato sulla riga meglio supportata di una scansione di 36 segnali:
| versione | vantaggio a 48 h | tasso di successo | n |
|---|---|---|---|
| ricostruito, lunghezza 22 | +0,423% | 51 | 1216 |
| corretto, lunghezza 23 | +0,260% | 50 | 1223 |
Un taglio del 38% dovuto a una convenzione di arrotondamento.
Poi abbiamo messo a verbale la lezione sbagliata
La nota che avevamo scritto diceva che accadeva solo su 4H. Era stata scritta dall'unico timeframe che in quel momento era sotto test, ed è rimasta così per due mesi.
Facendo girare la stessa aritmetica su ogni timeframe:
| timeframe | lunghezza di regime | lunghezza di flusso | risultato |
|---|---|---|---|
| 5m | 45 contro 45 | 23 contro 22 | diverge |
| 2H | 45 contro 45 | 23 contro 22 | diverge |
| 4H | 23 contro 22 | 12 contro 11 | diverge |
| 8H | 53 contro 52 | 27 contro 26 | diverge |
| 1D | 18 contro 18 | 9 contro 9 | pareggia, concorda |
| 3D, 1W | 15 contro 15 | 8 contro 8 | pareggia, concorda |
Quattro su sedici, non uno.
Da quella tabella cadono fuori due cose che nessun ragionamento aveva prodotto.
Un pareggio non basta. 1D, 3D e 1W cadono tutti esattamente su ,5 e concordano. L'arrotondamento bancario sposta soltanto un pareggio la cui risposta arrotondata per eccesso è dispari, quindi round(17.5) fa 18 in entrambi i casi. Circa metà di tutti i pareggi sono innocui, ed è proprio per questo che controllarne uno a campione non dimostra nulla.
La divergenza può arrivare un passo più tardi. Su 5m e 2H la prima lunghezza concorda a 45. La riga successiva, round(45 × 0.5), è di nuovo 22,5, e quella si divide. Se controllate la prima costante e tirate dritto, date il via libera a entrambi i timeframe a torto.
Gli altri due, in breve
Harmonic normalizza un oscillatore ritagliandolo su una banda mobile. Nel sorgente ogni barra viene ritagliata dalla propria banda. La ricostruzione ritagliava un'intera finestra di 200 barre usando la banda della barra corrente, che è una funzione diversa. Differenza misurata su 11.497 barre: 0,47 punti in media. Un vero errore di trascrizione senza effetto materiale.
Quello lì, per giunta, lo abbiamo gonfiato prima di misurarlo. È stato annunciato, alla sola lettura del codice, come quasi certamente la deriva del 9%. Il numero era 0,47. Un bug vero e un bug rilevante sono due affermazioni diverse, e l'ordine di grandezza si misura prima di dare un nome all'impatto.
Plutus Flow media il volume su 50 barre per individuare i picchi. La ricostruzione ne usava 20, perché era il numero che credevamo di sapere. Effetto: sotto un decimo di punto percentuale, nessun cambio di segno. Il verdetto non si è mosso, ma il numero era sbagliato e ora è giusto, che è l'unico metro che conta.
La parte che è davvero la lezione
Ecco che cosa riportava allora la validazione di ciascuna ricostruzione.
| ricostruzione | il suo stesso controllo | che cosa significava |
|---|---|---|
| Volume Oracle | 3 su 3 prima, 3 su 3 dopo | non è riuscito a distinguerle |
| Harmonic | 6 su 8 prima, 5 su 8 dopo | ha dato un punteggio più alto alla versione con il bug |
| Plutus Flow | mai eseguito | — |
È sulla riga di mezzo che vale la pena fermarsi. La validazione ha preferito il codice sbagliato. Se avessimo lasciato decidere il controllo, ci avrebbe riportati dentro il bug a forza di argomenti.
Una validazione che confronta un solo valore in uscita non può rilevare una costante in ingresso sbagliata. L'output è un setaccio troppo grossolano. Molti insiemi di parametri sbagliati e diversi producono oggi la stessa etichetta di regime, lo stesso stato di incrocio, lo stesso colore sul grafico. Differiscono su barre che in questo momento non state guardando, ed è esattamente lì che vive un backtest.
Che cosa fare invece
Stampate ogni parametro derivato. Ogni lunghezza, ogni soglia, ogni moltiplicatore. Confrontateli con il sorgente riga per riga, prima di dare un voto a qualsiasi cosa.
Tenete il controllo sull'output. Intercetta un'altra classe di errori ed è necessario. È soltanto ben lontano dall'essere sufficiente, e tutti e tre gli sono passati davanti indisturbati.
L'ambito onesto
Il codice Pine era corretto in tutti e tre i casi. Ciò che era sbagliato era l'apparato costruito per testarlo, che è la versione più scomoda del problema: lo strumento è andato alla deriva, e l'autocontrollo dello strumento stesso diceva di no.
La cifra del 38% è una riga, una scansione, un timeframe, dentro il campione, ed è citata dal nostro registro anziché ricalcolata. Il risultato sull'arrotondamento è riproducibile con un solo comando, e correggendolo è emerso che la nostra stessa nota in proposito era sbagliata da due mesi.
Pubblicato come Idea TradingView su ETHUSDT. Guarda il grafico su TradingView
Misurazione passata dei nostri stessi strumenti, descritta a posteriori. Nulla di quanto sopra è una raccomandazione o un'indicazione di risultati futuri.