← Torna agli articoli
July 2, 2026
5 min di lettura

Il Design della Funzione Obiettivo: La Metrica che Ottimizzi Sceglie di Nascosto la Tua Strategia

Il Design della Funzione Obiettivo: La Metrica che Ottimizzi Sceglie di Nascosto la Tua Strategia
#algotrading
#backtest
#overfitting
#funzione-obiettivo
#ottimizzazione
#sharpe
#validazione
🎯
Part 1 of 7 · Collection
Backtesting Without Fooling Yourself

Fa parte della serie "Backtest Senza Illusioni".

📄 Questo articolo è cresciuto fino a diventare un paper di ricerca. Ogni numero qui sotto proviene da un unico script deterministico che costruisce una ground truth controllata — un mercato sintetico con un vantaggio noto in una banda di segnale moderata e rumore a code grasse ovunque — e poi esegue un'unica ricerca di soglia sotto sei diverse funzioni obiettivo, misurando, out of sample, quale strategia ciascun obiettivo sceglie realmente. Leggi il paper online (versione interattiva + PDF) su objective-design.marketmaker.cc, codice e dati su github.com/suenot/objective-design-degeneracy.

Vuoi la strategia migliore. Quindi esegui una ricerca — fai uno sweep su una soglia, un lookback, una distanza di stop, e tieni qualunque impostazione ottenga il punteggio più alto. La ricerca finisce e ti consegna un vincitore. Ragionevole. Standard. È ciò che fa ogni optimizer, grid search e hyperparameter tuner sulla faccia della terra.

Ma guarda il verbo: ottiene il punteggio più alto. Più alto rispetto a cosa? Prima che la ricerca possa incoronare qualcosa, le hai dovuto consegnare un unico numero da massimizzare — una funzione obiettivo. PnL. Sharpe. Sharpe-sui-bar-tradati. Return-su-max-drawdown. Ne hai digitato uno di questi, probabilmente senza pensarci troppo, e poi la ricerca ha speso un milione di valutazioni facendo esattamente ciò che le hai chiesto.

Quella singola scelta non è una formalità. È l'intera decisione. La ricerca non trova "una buona strategia" — una cosa del genere non esiste in astratto. Trova la strategia che massimizza lo scalare che hai scelto, e scalari diversi puntano a strategie radicalmente diverse sugli stessi dati. L'obiettivo è la mano segreta sul volante, e per la maggior parte del tempo nessuno la sta guardando.

Ecco l'intero articolo in un'unica tabella. Un'unica ricerca di soglia, un unico mercato sintetico con un vantaggio reale e noto, sei obiettivi — e le sei strategie che selezionano, misurate su dati held-out:

Obiettivo (cosa massimizza la ricerca) Esposizione media al mercato Sharpe in-sample Sharpe out-of-sample Vincitori degeneri
PnL grezzo 0.859 1.76 1.61 0%
Sharpe sull'intera timeline 0.740 1.82 1.71 0%
Sharpe per-trade ("active") 0.286 1.00 0.70 57%
Floor di esposizione (emin=0.20e_{\min}=0.20) 0.740 1.82 1.71 0%
Shrinkage sul conteggio dei trade (conf_k=40=40) 0.523 1.54 1.31 20.7%
Robusto (floor + conf_k) 0.675 1.78 1.70 0.2%

600 seed indipendenti, T=2000T = 2000 bar ciascuno, 80 soglie candidate per ricerca, in-sample e out-of-sample estratti indipendentemente. Sharpe annualizzato (252 periodi/anno). "Degenere" = il vincitore selezionato è nel mercato meno del 5% del tempo, oppure ottiene uno Sharpe out-of-sample non positivo. Il vero ottimo di questo mercato è uno Sharpe out-of-sample annualizzato di 1.77.

Leggi la terza riga finché non brucia. Lo Sharpe per-trade — un rappresentante dell'intera famiglia di metriche condizionate all'attività (Sharpe per-trade, expectancy, SQN di van Tharp, win rate), tutte calcolate solo sui bar in cui hai tradato — seleziona una strategia che out of sample è peggiore di metà delle altre, e lo fa in modo degenere il 57% delle volte. Non è un obiettivo sottilmente peggiore. Su questi dati è una trappola, e la ricerca ci cade dentro più della metà delle volte. Ora leggi la riga appena sopra: il semplice Sharpe sull'intera timeline non degenera mai e segna 1.71 out of sample. Questo è il punto centrale dell'intera riparazione, svelato in anticipo — la correzione onesta è semplicemente misurare sull'intera timeline; i rimedi più sofisticati nelle righe in basso, nel migliore dei casi, si limitano a eguagliare quel numero, senza mai batterlo. Questo articolo è l'anatomia di quella trappola e della sua correzione, con la ground truth nota per tutto il tempo, così che "l'obiettivo ha scelto la strategia giusta?" sia un fatto, non un'opinione.

Atto 1 — La decisione segreta: la legge di Goodhart è la ricerca

Una ricerca di parametri raffigurata come un imbuto di molte curve di strategia candidate, con un'unica lente etichettata OBIETTIVO che timbra una curva come vincitrice mentre curve dall'aspetto identico vengono scartate, a illustrare che la scelta della metrica seleziona di nascosto la strategia

Nel 1975 l'economista Charles Goodhart scrisse una frase che è sopravvissuta a tutto il resto del suo lavoro:

"Qualsiasi regolarità statistica osservata tenderà a collassare non appena su di essa viene esercitata una pressione a fini di controllo."

La parafrasi popolare, di solito attribuita a Marilyn Strathern, è più incisiva: quando una misura diventa un obiettivo, smette di essere una buona misura.

Una ricerca di parametri è l'istanza più pura possibile della legge di Goodhart. La funzione obiettivo è la misura. La ricerca è la pressione — migliaia, milioni di tentativi di spingere quella misura più in alto possibile. E alla ricerca non importa minimamente cosa intendevi con quella misura. Le importa solo del numero. Se esiste un modo qualsiasi per rendere grande quel numero che non ha nulla a che fare con un vantaggio reale e tradabile — tradare raramente, restare flat per la maggior parte del tempo, agganciare un paio di outlier fortunati — la ricerca troverà quel modo, perché trovare il massimo è l'unica cosa per cui è costruita.

