Sharpe Ratio per la Misura delle Prestazioni del Trading Algoritmico

Quando si esegue una strategia di trading algoritmico, si pensa che il rendimento annualizzato (annualised return) è la metrica delle prestazioni più utile. Tuttavia, ci sono molti criticità nell’usare solo questo parametro, infatti il calcolo dei profotti per alcune tipologie di  strategie non è semplice e del tutto corretto. Questo è particolarmente vero per le strategie non direzionali come le strategie market-neutral o strategie che sfruttano pesantemente la leva finanziaria. Questi fattori rendono difficile confrontare due strategie considerando esclusivamente i loro rendimenti.

Inoltre, se confrontiamo due strategie che hanno identici payoff, come possiamo individuare quale strategia ha un maggior rischio? In particolare, cosa si intende per “maggior rischio”? Nel settore finanziario, siamo spesso preoccupati della volatilità dei rendimenti e dei periodi di drawdown. Pertanto, se una di queste strategie presenta una maggiore volatilità dei rendimenti, probabilmente la troveremmo meno attraente, anche nel caso di simili (se non identici) rendimenti storici.

Questi aspetti del confronto tra strategie e della valutazione del rischio motivano l’uso del Sharpe Ratio.

Definizione dello Sharpe Ratio

William Forsyth Sharpe è un economista assegnatario di un premio Nobel, ha contribuito a creare il Capital Asset Pricing Model (CAPM) e ha sviluppato il Sharpe Ratio nel 1966 (successivamente aggiornato nel 1994).

Il Sharpe Ratio S è definito come:

\(S = \frac{E(R_a – R_b )}{ \sqrt{Var(R_a – R_b)}}\)

Dove \(R_a\) è il rendimento di di un asset o di una strategia e \(R_b\) è il rendimento di un indice di riferimento a bassissimo rischio.

Il rapporto confronta la media dei excess return, cioè la differenza dei rendimenti dell’attività o della strategia con il benchmark di riferimento, con la deviazione standard di tali rendimenti. Quindi una minore volatilità dei rendimenti porterà ad un maggiore Sharpe Ratio, assumendo identici rendimenti.

Il “Sharpe Ratio” utilizzato maggiormente da coloro che attuano strategie di trading è la Sharpe Annualizzata, il cui calcolo dipende dal periodo di trading per cui vengono misurati i payoff. Supponendo che ci siano N periodi di trading in un anno, la Sharpe annualizzata è calcolata come segue:

\(S =  \sqrt{N}\frac{E(R_a – R_b )}{ \sqrt{Var(R_a – R_b)}}\)

Da notare che lo stesso Sharpe Ratio DEVE essere calcolato in base allo Sharpe ad una  particolare tipologia di periodo temporale. Per una strategia basata sul periodo di trading giornaliero, si considera N = 252 (poiché ci sono 252 giorni di contrattazione in un anno, e non 365) e \(R_a\), \(R_b\) devono essere i profitti giornalieri. Allo stesso modo, in caso di dati orari si N = 252 × 6.5 = 1638, e non N = 252 × 24 = 6048 dato che ci sono solo 6,5 ore di contrattazioni in un giorno.

Scegliere il Benchmark

La formula per Sharpe Ratio prevede l’uso di un benchmark. Un indice di riferimento è usato come “metro di giudizio” o “soglia limite” che una particolare strategia deve superare affinchè valga la pena considerarla. Ad esempio, una semplice strategia long-only basata su titoli azionari statunitensi a grande capitalizzazione dovrebbe mediamente “battere” l’indice S&P500, o almeno pareggiarlo in caso di minore volatilità.

La scelta del parametro di riferimento a volte può non essere semplice. Ad esempio, può l’Exhange Traded Fund (ETF) di un settore essere utilizzato come benchmark di performance per i singoli titoli azionari o per lo stesso S&P500? Perché non usare il Russell3000? Allo stesso modo la strategia di un hedge fund dovrebbe essere confrontata con un indice di mercato o con l’indice di altri hedge fund?

