Lors de la mise en œuvre d'une stratégie de trading algorithmique, il est tentant de considérer le rendement annualisé comme la mesure de performance la plus utile. Cependant, il existe de nombreux inconvénients à utiliser cette mesure isolément. Le calcul des rendements pour certaines stratégies n'est pas tout à fait simple. Cela est particulièrement vrai pour les stratégies qui ne sont pas directionnelles telles que les variantes neutres du marché ou les stratégies qui utilisent l'effet de levier. Ces facteurs rendent difficile la comparaison de deux stratégies basées uniquement sur leurs rendements.
En outre, si nous sommes confrontés à deux stratégies présentant des rendements identiques, comment savons-nous laquelle contient plus de risque? En outre, que voulons-nous dire par "plus de risque"? En finance, nous nous préoccupons souvent de la volatilité des rendements et des périodes de retrait. Ainsi, si l'une de ces stratégies a une volatilité significativement plus élevée des rendements, nous la trouverons probablement moins attrayante, malgré le fait que ses rendements historiques peuvent être similaires, voire identiques.
Ces problèmes de comparaison des stratégies et d'évaluation des risques motivent l'utilisation du ratio de Sharpe.
William Forsyth Sharpe est un économiste lauréat du prix Nobel, qui a contribué à créer le modèle de tarification des actifs en capital (CAPM) et a développé le ratio Sharpe en 1966 (plus tard mis à jour en 1994).
Le rapport Sharpe S est défini par la relation suivante:Dans ce cas, la valeur de l'actif ou de la stratégie est la valeur de l'indice de référence approprié.
Le ratio compare la moyenne moyenne des rendements excédentaires de l'actif ou de la stratégie avec l'écart type de ces rendements.
Le ratio
La formule pour le ratio Sharpe ci-dessus fait allusion à l'utilisation d'un indice de référence. Un indice de référence est utilisé comme un
Le choix de l'indice de référence peut parfois être flou. Par exemple, un fonds négocié en bourse (ETF) sectoriel doit-il être utilisé comme indice de performance pour les actions individuelles, ou le S&P500 lui-même? Pourquoi pas le Russell 3000? De même, une stratégie de fonds spéculatifs devrait-elle se comparer à un indice de marché ou à un indice d'autres fonds spéculatifs? Il y a aussi la complication du taux sans risque.
Dans un cas particulier, pour les stratégies neutres sur le marché, il y a une complication particulière quant à savoir s'il faut utiliser le taux sans risque ou zéro comme référence. L'indice de marché lui-même ne doit pas être utilisé car la stratégie est, par conception, neutre sur le marché. Le choix correct pour un portefeuille neutre sur le marché n'est pas de soustraire le taux sans risque car il est autofinancement. Puisque vous gagnez un intérêt de crédit, Rf, de la détention d'une marge, le calcul réel des rendements est: (Ra + Rf) −Rf = Ra. Par conséquent, il n'y a pas de soustraction réelle du taux sans risque en dollars pour les stratégies neutres.
Malgré la prévalence du ratio de Sharpe au sein de la finance quantitative, il souffre de certaines limites.
Premièrement, le ratio Sharpe est rétrospectif. Il ne tient compte que de la répartition historique des rendements et de la volatilité, et non de celles qui se produiront à l'avenir.
Le calcul du ratio de Sharpe suppose que les rendements utilisés sont normalement distribués (c'est-à-dire gaussiens). Malheureusement, les marchés souffrent souvent d'une kurtosis supérieure à celle d'une distribution normale.
Cette tendance peut être clairement observée dans les stratégies qui sont très sujettes à de tels risques. Par exemple, la vente d'options d'achat (alias
Bien que ce point puisse sembler évident pour certains, les coûts de transaction DOIVENT être inclus dans le calcul du ratio Sharpe pour qu'il soit réaliste. Il existe d'innombrables exemples de stratégies de négociation qui ont des Sharpes élevés (et donc une probabilité de grande rentabilité) qui ne sont réduites qu'à des stratégies à faible Sharpe, à faible rentabilité une fois que les coûts réalistes ont été pris en compte. Cela signifie utiliser les rendements nets lors du calcul en excédent de l'indice de référence. Par conséquent, les coûts de transaction doivent être pris en compte en amont du calcul du ratio Sharpe.
Une question évidente qui est restée sans réponse jusqu'à présent dans cet article est
Le ratio Sharpe augmente souvent avec la fréquence des transactions. Certaines stratégies à haute fréquence auront des ratios Sharpe à un seul chiffre (et parfois à deux chiffres) élevés, car elles peuvent être rentables presque tous les jours et certainement tous les mois.
Il s'agit d'un article assez théorique jusqu'à présent. Maintenant, nous allons nous concentrer sur quelques exemples réels. Nous commencerons simplement, en considérant un achat et une détention à long terme d'une action individuelle, puis en considérant une stratégie neutre sur le marché. Ces deux exemples ont été réalisés dans la bibliothèque d'analyse de données Python pandas.
La première tâche est d'obtenir les données et de les mettre dans un objet Panda DataFrame. Dans l'article sur l'implémentation des valeurs mobilières en Python et MySQL, j'ai créé un système pour y parvenir. Alternativement, nous pouvons utiliser ce code plus simple pour saisir directement les données de Yahoo Finance et les mettre directement dans un Panda DataFrame. Au bas de ce script, j'ai créé une fonction pour calculer le ratio annualisé de Sharpe basé sur un flux de rendements de période:
import datetime
import numpy as np
import pandas as pd
import urllib2
def get_historic_data(ticker,
start_date=(2000,1,1),
end_date=datetime.date.today().timetuple()[0:3]):
"""
Obtains data from Yahoo Finance and adds it to a pandas DataFrame object.
ticker: Yahoo Finance ticker symbol, e.g. "GOOG" for Google, Inc.
start_date: Start date in (YYYY, M, D) format
end_date: End date in (YYYY, M, D) format
"""
# Construct the Yahoo URL with the correct integer query parameters
# for start and end dates. Note that some parameters are zero-based!
yahoo_url = "http://ichart.finance.yahoo.com/table.csv?s=%s&a=%s&b=%s&c=%s&d=%s&e=%s&f=%s" % \
(ticker, start_date[1] - 1, start_date[2], start_date[0], end_date[1] - 1, end_date[2], end_date[0])
# Try connecting to Yahoo Finance and obtaining the data
# On failure, print an error message
try:
yf_data = urllib2.urlopen(yahoo_url).readlines()
except Exception, e:
print "Could not download Yahoo data: %s" % e
# Create the (temporary) Python data structures to store
# the historical data
date_list = []
hist_data = [[] for i in range(6)]
# Format and copy the raw text data into datetime objects
# and floating point values (still in native Python lists)
for day in yf_data[1:]: # Avoid the header line in the CSV
headers = day.rstrip().split(',')
date_list.append(datetime.datetime.strptime(headers[0],'%Y-%m-%d'))
for i, header in enumerate(headers[1:]):
hist_data[i].append(float(header))
# Create a Python dictionary of the lists and then use that to
# form a sorted Pandas DataFrame of the historical data
hist_data = dict(zip(['open', 'high', 'low', 'close', 'volume', 'adj_close'], hist_data))
pdf = pd.DataFrame(hist_data, index=pd.Index(date_list)).sort()
return pdf
def annualised_sharpe(returns, N=252):
"""
Calculate the annualised Sharpe ratio of a returns stream
based on a number of trading periods, N. N defaults to 252,
which then assumes a stream of daily returns.
The function assumes that the returns are the excess of
those compared to a benchmark.
"""
return np.sqrt(N) * returns.mean() / returns.std()
Maintenant que nous avons la possibilité d'obtenir des données de Yahoo Finance et de calculer directement le ratio annualisé de Sharpe, nous pouvons tester une stratégie d'achat et de détention pour deux actions.
Nous pouvons créer une fonction d'assistant supplémentaire qui nous permet de voir rapidement l'achat et la détention de Sharpe sur plusieurs actions pour la même période (codifiée):
def equity_sharpe(ticker):
"""
Calculates the annualised Sharpe ratio based on the daily
returns of an equity ticker symbol listed in Yahoo Finance.
The dates have been hardcoded here for the QuantStart article
on Sharpe ratios.
"""
# Obtain the equities daily historic data for the desired time period
# and add to a pandas DataFrame
pdf = get_historic_data(ticker, start_date=(2000,1,1), end_date=(2013,5,29))
# Use the percentage change method to easily calculate daily returns
pdf['daily_ret'] = pdf['adj_close'].pct_change()
# Assume an average annual risk-free rate over the period of 5%
pdf['excess_daily_ret'] = pdf['daily_ret'] - 0.05/252
# Return the annualised Sharpe ratio based on the excess daily returns
return annualised_sharpe(pdf['excess_daily_ret'])
Pour Google, le ratio Sharpe pour l'achat et la détention est de 0,7501.
Je ne peux pas vous dire ce que je pense. 0,75013831274645904 Il est vrai que c'est un problème.
les fonds propres de l'entreprise 0,21777027767830823
L'objectif de cette stratégie est d'isoler complètement la performance d'une action particulière du marché en général. La façon la plus simple d'y parvenir est de sous-traiter un montant égal (en dollars) d'un fonds négocié en bourse (ETF) conçu pour suivre un tel marché. Le choix le plus évident pour le marché américain des actions à grande capitalisation est l'indice S&P500, qui est suivi par le SPDR ETF, avec le ticker de SPY.
Pour calculer le ratio annualisé de Sharpe d'une telle stratégie, nous obtiendrons les prix historiques pour SPY et calculerons les rendements en pourcentage de manière similaire aux stocks précédents, à l'exception que nous n'utiliserons pas l'indice de référence sans risque. Nous calculerons les rendements quotidiens nets qui nécessitent de soustraire la différence entre les rendements longs et courts, puis de les diviser par 2, car nous avons maintenant deux fois plus de capital de trading. Voici le code Python/pandas pour effectuer cela:
def market_neutral_sharpe(ticker, benchmark):
"""
Calculates the annualised Sharpe ratio of a market
neutral long/short strategy inolving the long of 'ticker'
with a corresponding short of the 'benchmark'.
"""
# Get historic data for both a symbol/ticker and a benchmark ticker
# The dates have been hardcoded, but you can modify them as you see fit!
tick = get_historic_data(ticker, start_date=(2000,1,1), end_date=(2013,5,29))
bench = get_historic_data(benchmark, start_date=(2000,1,1), end_date=(2013,5,29))
# Calculate the percentage returns on each of the time series
tick['daily_ret'] = tick['adj_close'].pct_change()
bench['daily_ret'] = bench['adj_close'].pct_change()
# Create a new DataFrame to store the strategy information
# The net returns are (long - short)/2, since there is twice
# trading capital for this strategy
strat = pd.DataFrame(index=tick.index)
strat['net_ret'] = (tick['daily_ret'] - bench['daily_ret'])/2.0
# Return the annualised Sharpe ratio for this strategy
return annualised_sharpe(strat['net_ret'])
Pour Google, le ratio Sharpe pour la stratégie neutre sur le marché long/courte est de 0,7597.
Je ne peux pas vous dire ce que je veux. Je vous en prie.
Je ne suis pas d'accord avec vous. Je vous en prie. Bien que le ratio de Sharpe soit utilisé presque partout dans le trading algorithmique, nous devons considérer d'autres mesures de performance et de risque.