Questo è lo stesso fallimento che la letteratura sull'AI-safety chiama reward hacking: un agente che ottimizza un proxy per ciò che vuoi sfrutterà ogni divario tra il proxy e l'obiettivo reale. La tua ricerca è quell'agente. "Sharpe ratio" è quel proxy. "Una strategia di cui posso fidarmi per tradare soldi veri il prossimo trimestre" è l'obiettivo reale. Il divario tra i due è dove vive l'intera disciplina.

Per osservare quel divario aprirsi, ci serve un mondo di cui conosciamo la verità. Quindi ne costruiamo uno.

Il mercato. In ogni periodo arriva un predittore sts_t (un segnale Normale-standard), seguito dal rendimento rtr_t che predice parzialmente. Il vantaggio è reale ma limitato — esiste solo dentro una banda di segnale moderata st1|s_t| \le 1, e svanisce al di fuori di essa:

rt=βst1[st1]+εt,β=0.3,εtt4 (unit variance).r_t = \beta\, s_t \cdot \mathbf{1}\big[\,|s_t| \le 1\,\big] + \varepsilon_t, \qquad \beta = 0.3, \qquad \varepsilon_t \sim t_{4}\ (\text{unit variance}).

Due scelte di design contano. Primo, il vantaggio vive nella banda moderata: i segnali estremi non portano alcuna informazione predittiva, quindi una strategia dovrebbe tradare il centro e saltare le code. Secondo, il rumore εt\varepsilon_t è a code grasse (Student-tt con 4 gradi di libertà, il tipo di coda pesante che i rendimenti reali hanno davvero) — ma questo ingrediente è qui per realismo, non per meccanismo. È tentante dire che le code grasse siano ciò che rende possibile la trappola, ed è esattamente ciò che abbiamo assunto finché non abbiamo eseguito il controllo: una versione a rumore Gaussiano di questo mercato (gaussian_control nei risultati, 300 seed) riproduce la trappola in modo sostanzialmente invariato — l'obiettivo per-trade degenera ancora il 55.7% delle volte sotto rumore Gaussiano contro il 57.0% con code grasse, e il suo Sharpe out-of-sample è 0.71 contro 0.70. Quindi la trappola non riguarda le code grasse. È un puro effetto di piccolo-campione-più-selezione: prendi il massimo, su ~20 soglie a bassa esposizione, di uno Sharpe calcolato su una manciata di osservazioni, e qualche angolo fortunato sembrerà sempre spettacolare. Qualsiasi distribuzione di rumore lo fa; una strategia nel mercato per solo pochi bar può, per pura fortuna, attraversare un paio di mosse favorevoli e ottenere un numero in-sample che non significa nulla. Manteniamo le code grasse perché i rendimenti reali le hanno, non perché la trappola ne abbia bisogno.

La strategia. Una famiglia a un parametro. Tradare nella direzione del segnale ogni volta che la sua magnitudine è sotto una soglia θ\theta, altrimenti restare flat:

post=sign(st)1[stθ].\text{pos}_t = \operatorname{sign}(s_t)\cdot \mathbf{1}\big[\,|s_t| \le \theta\,\big].

Un θ\theta minuscolo tradà solo sui segnali più piccoli e insignificanti — una lotteria a trade rari, quasi mai nel mercato. Un θ\theta vicino al bordo della banda cattura l'intero vantaggio reale ed è ben esposto. Un θ\theta enorme tradà tutto, inclusi i bar fuori-banda che non portano vantaggio e aggiungono solo rumore.

def gen_dataset(T, rng, beta=0.30, band=1.0, tail_df=4):
    s    = rng.standard_normal(T)
    edge = beta * np.where(np.abs(s) <= band, s, 0.0)          # edge ONLY inside |s| <= 1
    t    = rng.standard_t(tail_df, T) / np.sqrt(tail_df / (tail_df - 2.0))  # fat tails, unit var
    return s, edge + t

def simulate(s, r, theta):
    pos      = np.where(np.abs(s) <= theta, np.sign(s), 0.0)   # trade the band, skip outliers
    strat    = pos * r
    active   = pos != 0.0
    exposure = active.mean()                                   # fraction of bars in a position
    sharpe_full   = strat.mean()         / strat.std(ddof=1)            # on the WHOLE timeline
    sharpe_active = strat[active].mean() / strat[active].std(ddof=1)    # on ONLY the active bars
    return dict(exposure=exposure, n_trades=int(active.sum()),
                sharpe_full=sharpe_full, sharpe_active=sharpe_active, pnl=strat.sum())

Poiché abbiamo costruito il mercato, possiamo calcolare la verità direttamente — performance media a ogni soglia su tutti i 600 seed, out of sample. Il vero ottimo si colloca a θ1.04\theta \approx 1.04: proprio al bordo della banda di segnale, nel mercato circa il 70% delle volte (derivazione: un segnale Normale-standard cade dentro s1.04|s|\le 1.04 con probabilità P(s1.04)=0.70P(|s|\le 1.04)=0.70), ottenendo uno Sharpe out-of-sample annualizzato di 1.77. Questo è il numero che ogni obiettivo sta cercando di trovare. Tienilo a mente: θ≈1.04, Sharpe OOS 1.77, circa il 70% della timeline nel mercato. Qualsiasi cosa un obiettivo selezioni lontana da questo è l'obiettivo che fallisce, non il mercato che è difficile.

Atto 2 — La trappola: otto trade fortunati, uno Sharpe di 21, un miraggio

Una slot machine che paga su un singolo giro fortunato, con otto biglietti di trade e uno Sharpe per-trade in-sample torreggiante di 21 che collassa a 0.13 out of sample, a drammatizzare un vincitore-lotteria a trade rari selezionato da un obiettivo ingenuo