Inoltre c’è anche il vincolo sul “risk free rate”, cioè tasso di rendimento generato da titoli senza rischio. Dovrebbero essere utilizzati i titoli di stato nazionali? Un paniere di obbligazioni internazionali? Contratti a breve o lungo termine? o un mix? Chiaramente ci sono molti modi per scegliere un benchmark di riferimento! Il Sharpe Ratio usa generalmente il free risk rate e spesso, per le strategie sull’azionario, si basa sui treasury governativi a dieci anni.

In un caso particolare, per le strategie market-neutral rispetto al mercato, vi è una criticità relativa all’utilizzo del risk-free rate come parametro di riferimento. Lo stesso indice di mercato non dovrebbe essere utilizzato in quanto la strategia è, per definizione, neutrale rispetto al mercato. La scelta corretta per una strategia di questo tipo  non può quindi considerare il free risk rate perché questo è “autofinanziato”. Dato che si ottiene un profitto da interessi, Rf, dal possesso di un margine, il calcolo effettivo dei rendimenti corrisponde a:\((R_a + R_f) – R_f = R_a\). Quindi per le strategie neutrali non si considera realmente il free risk rate.

Limitazioni

Nonostante l’ampio utilizzo del Sharpe Ratio all’interno della finanza quantitativa, sono presentia alcune limitazioni.

Innanzitutto, il Sharpe Ratio è retrospettivo. Rappresenta solo la distribuzione dei rendimenti storici e la volatilità, non quelli che si verificano in futuro. Quando si effettuano valutazioni basate sullo Sharpe Ratio, si presume implicitamente che il passato sarà simile al futuro. Evidentemente questo non è sempre corretto, in particolare nel caso di variazioni delle condizioni del mercato.

Il calcolo dello Sharpe Ratio presuppone che i rendimenti utilizzati siano normalmente distribuiti (cioè gaussiani). Sfortunatamente, i mercati spesso soffrono di una  curtosi superiore alla distribuzione gaussiana. Essenzialmente la distribuzione dei rendimenti ha “code più grasse” (fat tail) e quindi è più probabile che si verifichino eventi estremi di quanto una distribuzione gaussiana ci potrebbe far credere. Quindi, il Sharpe Ratio è carente nel caratterizzare il “tail risk”.

Questo può essere visto chiaramente in strategie che sono molto inclini a tali rischi. Ad esempio, la vendita di opzioni call (dette anche “penny under a steam roller”). Un flusso costante di premi di opzione sono generati dalla vendita di opzioni call nel corso del tempo, portando a una bassa volatilità dei rendimenti, con un forte eccesso rispetto a un benchmark. In questo caso la strategia avrebbe un elevato Sharpe Ratio (basato su dati storici). Tuttavia, non tiene conto del fatto che tali opzioni possono essere called, portando a significative ed improvvise drawdown (o addirittura al wipeout) nella curva di equity. Quindi, come con qualsiasi misura delle performance di una strategia di trading algoritmico, non si può utilizzare solamente il Sharpe Ratio.

Sebbene questo punto possa sembrare ovvio per alcuni, i costi di transazione DEVONO essere inclusi nel calcolo del Sharpe Ratio, affinchè sia ​​realistico. Ci sono innumerevoli esempi di strategie di trading che hanno elevati Sharpes (e quindi una probabilità di grande redditività) che poi diventano strategie con Sharpe ridotto e bassa redditività, una volta che sono stati calcolati i costi e le commissioni. Quindi è assolutamente necessario considerare i rendimenti netti quando si calcola la differenza con il benchmark. Pertanto, i costi di transazione devono essere considerati a monte del calcolo del coefficiente di Sharpe.

Uso Pratico ed Esempi

Una domanda rimasta finora senza risposta all’interno di questo articolo è “Qual è un buon Sharpe Ratioper una strategia?”. Pragmaticamente, dovresti ignorare qualsiasi strategia che possieda uno Sharpe annualizzato S < 1 dopo aver incluso i costi di transazione. I fondi speculativi quantitativi tendono a ignorare tutte le strategie che possiedono Sharpe S < 2. Un importante hedge fund quantitativo che conosco non prenderebbe in considerazione nemmeno le strategie che hanno rapporti di Sharpe S <3. Come trader algoritmico retail, se riesci a ottenere un Sharpe Ratio S> 2, è già un ottimo risultato. Generalmente il Sharpe Ratio aumenta con l’aumentare della frequenza di trading. Alcune strategie ad alta frequenza hanno a volte  Sharpe Ratio a doppia cifra, in quanto possono essere redditizi quasi ogni giorno e certamente ogni mese. Queste strategie raramente soffrono di rischi catastrofici e quindi riducono al minimo la volatilità dei loro rendimenti, questo causa percentuali di Sharpe così elevate.