Ora lascia libero un obiettivo ingenuo su un'estrazione concreta di questo mercato — il seed 6. Piena trasparenza sul seed: non è stata la prima estrazione né una casuale. Abbiamo scansionato i seed alla ricerca di un vincitore per-trade fortemente degenere e abbiamo scelto questo, proprio perché il meccanismo sia impossibile da non notare. Il risultato che mostra è del tutto tipico — come confermerà l'Atto 3, l'obiettivo per-trade sceglie una lotteria con esposizione sotto il 5% nel 56% di tutti i seed — ma la magnitudine del seed 6 si colloca all'estremo di quella distribuzione. Leggilo come un'istanza particolarmente estrema di un fallimento comune, non come una mediana. Ottimizziamo lo Sharpe per-trade: lo Sharpe ratio calcolato solo sui bar in cui la strategia è effettivamente in posizione. È una cosa estremamente naturale da riportare. "Quando tradà, quanto sono buoni i suoi trade?" Sembra isolare l'abilità dall'inattività. Fa l'opposto.

Ecco la strategia che lo Sharpe per-trade incorona sul seed 6:

  • Soglia θ=0.005\theta = 0.005 — tradà solo sui segnali più minuscoli in assoluto.
  • Esposizione al mercato 0.4% — è flat il 99.6% del tempo.
  • Otto trade. Otto. Su 2000 bar.
  • Sharpe per-trade annualizzato in-sample: 21.09.
  • Sharpe sull'intera timeline in-sample: 0.82.
  • Sharpe sull'intera timeline out-of-sample: 0.13.

La metrica per-trade segna 21.09 — un numero che nessuna strategia reale ha mai ottenuto, il tipo di cifra che farebbe lanciare un fondo. Ed è un miraggio completo. Quegli otto trade hanno per caso agganciato un paio di mosse favorevoli; misurato su quei soli otto bar, il rapporto tra media e deviazione standard è astronomico. Ma sull'intera timeline — dove la strategia è flat il 99.6% del tempo — quel "vantaggio" contribuisce sostanzialmente a nulla: uno Sharpe sull'intera timeline di 0.82 in-sample, che collassa a 0.13 su dati freschi. Il vincitore selezionato dall'obiettivo è, a tutti gli effetti pratici di trading, flat.

E non è nemmeno un vantaggio reale a quella soglia. Ricorda il mercato: il vantaggio vive nella banda s1|s|\le 1, e θ=0.005\theta = 0.005 si colloca proprio al centro morto dove il segnale è più debole. La vera curva out-of-sample a θ=0.005\theta = 0.005 è −0.01 — indistinguibile da zero (derivata dalla curva di ground truth). La ricerca non ha trovato un piccolo vantaggio reale. Ha trovato otto estrazioni fortunate di rumore e le ha riportate come uno Sharpe di 21.

Questa è la trappola in miniatura: lo Sharpe per-trade premia la strategia per tradare il più raramente possibile, perché meno bar occupi, più facile è che un paio di essi siano fortunati, e la metrica non chiede mai "ma sei stato davvero nel mercato?" La magnitudine del seed 6 è cherry-picked — siamo andati a cercarne una estrema — ma il suo tipo non lo è. Su tutti i 600 seed lo Sharpe per-trade seleziona un vincitore degenere (uno che tradà a malapena, o perde out of sample) nel 57% dei casi, e una lotteria con esposizione sotto il 5% specificamente nel 56%. La scelta degenere tipica è molto più mite dello Sharpe di 21 del seed 6: mediato su tutti i 600 seed, il vincitore dell'obiettivo per-trade ha uno Sharpe per-trade in-sample di 4.58 ed esposizione media 0.286 — ancora flat per la maggior parte del tempo, solo non flat al 99.6%. Il seed 6 drammatizza il meccanismo; il 56% è la parte che dovrebbe preoccuparti. Più della metà delle volte, questa metrica di uso quotidiano ti consegna un biglietto della lotteria e lo chiama strategia.

Atto 3 — La verità statistica: sei obiettivi, 600 seed

Sei funzioni obiettivo come concorrenti su una classifica, lo Sharpe per-trade che brilla più intensamente in-sample ma timbrato degenere al 57 percento mentre gli obiettivi consapevoli dell'esposizione restano stabili out of sample, a illustrare che un ottimo numero in-sample non significa una buona selezione

Un solo seed non prova nulla; illustra soltanto. Per misurare un obiettivo dobbiamo chiedere cosa seleziona in media, su molti mercati indipendenti, e valutare quella selezione su dati che la ricerca non ha mai visto. Quindi: 600 seed, ciascuno un'estrazione indipendente del mercato; su ognuno, esegui la ricerca a 80 soglie sotto ciascun obiettivo; registra l'esposizione, lo Sharpe in-sample e out-of-sample di qualunque cosa abbia scelto, e se quella scelta fosse degenere.

Obiettivo Esposizione media Sharpe in-sample Sharpe out-of-sample Calo IS→OOS (ass.) Degenere
PnL grezzo 0.859 1.76 1.61 0.15 0.0%
Sharpe sull'intera timeline 0.740 1.82 1.71 0.11 0.0%
Sharpe per-trade 0.286 1.00 0.70 0.30 57%
Floor di esposizione (emin=0.20e_{\min}=0.20) 0.740 1.82 1.71 0.11 0.0%
Shrinkage conf_k (k=40k=40) 0.523 1.54 1.31 0.23 20.7%
Robusto (floor + conf_k) 0.675 1.78 1.70 0.08 0.2%

La colonna "Calo IS→OOS" è la caduta assoluta dello Sharpe annualizzato da in-sample a out-of-sample (es. 1.000.701.00\to0.70 è un calo di 0.30), non una percentuale. E nota che la riga "Floor di esposizione" è identica byte per byte a "Sharpe sull'intera timeline": non è una coincidenza, e l'Atto 5 spiega perché.

Tre fatti saltano all'occhio, e ciascuno è una lezione.

Lo Sharpe per-trade è l'unico obiettivo ingenuo che degenera. La sua esposizione media è 0.286 — seleziona strategie che sono flat per la maggior parte del tempo — e il suo Sharpe in-sample di 1.00 cade di 0.30 fino a un out-of-sample di 0.70, il peggiore del gruppo. Nota il tell: il suo numero in-sample (1.00) non è nemmeno impressionante, eppure su qualsiasi seed singolo riporterà volentieri una cifra per-trade di 21. La media si annulla perché le finestre fortunate puntano in direzioni casuali; ciò che sopravvive fino a out-of-sample è solo 0.70, e il 57% delle selezioni individuali è puramente spazzatura.

Gli obiettivi consapevoli dell'esposizione sono naturalmente sicuri. Il PnL grezzo e lo Sharpe sull'intera timeline non degenerano mai (0.0%). La ragione è strutturale: entrambi sono misurati sull'intera timeline, quindi una strategia che è flat il 99.6% del tempo guadagna quasi nulla sotto di essi. Non puoi ingannare una metrica sull'intera timeline tradando raramente — restare flat viene penalizzato direttamente e automaticamente, perché i bar flat sono nel denominatore. Questa è l'idea singola più importante dell'intero articolo, e vi torniamo nell'Atto 6.

Il PnL grezzo è sicuro ma non ottimale — sovra-espone. Guarda da vicino: l'esposizione media del PnL grezzo è 0.859, la più alta di tutte, e il suo Sharpe out-of-sample (1.61) è di poco sotto lo Sharpe sull'intera timeline (1.71) e il vero ottimo (1.77). Il PnL premia l'essere nel mercato, quindi la ricerca spinge θ\theta troppo in alto (sul seed 6, il PnL grezzo sceglie θ=1.84\theta=1.84 contro l'ottimo di 1.04), trascinando dentro bar fuori-banda che non portano vantaggio e aggiungono solo rumore. Non esplode — ma deriva oltre il vero ottimo nella direzione opposta rispetto alla trappola per-trade. Obiettivo diverso, bias diverso, stessa lezione: la metrica ha scelto la strategia.

Le due righe di cui non abbiamo ancora parlato — il floor di esposizione e conf_k — sono la riparazione. Questo è il prossimo atto.

Atto 4 — Perché otto trade non possono mai essere affidabili

Una singola stima puntuale dello Sharpe segnata con un'enorme barra d'errore da intervallo di confidenza perché poggia su sole otto osservazioni, accanto a un righello etichettato minimum track record length, a illustrare che un rapporto misurato su una manciata di trade è statisticamente privo di significato

Prima di riparare la trappola, vale la pena essere precisi sul perché otto trade producono uno Sharpe di 21 che non significa nulla — perché la correzione discende direttamente dalla ragione.

Uno Sharpe ratio è una stima, e le stime hanno barre d'errore. Il risultato di Andrew Lo del 2002 dà l'errore standard di uno Sharpe ratio stimato da TT osservazioni, sotto l'assunzione più generosa possibile (rendimenti Normali IID):

SE(SR^)1+SR^2/2T.\operatorname{SE}\big(\widehat{SR}\big) \approx \sqrt{\frac{1 + \widehat{SR}^{\,2}/2}{T}}.

L'errore si restringe solo come 1/T1/\sqrt{T}. Dagli in pasto la trappola. Lo Sharpe per-trade sul seed 6 è 21.0921.09 annualizzato, che è 1.331.33 per osservazione, calcolato su T=8T = 8 bar. L'errore standard è

SE1+1.332/280.49 per observation = 7.7 annualized\operatorname{SE} \approx \sqrt{\frac{1 + 1.33^2/2}{8}} \approx 0.49 \ \text{per observation} \ = \ \textbf{7.7 annualized}

(derivato dalla formula di Lo). La stima puntuale è 21.0921.09; la sua barra d'errore a un sigma è dell'ordine di ±7.7\pm 7.7 — leggilo come un ordine di grandezza illustrativo, non un intervallo di confidenza calibrato, dato che la formula assume rendimenti Normali IID che il nostro rumore a code grasse t4t_4 viola. Anche così, il messaggio è inequivocabile: il "Sharpe di 21" è un numero estratto da una distribuzione così larga da portare sostanzialmente nessuna informazione — ed è il calcolo caritatevole, perché l'estensione di Mertens mostra che code grasse e skew gonfiano ulteriormente l'errore standard. Lo Sharpe di un backtest a trade rari è meno affidabile del suo valore puntuale in ogni direzione contemporaneamente: troppo poche osservazioni, e la distribuzione sbagliata.

Questo è esattamente ciò che il Minimum Track Record Length formalizza (Bailey & López de Prado, 2012). Inverte la domanda — quante osservazioni mi servono prima di potermi fidare di uno Sharpe di questa grandezza con confidenza pp?

MinTRL=1+[1γ^3SR^+γ^414SR^2](Z1pSR^SR)2,\text{MinTRL} = 1 + \Big[\,1 - \hat\gamma_3\,\widehat{SR} + \tfrac{\hat\gamma_4 - 1}{4}\,\widehat{SR}^{\,2}\,\Big]\left(\frac{Z_{1-p}}{\widehat{SR} - SR^*}\right)^{2},

trasformando "fidati meno dei backtest a pochi trade" in un numero di trade esplicito e verificabile. Il punto profondo per il design della funzione obiettivo è questo: un buon obiettivo dovrebbe imporre un track record minimo dall'interno, invece di lasciare che sia un essere umano a notare, a posteriori, che il vincitore poggia su otto osservazioni. Lo Sharpe per-trade fa l'opposto — viene massimizzato spingendo il conteggio delle osservazioni verso il minimo. Qualsiasi obiettivo il cui ottimo si colloca a "il minor numero di trade possibile" è, per costruzione, un obiettivo che va in cerca della propria stima meno affidabile.