Esempi di Sharpe Ratio

Finora questo articolo è stato abbastanza teorico, quindi è giunto il momento di “sporcarci” le mani con  alcuni esempi reali. Si considera inizialmente una semplice strategia di buy-and-hold long-only di un singolo titolo azionario, e successivamente si considera una strategia market-neutral. Entrambi questi esempi sono stati implementati utilizzanzo la libreria di analisi dei dati Pandas, di Python.

Il primo compito è quello di acquisire effettivamente i dati e inserirli in un oggetto DataFrame di Pandas. Nell’articolo sull’implementazione dei Securities Master in Python e MySQL abbiamo sviluppato un sistema per raggiungere questo obiettivo. In alternativa, possiamo utilizzare un  codice più semplice per acquisire direttamente i dati da Yahoo Finance e inserirli direttamente in un DataFrame. Nella parte inferiore di questo script ho creato una funzione per calcolare il rapporto Sharpe annualizzato in base a un flusso di rendimenti:

            import datetime
import numpy as np
import pandas as pd
from pandas_datareader import data as pdr


def get_historic_data(ticker,
                      start_date=(2000, 1, 1),
                      end_date=datetime.date.today().timetuple()[0:3]):
    """
    Ottenere i dati da Yahoo Finance e li aggiunge a un oggetto DataFrame di Pandas.

    ticker: simbolo del ticker di Yahoo Finanza, ad es. "GOOG" per Google, Inc.
    start_date: data di inizio nel formato (AAAA, M, D)
    end_date: data di fine nel formato (AAAA, M, D)
    """

    start = datetime.datetime(start_date[0], start_date[1], start_date[2])
    end = datetime.datetime(end_date[0], end_date[1], end_date[2])


    pdf = None
    # Prova a connettersi a Yahoo Finance e a ottenere i dati
    # In caso di errore, stampa un messaggio di errore
    try:
        pdf =  pdr.get_data_yahoo(ticker, start, end)
    except Exception as e:
        print("Could not download Yahoo data: {}".format(e))

    return pdf


def annualised_sharpe(returns, N=252):
    """
    Calcola lo Sharpe Ratio annualizzato di un flusso di rendimenti in base 
    a un numero di periodi di trading, N. 252 è il valore predefinito per N,
    che quindi presuppone un flusso di rendimenti giornalieri.

    La funzione assume che i rendimenti siano l'eccesso di
    quelli rispetto a un benchmark.
    """
    return np.sqrt(N) * returns.mean() / returns.std()
        

Ora che abbiamo implementato le funzionalita per scaricare i dati da Yahoo Finance e calcolare direttamente il Sharpe Ratio annualizzato, possiamo verificare una strategia di buy-and-hold per due titoli azionari. Useremo Google (GOOG) e Goldman Sachs (GS) dal 1° gennaio 2000 al 31 dicembre 2016.

E’ anche possibile creare un’ulteriore funzione di supporto che permette di verificare rapidamente il Sharpe buy-and-hold su più azioni per lo stesso periodo (codificato):

            def equity_sharpe(ticker):
    """
    Calcola l'indice di Sharpe annualizzato in base al quotidiano
    ritorni di un simbolo di ticker azionario elencato in Yahoo Finanza.

    In questo script le date sono state cablate nel codice .
    """

    # Ottenere i dati storici giornalieri delle azioni per il periodo di tempo desiderato
    # e li aggiungi a un DataFrame panda
    pdf = get_historic_data(ticker, start_date=(2000,1,1), end_date=(2016,12,31))

    # Usa il metodo di variazione percentuale per calcolare facilment i rendimenti giornalieri
    pdf['daily_ret'] = pdf['Adj Close'].pct_change()

    # si considera un tasso annuale medio risk-free rate per un periodo del 5%
    pdf['excess_daily_ret'] = pdf['daily_ret'] - 0.05/252

    # restituisce lo Sharpe Ratio annualizzato basato gli eccessi dei rendimenti giornalieri
    return annualised_sharpe(pdf['excess_daily_ret'])
        