Due fallimenti si combinano nella trappola, e nominarli entrambi ci dice come correggerla. Primo, il rumore da piccolo campione: otto osservazioni non possono determinare alcun rapporto con precisione. Secondo, la selezione: quegli otto bar non ci sono stati consegnati — la ricerca ha scelto la soglia che è atterrata su di essi, in parte perché erano fortunati. La ricerca è un massimizzatore; troverà sempre l'angolo dello spazio in cui il rumore per caso somiglia al segnale. Non puoi essere più furbo di questo con una stima puntuale migliore. Devi cambiare cosa significa "migliore" in modo che l'angolo fortunato non sia il massimo.

Atto 5 — La riparazione: un floor di esposizione e uno shrinkage sul conteggio dei trade

Un pannello di controllo con due manopole etichettate exposure floor e conf_k shrinkage, entrambe che sollevano una superficie di performance out-of-sample fino a un plateau alto e piatto mentre un indicatore di degenerazione si spegne, a illustrare due correzioni indipendenti che insieme recuperano il vero ottimo

Abbiamo due malattie nominate — tradà troppo raramente e poggia su troppe poche osservazioni — quindi scriviamo due cure, ciascuna mirata a una di esse.

Cura 1: un floor di esposizione. La correzione più semplice possibile. Rigetta senza appello qualsiasi strategia che non sia nel mercato almeno emine_{\min} del tempo — se tradi a malapena, il tuo punteggio è -\infty e la ricerca non può selezionarti. Ma c'è una sottigliezza onesta in cosa metti sotto floor, ed è la lezione silenziosa di tutto questo articolo. Come obiettivo standalone abbiamo messo un floor sullo Sharpe sull'intera timeline, e su questo mercato non cambia assolutamente nulla: il vincitore dello Sharpe sull'intera timeline si colloca già a ~74% di esposizione, quindi un floor al 20% non vincola mai. Questo è esattamente il motivo per cui le righe "floor di esposizione" e "Sharpe sull'intera timeline" nelle tabelle sopra sono identiche byte per byte — imbullonare un floor su una metrica già sicura equivale semplicemente a ri-derivare lo Sharpe pieno. Il floor fa un lavoro visibile solo quando sta proteggendo una metrica che altrimenti scatterebbe verso l'angolo: una metrica per-trade, come nell'obiettivo robusto qui sotto. In altre parole, "richiedi esposizione" e "misura sull'intera timeline" sono, su questi dati, due nomi per lo stesso intervento.

Cura 2: uno shrinkage sul conteggio dei trade — "conf_k". Per quando sei bloccato con una metrica per-trade e vuoi una correzione morbida invece di un taglio netto: scala lo Sharpe in modo continuo in base a su quanti trade poggia. Moltiplica per n/(n+k)n/(n+k), dove nn è il conteggio dei trade e kk è una "costante di confidenza" fissa — una forza prior equivalente-in-trade scelta prima della ricerca:

score(θ)=SR^(θ)n(θ)n(θ)+k.\text{score}(\theta) = \widehat{SR}(\theta)\cdot \frac{n(\theta)}{n(\theta) + k}.

Quando n0n \to 0 il punteggio viene schiacciato a zero indipendentemente da quanto grande sia lo Sharpe grezzo; quando nn \to \infty il punteggio converge allo Sharpe grezzo. Questa è la stessa logica correttiva del MinTRL e dell'errore standard dell'Atto 4 — restringere una stima da piccolo campione verso zero come funzione decrescente della sua dimensione campionaria — ripiegata direttamente dentro l'obiettivo invece che applicata come filtro post-hoc. Il precedente nominato più vicino è il System Quality Number di van Tharp (SQN=Ntrade/σtrade\text{SQN} = \sqrt{N}\cdot \overline{\text{trade}}/\sigma_{\text{trade}}), che allo stesso modo fa scalare una metrica di qualità per-trade con il conteggio dei trade NN — sebbene la forma funzionale differisca (N\sqrt{N} cresce senza limite, mentre n/(n+k)n/(n+k) satura a 1). Nella forma il nostro è uno shrinkage in stile Bayesiano a pesi di precisione / empirical-Bayes; è una nostra costruzione per questo problema, non uno stimatore nominato preso dalla letteratura.

def obj_active_sharpe(m):                  # the trap: Sharpe on only the active bars
    return m["sharpe_active"]

def _shrink(n, conf_k):                     # trade-count shrinkage n / (n + k)
    return n / (n + conf_k) if (n + conf_k) > 0 else 0.0

def obj_confk(m, conf_k=40.0):              # few trades -> little credit
    return m["sharpe_active"] * _shrink(m["n_trades"], conf_k)

def obj_robust(m, e_min=0.20, conf_k=40.0): # both cures at once
    if m["exposure"] < e_min:               # floor: reject strategies that barely trade
        return -np.inf
    return m["sharpe_active"] * _shrink(m["n_trades"], conf_k)

Ora la parte onesta: quanto floor, quanto shrinkage? Fai uno sweep su entrambi e leggi l'intera superficie. Ogni cella è lo Sharpe medio out-of-sample su 200 seed (un sottoinsieme di un terzo dei 600, per mantenere economico lo sweep bidimensionale) con il tasso di degenerazione a fianco:

emine_{\min} \ conf_k k=0k=0 k=40k=40 k=80k=80
0.00 0.66 (59.5%) 1.26 (22.5%) 1.47 (11.5%)
0.05 1.43 (10.0%) 1.53 (6.0%) 1.60 (4.0%)
0.10 1.64 (1.5%) 1.65 (1.0%) 1.67 (1.0%)
0.20 1.71 (0.0%) 1.71 (0.0%) 1.71 (0.0%)
0.35 1.73 (0.0%) 1.73 (0.0%) 1.73 (0.0%)

Sharpe medio annualizzato out-of-sample, con il tasso di degenerazione tra parentesi. La cella in alto a sinistra (0,0)(0,0) è lo Sharpe per-trade grezzo — nessun floor, nessuno shrinkage: OOS 0.66, degenere 59.5%. È lo stesso obiettivo della riga per-trade dell'Atto 3, che segnava 0.70 / 57%; il piccolo divario è puramente il set di seed — questo sweep usa 200 seed, il Monte Carlo ne ha usati tutti e 600. Stessa metrica, campione più piccolo.

La superficie racconta una storia pulita in tre letture.

Ciascuna cura funziona da sola. Muoviti verso destra lungo la riga superiore (aggiungi shrinkage, nessun floor): l'OOS sale 0.661.261.470.66 \to 1.26 \to 1.47 e la degenerazione cala 59.5%22.5%11.5%59.5\% \to 22.5\% \to 11.5\%. Muoviti verso il basso lungo la colonna sinistra (aggiungi floor, nessuno shrinkage): l'OOS sale 0.661.431.641.710.66 \to 1.43 \to 1.64 \to 1.71 e la degenerazione cala 59.5%10%1.5%0%59.5\% \to 10\% \to 1.5\% \to 0\%. Ciascuna manopola, girata da sola, solleva indipendentemente la performance out-of-sample e uccide la degenerazione. Il floor di esposizione è la leva singola più forte qui, perché attacca frontalmente la caratteristica distintiva della trappola — l'esposizione vicina allo zero.

Insieme raggiungono il plateau — e il plateau è semplicemente lo Sharpe sull'intera timeline. A emin=0.20e_{\min} = 0.20 la riga è piatta a OOS 1.71 con 0% di degenerazione a ogni livello di shrinkage; spingi a emin=0.35e_{\min}=0.35 e sale leggermente a 1.73. Ma guarda bene cos'è quel 1.71: è esattamente il punteggio che il semplice Sharpe sull'intera timeline ottiene nell'Atto 3 senza alcun floor e senza alcuno shrinkage. Nel migliore dei casi, i rimedi retroattivi non battono lo Sharpe sull'intera timeline — lo ricostruiscono. E l'obiettivo robusto completamente riparato non arriva nemmeno del tutto lì: su tutti i 600 seed atterra a OOS 1.70 con una degenerazione residua dello 0.17%, di un pelo sotto l'1.71 / 0% dello Sharpe pieno — è debolmente dominato dalla metrica più semplice. Un'impostazione intermedia modesta, emin=0.10e_{\min}=0.10 con k=40k=40, raggiunge OOS 1.65 con 1% di degenerazione — utile se una metrica per-trade ti è imposta, ma mai una ragione per preferirne una.

I numeri esatti dipendono dalla scala — la forma è il risultato. I valori specifici emin=0.20e_{\min}=0.20, k=40k=40 che riparano completamente questo mercato sono calibrati su questo processo generatore di dati; su un mercato diverso con frequenze di trade e spessore delle code diversi, il plateau si colloca altrove. Ciò che si generalizza non sono le coordinate ma la superficie: un sollevamento monotono in entrambe le direzioni, la degenerazione spinta a zero, un plateau sulla verità. Trovi le tue coordinate facendo uno sweep, esattamente come sopra.

Metti insieme entrambe le cure — l'obiettivo robusto, floor 0.20 più conf_k 40 — e torna al seed 6. La trappola aveva incoronato θ=0.005\theta = 0.005, otto trade, uno Sharpe OOS sull'intera timeline di 0.13. L'obiettivo robusto seleziona invece θ=0.979\theta = 0.979: esposizione al mercato 0.66, 447 trade, Sharpe out-of-sample annualizzato 1.77. Quel θ=0.979\theta = 0.979 è un punto di griglia sotto il vero ottimo θ=1.04\theta = 1.04, quindi recupera una soglia quasi-ottimale e ben esposta piuttosto che centrare il bersaglio — il suo Sharpe out-of-sample a singolo seed (1.77) coincide per caso con l'ottimo di popolazione. Stessi dati, stessa ricerca, stesse 80 soglie candidate. È cambiata solo la definizione di "migliore", e ha spostato il vincitore da un miraggio flat a otto trade al vero vantaggio ben esposto — che è, significativamente, esattamente la stessa soglia che il semplice Sharpe sull'intera timeline sceglie su questo seed.

Un avvertimento che lo sweep rende esplicito: conf_k da solo non basta su questo mercato. A k=40k=40 senza floor, la degenerazione è ancora al 22.5% sui seed — e sul seed 6 specificamente, conf_k da solo sceglie θ=0.015\theta = 0.015, 35 trade, uno Sharpe out-of-sample di −0.06. Trentacinque trade sopravvivono a uno shrinkage di 35/(35+40)0.4735/(35+40) \approx 0.47 con punteggio sufficiente rimasto per vincere. Il floor di esposizione è ciò che chiude quell'ultimo divario, perché prende di mira direttamente la vera firma della trappola — l'essere flat — invece di fidarsi del conteggio dei trade come proxy per essa.

Atto 6 — La lezione più profonda: misura sull'intera timeline

Due modi di valutare la stessa strategia messi a confronto: un faretto stretto che illumina solo i pochi bar in cui la strategia ha tradato contro un riflettore che misura l'intera timeline inclusi i tratti flat, a illustrare che gli obiettivi consapevoli dell'esposizione non possono essere ingannati da trade rari e fortunati

Fai un passo indietro dalla riparazione e nota cosa ha effettivamente separato gli obiettivi sicuri dalla trappola. Non è stata la sofisticazione. Il PnL grezzo e lo Sharpe sull'intera timeline sono più semplici dello Sharpe per-trade, e non sono mai degenerati — 0% su 600 seed — senza alcun floor, senza alcuno shrinkage, senza alcun tuning.