Per Google, il Sharpe Ratio della strategia buy-and-hold è pari a 0.7019, mentre per Goldman Sachs è 0.2404:

            >>> equity_sharpe('GOOG')
0.7019360529562169

>>> equity_sharpe('GS')
0.24035938143368338
        

Successivamente è possibile provare provare lo stesso calcolo per una strategia market-neutral. L’obiettivo di questa strategia è isolare completamente le prestazioni di un particolare titolo azionario dal mercato in generale. Il modo più semplice per raggiungere questo obiettivo è quello di ottenere una somma equivalente (in dollari) di un Exchange Traded Fund (ETF) concepito per seguire un tale mercato. La scelta più ovvia per il mercato azionario statunitense a grande capitalizzazione è l’indice S&P500, che è tracciato dall’ETF SPDR, con il ticker di SPY.

Per calcolare il Sharpe Ratio annualizzato di tale strategia otterremo i prezzi storici di SPY e calcoleremo i rendimenti percentuali in modo simile ai titoli precedenti, con l’eccezione che non useremo il benchmark senza rischio. Si calcola i rendimenti giornalieri netti come la differenza tra i rendimenti long e short e dividendo per 2, poiché ora abbiamo il doppio del capitale. Di seguito il codice Python / Pandas che implementa questa logica:

            def market_neutral_sharpe(ticker, benchmark):
    """
    Calcola lo Sharpe Ratio annualizzato per una strategia long / short
    neutrale al di un mercato, che prevede di andare long per il 'ticker'
    e un corrispondente short del "benchmark".
    """

    # Ottenere i dati storici sia per un simbolo / ticker che per un benchmark
    # Le date sono state codificate, ma puoi modificarle come meglio credi!
    tick = get_historic_data(ticker, start_date=(2000, 1, 1), end_date=(2016,12,31))
    bench = get_historic_data(benchmark, start_date=(2000, 1, 1), end_date=(2016,12,31))

    # Calcola la percentuale dei rendimenti per ogni serie temporale
    tick['daily_ret'] = tick['Adj Close'].pct_change()
    bench['daily_ret'] = bench['Adj Close'].pct_change()

    # Crea un nuovo DataFrame per memorizzare le informazioni sulla strategia
    # I rendimenti netti sono (long - short) / 2, poiché c'è il doppio
    # capitale di trading per questa strategia
    strat = pd.DataFrame(index=tick.index)
    strat['net_ret'] = (tick['daily_ret'] - bench['daily_ret']) / 2.0

    # restituisce lo Sharpe Ratio annualizzato per questa strategia
    return annualised_sharpe(strat['net_ret'])
        

Per Google, il Sharpe Ratio della strategia market-neutral long-only è pari a 0.6679, mentre per Goldman Sachs è 0.2809:

            >>> market_neutral_sharpe('GOOG', 'SPY')
0.6679282132106448

>>> market_neutral_sharpe('GS', 'SPY')
0.28097410604210993
        
Nonostante il Sharpe Ratio sia utilizzato quasi ovunque nel trading algoritmico, dobbiamo considerare altre metriche di performance e rischio. Negli articoli successivi discuteremo i drawdown e di come influenzano la decisione di eseguire o meno una strategia.

 

Per il codice completo riportato in questo articolo utilizzando il modulo di backtesting vettoriale VectorBacktest si può consultare il seguente repository di github:
https://github.com/datatrading-info/VectorBacktest

Gli altri articoli di questa serie

Benvenuto su DataTrading!

Sono Gianluca, ingegnere software e data scientist. Sono appassionato di coding, finanza e trading. Leggi la mia storia.

Ho creato DataTrading per aiutare le altre persone ad utilizzare nuovi approcci e nuovi strumenti, ed applicarli correttamente al mondo del trading.

DataTrading vuole essere un punto di ritrovo per scambiare esperienze, opinioni ed idee.

SCRIVIMI SU TELEGRAM

Per informazioni, suggerimenti, collaborazioni...

Torna in alto
Scroll to Top