La linea di demarcazione è una singola proprietà: quale finestra misura la metrica? Lo Sharpe per-trade misura solo i bar su cui la strategia ha scelto di stare — una finestra auto-selezionata che la ricerca può restringere a piacimento. Lo Sharpe sull'intera timeline e il PnL totale misurano l'intera timeline, bar flat inclusi. E non puoi rendere grande una metrica sull'intera timeline tradando raramente, perché ogni ora in cui resti flat è un'ora nel denominatore che non guadagna nulla. Il floor di esposizione e conf_k sono, alla fine, solo modi di correggere retroattivamente la metrica per-trade con la consapevolezza dell'esposizione che le metriche sull'intera timeline hanno gratuitamente — e lo sweep ci ha già detto il tetto di quella correzione retroattiva: nel migliore dei casi eguaglia lo Sharpe sull'intera timeline (OOS 1.70 contro 1.71), senza mai batterlo. Se sei libero di scegliere la finestra, scegli l'intera timeline e salta del tutto la correzione retroattiva.

Quindi il principio di design, detto chiaramente:

Progetta l'obiettivo in modo che non possa essere ingannato da trade rari e fortunati. Hai tre strumenti, in ordine approssimativo di preferenza:

  1. Misura sull'intera timeline. Il default da cui non ci si dovrebbe quasi mai allontanare. Lo Sharpe sull'intera timeline e il rendimento totale sono consapevoli dell'esposizione per costruzione — l'inattività viene penalizzata automaticamente perché i bar flat contano. Se ti ritrovi a riportare una metrica calcolata "solo sui bar in cui eravamo attivi", fermati e chiediti cosa farà la ricerca con la libertà di scegliere quei bar.
  2. Richiedi esposizione. Se devi usare una metrica condizionata all'attività, metti un floor sull'esposizione in modo che la ricerca non possa selezionare una strategia che tradà a malapena. Questa è la leva singola più forte contro questa specifica trappola.
  3. Restringi in base al conteggio dei trade. Scala qualsiasi rapporto per n/(n+k)n/(n+k) in modo che uno Sharpe che poggia su una manciata di osservazioni guadagni una frazione del credito di uno che poggia su migliaia. Questa è l'imposizione a livello di obiettivo del Minimum Track Record Length: un numero da poche osservazioni non è affidabile (Atto 4), quindi un obiettivo onesto sconta in anticipo quella inaffidabilità invece di fidarsi che un essere umano se ne accorga dopo.

Nulla di tutto questo rende la ricerca più intelligente. Rende onesto il bersaglio, così che quando la ricerca fa esattamente ciò che fa sempre — trovare il massimo — il massimo sia una strategia che vuoi davvero.

Note di onestà

Tre avvertenze, dette chiaramente, perché uno studio controllato guadagna le proprie conclusioni solo nominando i propri limiti.

  • Il mercato è sintetico, e deliberatamente così. Un segnale Normale-standard, un vantaggio lineare confinato a s1|s|\le 1, rumore Student-tt(44) a code grasse — scelti per la ground truth controllata, non per il realismo di mercato. Possiamo provare che un obiettivo sceglie la strategia sbagliata solo eseguendolo su dati dove sappiamo quale strategia è quella giusta. I mercati reali sono non stazionari, autocorrelati, e cambiano regime. Le code grasse sono un ingrediente realistico che abbiamo mantenuto, ma — contrariamente a un'ipotesi naturale iniziale, e contrariamente a una bozza precedente di questo stesso articolo — non sono ciò che alimenta la trappola: un controllo a rumore Gaussiano (300 seed) degenera il 55.7% delle volte contro il 57.0% qui, con Sharpe out-of-sample 0.71 contro 0.70. La trappola è un artefatto piccolo-campione-più-selezione che sopravvive con o senza code pesanti. Il risultato consegnato è la diagnosi e il pattern di riparazione, non una strategia e non una costante universale.
  • I valori di riparazione dipendono dalla scala. Il floor specifico emin=0.20e_{\min}=0.20 e lo shrinkage k=40k=40 che chiudono completamente la trappola sono calibrati su questo processo generatore di dati — le sue frequenze di trade, lo spessore delle sue code, la dimensione del suo vantaggio. Su altri dati il plateau si sposta. Ciò che si trasferisce è la forma della superficie dello sweep (sollevamento monotono su entrambe le manopole, degenerazione a zero, un plateau sulla verità) e il metodo per trovare le proprie coordinate: fai lo sweep su entrambe e leggi la superficie, non copiare i numeri.
  • conf_k è una nostra costruzione, non uno stimatore nominato. Lo shrinkage sul conteggio dei trade SR^n/(n+k)\widehat{SR}\cdot n/(n+k) è un dispositivo in stile Bayesiano a pesi di precisione / empirical-Bayes che abbiamo costruito per questo problema; la sua logica è fondata sul risultato verificato dell'errore standard di Lo/Mertens e sul MinTRL di Bailey–López de Prado, e il suo parente nominato più vicino è il System Quality Number di van Tharp (Ntrade/σtrade\sqrt{N}\cdot \overline{\text{trade}}/\sigma_{\text{trade}}, una forma funzionale diversa), ma non affermiamo che n/(n+k)n/(n+k) stesso compaia sotto un nome nella letteratura. Le sue cure gemelle — il floor di esposizione, la misurazione sull'intera timeline — sono pratica standard enunciata con precisione. E nota quali obiettivi erano già sicuri qui: il PnL grezzo e lo Sharpe sull'intera timeline non hanno mai avuto bisogno di riparazione, perché sono consapevoli dell'esposizione fin dall'inizio — a tal punto che mettere un floor sullo Sharpe sull'intera timeline si riduce allo Sharpe sull'intera timeline, il cui vincitore supera già qualsiasi floor ragionevole. La trappola è specificamente lo Sharpe per-trade / active — e anche l'obiettivo per-trade completamente riparato si limita a eguagliare lo Sharpe sull'intera timeline (OOS 1.70 contro 1.71), senza mai batterlo. La lezione primaria non è la riparazione; è misurare sull'intera timeline fin dall'inizio.

Punti Chiave

  1. L'obiettivo è la decisione, non una formalità. Una ricerca non trova "una buona strategia" — trova il massimizzatore di qualunque scalare le hai consegnato, e scalari diversi selezionano strategie radicalmente diverse sugli stessi dati identici. Scegliere l'obiettivo è scegliere la strategia; tutto ciò che viene dopo è contabilità. Questa è la legge di Goodhart: nel momento in cui la tua metrica diventa il bersaglio della ricerca, la ricerca sfrutterà ogni divario tra essa e ciò che intendevi.
  2. Lo Sharpe per-trade è una trappola. Misurato solo sui bar in cui una strategia tradà, viene massimizzato tradando il più raramente possibile — meno osservazioni, più facile che un paio di mosse fortunate gonfino il rapporto (un controllo Gaussiano conferma che le code grasse non sono necessarie; è un effetto piccolo-campione-più-selezione). Su 600 seed sceglie una lotteria con esposizione sotto il 5% nel 56% dei casi e degenera nel 57%; la scelta degenere tipica ha in media uno Sharpe per-trade in-sample di 4.58. Su un seed deliberatamente estremo ha incoronato una strategia a otto trade e 0.4% di esposizione con uno Sharpe per-trade in-sample di 21.09 che collassa a uno Sharpe out-of-sample sull'intera timeline di 0.13. Un rapporto costruito su otto osservazioni ha un errore standard dell'ordine di ±7.7 annualizzato (Atto 4) — non è mai stata informazione.
  3. Gli obiettivi consapevoli dell'esposizione sono naturalmente sicuri. Il PnL grezzo e lo Sharpe sull'intera timeline non sono mai degenerati (0%), perché misurano l'intera timeline e l'inattività viene penalizzata automaticamente. Non puoi ingannare una metrica sull'intera timeline tradando raramente. L'unico difetto del PnL grezzo è il bias opposto — sovra-espone (esposizione media 0.859, OOS 1.61 contro il vero 1.77), facendo derivare θ\theta oltre l'ottimo per stare di più nel mercato.
  4. Le riparazioni funzionano — ma ti riportano solo allo Sharpe sull'intera timeline. Un floor di esposizione e uno shrinkage sul conteggio dei trade (conf_k) sollevano ciascuno indipendentemente lo Sharpe out-of-sample e spingono la degenerazione verso zero; insieme raggiungono un plateau. Ma quel plateau è lo Sharpe sull'intera timeline: la degenerazione cala dal 59.5% a (emin,k)=(0,0)(e_{\min},k)=(0,0) allo 0% a emin=0.20e_{\min}=0.20 e lo Sharpe OOS sale da 0.66 a 1.71 — esattamente il numero che il semplice Sharpe pieno ottiene senza aiuto, e l'obiettivo robusto completamente riparato in realtà atterra di un pelo sotto (OOS 1.70, 0.17% di degenerazione: debolmente dominato). Sul seed 6 l'obiettivo robusto recupera una soglia quasi-ottimale e ben esposta (θ=0.979\theta = 0.979, un punto di griglia sotto il vero 1.041.04; 447 trade; Sharpe OOS 1.77). Tratta conf_k come un fallback per quando una metrica per-trade ti è imposta, non come un miglioramento rispetto a misurare l'intera timeline. Le coordinate esatte dipendono dalla scala; la forma della superficie è il risultato trasferibile.
  5. Progetta l'obiettivo in modo che non possa essere ingannato da trade rari e fortunati. In ordine di preferenza: misura sull'intera timeline (default), richiedi esposizione (leva singola più forte), restringi in base al conteggio dei trade (Minimum Track Record Length a livello di obiettivo). Nessuna di queste rende la ricerca più furba — rendono onesto il bersaglio, così che il massimo che la ricerca inevitabilmente trova sia una strategia che davvero tradersti.

Una ricerca di parametri è un genio obbediente. Concede esattamente il desiderio che formuli, non quello che intendevi — e "massimizza questa metrica" è il desiderio. Formulalo come uno Sharpe per-trade e evocherà otto trade fortunati chiamandoli una fortuna. Formulalo in modo che restare flat sia punito e che una manciata di trade guadagni solo una manciata di credito, e lo stesso genio, sugli stessi dati, ti consegna il vero vantaggio. La strategia che dispieghi è stata scelta nel momento in cui hai digitato l'obiettivo. Sceglila di proposito.

L'esperimento completo — il mercato sintetico, i sei obiettivi, il Monte Carlo a 600 seed, e la superficie dello sweep di riparazione, ogni numero rigenerabile da un unico script deterministico — è nel paper compagno su objective-design.marketmaker.cc, con codice e dati su github.com/suenot/objective-design-degeneracy.

Questo è un fronte della stessa guerra che i nostri altri studi combattono da angolazioni diverse. Il Deflated Sharpe Ratio prezza il vincitore di una ricerca dopo i test multipli — dove questo articolo chiede se l'obiettivo abbia scelto la strategia giusta in primo luogo, il DSR chiede se la strategia scelta batta ciò che la sola fortuna produrrebbe. Il prossimo studio sulla probabilità di overfitting del backtest attacca lo stesso bias di selezione dal lato del resampling, valutando la procedura piuttosto che il vincitore. E la tassonomia del look-ahead bias cataloga l'altro grande fabbricante di falsi Sharpe — un leak dal futuro — che produce il sintomo identico (un backtest glorioso che muore live) attraverso un meccanismo completamente diverso. Design dell'obiettivo, deflazione, probabilità di overfitting, look-ahead: quattro nomi per un'unica disciplina — non farsi ingannare dal proprio backtest.

Disclaimer: le informazioni fornite in questo articolo hanno solo scopo didattico e informativo e non costituiscono consulenza finanziaria, di investimento o di trading. Il trading di criptovalute comporta un rischio significativo di perdita.

Autori

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Resta un Passo Avanti al Mercato

Iscriviti alla nostra newsletter per approfondimenti esclusivi sul trading con IA, analisi di mercato e aggiornamenti sulla piattaforma.

Rispettiamo la tua privacy. Annulla l'iscrizione in qualsiasi momento.