Bei der Durchführung einer algorithmischen Handelsstrategie ist es verlockend, die annualisierte Rendite als nützlichste Leistungsmetrik zu betrachten. Allerdings gibt es viele Mängel bei der Verwendung dieser Maßnahme isoliert. Die Berechnung der Rendite für bestimmte Strategien ist nicht ganz einfach. Dies gilt insbesondere für Strategien, die nicht richtungsorientiert sind, wie marktneutrale Varianten oder Strategien, die Hebelwirkung verwenden. Diese Faktoren erschweren es, zwei Strategien zu vergleichen, die ausschließlich auf ihren Renditen basieren.
Darüber hinaus, wenn uns zwei Strategien mit identischen Renditen präsentiert werden, wie wissen wir, welche mehr Risiko enthält? Weiterhin, was meinen wir überhaupt mit "mehr Risiko"? In der Finanzwelt beschäftigen wir uns oft mit Volatilität der Renditen und Zeiten des Drawdowns. Wenn also eine dieser Strategien eine signifikant höhere Volatilität der Renditen aufweist, würden wir sie wahrscheinlich weniger attraktiv finden, obwohl ihre historischen Renditen ähnlich, wenn nicht identisch sein könnten.
Diese Probleme des Strategievergleichs und der Risikobewertung motivieren den Einsatz des Sharpe-Verhältnisses.
William Forsyth Sharpe ist ein Nobelpreisträger, der dazu beigetragen hat, das Capital Asset Pricing Model (CAPM) zu entwickeln und 1966 das Sharpe Ratio (später 1994 aktualisiert) entwickelt hat.
Das Sharpe-Verhältnis S wird durch folgende Beziehung definiert:Hierbei ist Ra die Periodenrendite des Vermögenswerts oder der Strategie und Rb die Periodenrendite einer geeigneten Benchmark.
Die Ratio vergleicht den mittleren Durchschnitt der überschüssigen Renditen des Vermögenswerts oder der Strategie mit der Standardabweichung dieser Renditen.
Die
Die oben genannte Formel für die Sharpe-Ratio verweist auf die Verwendung eines Benchmarks. Ein Benchmark wird als
Die Wahl des Benchmarks kann manchmal unklar sein. Zum Beispiel sollte ein Sektor-Exchange Traded Fund (ETF) als Performance-Benchmark für einzelne Aktien oder den S&P500 selbst verwendet werden? Warum nicht den Russell 3000? Ebenso sollte sich eine Hedgefondsstrategie mit einem Marktindex oder einem Index anderer Hedgefonds vergleichen? Es gibt auch die Komplikation der
In einem bestimmten Fall, bei marktneutralen Strategien, gibt es eine besondere Komplikation, ob die risikofreie Rate oder Null als Benchmark verwendet werden soll. Der Marktindex selbst sollte nicht verwendet werden, da die Strategie von Grund auf marktneutral ist. Die richtige Wahl für ein marktneutrales Portfolio besteht nicht darin, die risikofreie Rate abzuziehen, da es sich um eine Selbstfinanzierung handelt. Da Sie eine Kreditbeteiligung, Rf, aus dem Halten einer Marge erhalten, ist die tatsächliche Berechnung der Rendite: (Ra + Rf) −Rf = Ra. Daher gibt es keine tatsächliche Subtraktion der risikofreien Dollarrate für neutrale Strategien.
Trotz der Prävalenz des Sharpe-Verhältnisses im Bereich der quantitativen Finanzierungen ist er jedoch von einigen Einschränkungen betroffen.
Erstens ist die Sharpe-Ratio rückblickend. Sie berücksichtigt nur die historische Renditeverteilung und Volatilität, nicht die in der Zukunft auftretenden. Bei der Beurteilung auf der Grundlage der Sharpe-Ratio wird implizit davon ausgegangen, dass die Vergangenheit der Zukunft ähnlich sein wird. Dies ist offensichtlich nicht immer der Fall, insbesondere bei Veränderungen des Marktregimes.
Die Sharpe-Ratio-Berechnung geht davon aus, dass die verwendeten Renditen normal verteilt sind (d. h. gaussisch). Leider leiden Märkte oft unter einer Kurtosis über der einer normalen Verteilung. Im Wesentlichen hat die Renditenverteilung
Dies kann in Strategien deutlich gesehen werden, die sehr anfällig für solche Risiken sind. Zum Beispiel der Verkauf von Call-Optionen (auch bekannt als
Obwohl dieser Punkt für einige offensichtlich erscheinen mag, MUSSEN die Transaktionskosten in die Berechnung der Sharpe-Ratio einbezogen werden, damit sie realistisch ist. Es gibt unzählige Beispiele für Handelsstrategien, die hohe Sharpes (und damit eine Wahrscheinlichkeit einer großen Rentabilität) haben, die erst nach Berücksichtigung realistischer Kosten auf niedrige Sharpe, niedrige Rentabilitätsstrategien reduziert werden. Dies bedeutet, die Nettorenditen bei der Berechnung über die Benchmark hinaus zu nutzen. Daher müssen die Transaktionskosten vor der Berechnung der Sharpe-Ratio berücksichtigt werden.
Eine offensichtliche Frage, die bisher in diesem Artikel unbeantwortet geblieben ist, ist
Die Sharpe-Ratio wird oft mit der Handelsfrequenz steigen. Einige Hochfrequenzstrategien haben hohe einstellige (und manchmal niedrige doppelte) Ziffern Sharpe-Ratio, da sie fast jeden Tag und sicherlich jeden Monat profitabel sein können. Diese Strategien leiden selten unter einem katastrophalen Risiko und minimieren so ihre Volatilität der Rendite, was zu solchen hohen Sharpe-Ratio führt.
Dies war bis jetzt ein ziemlich theoretischer Artikel. Jetzt richten wir unsere Aufmerksamkeit auf einige tatsächliche Beispiele. Wir beginnen einfach, indem wir einen langen Kauf und Halten einer einzelnen Aktie betrachten und dann eine marktneutrale Strategie betrachten. Beide Beispiele wurden in der Python Panda Datenanalyse Bibliothek durchgeführt.
Die erste Aufgabe besteht darin, die Daten tatsächlich zu erhalten und in ein Panda-DataFrame-Objekt zu legen. In dem Artikel über die Implementierung von Securities Master in Python und MySQL habe ich ein System dafür erstellt. Alternativ können wir diesen einfacheren Code verwenden, um Yahoo Finance-Daten direkt zu erfassen und direkt in ein Panda-DataFrame zu legen. Am Ende dieses Skripts habe ich eine Funktion erstellt, um die annualisierte Sharpe-Ratio basierend auf einem Zeitrahmen-Rendite-Stream zu berechnen:
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()
Jetzt, da wir die Möglichkeit haben, Daten von Yahoo Finance zu erhalten und die annualisierte Sharpe-Ratio einfach zu berechnen, können wir eine Buy-and-Hold-Strategie für zwei Aktien testen. Wir werden Google (GOOG) und Goldman Sachs (GS) vom 1. Januar 2000 bis zum 29. Mai 2013 verwenden (als ich diesen Artikel schrieb!).
Wir können eine zusätzliche Helferfunktion erstellen, die es uns ermöglicht, schnell Sharpe über mehrere Aktien für denselben (hardcodierten) Zeitraum zu sehen:
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'])
Für Google beträgt die Sharpe-Ratio für Kauf und Halten 0,7501.
Die Kommission hat die Kommission aufgefordert, ihre Stellungnahme zu dem Bericht vorzulegen. 0,75013831274645904
Aktien von Aktienhändlern (einschließlich Aktien von Aktienhändlern) 0,21777027767830823
Nun können wir die gleiche Berechnung für eine marktneutrale Strategie ausprobieren. Das Ziel dieser Strategie ist es, die Leistung einer bestimmten Aktie vollständig vom Markt im Allgemeinen zu isolieren. Der einfachste Weg, dies zu erreichen, besteht darin, eine gleiche Menge (in Dollar) eines Exchange Traded Fund (ETF), der entworfen wurde, um einen solchen Markt zu verfolgen, kurz zu gehen. Die offensichtlichste Wahl für den US-amerikanischen Large-Cap-Aktienmarkt ist der S&P500-Index, der vom SPDR ETF verfolgt wird, mit dem Tickern SPY.
Um die annualisierte Sharpe-Ratio einer solchen Strategie zu berechnen, erhalten wir die historischen Preise für SPY und berechnen die prozentuale Rendite ähnlich wie bei den vorherigen Aktien, mit der Ausnahme, dass wir die risikofreie Benchmark nicht verwenden. Wir berechnen die Netto-Tagerendite, die die Differenz zwischen der langen und der kurzen Rendite subtrahieren und dann durch 2 dividieren muss, da wir jetzt das Doppelte des Handelskapitals haben. Hier ist der Python/Pandas-Code, um dies durchzuführen:
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'])
Für Google beträgt das Sharpe-Verhältnis für die lang-/kurzmarktneutrale Strategie 0,7597.
Markt-neutral_sharpe ((
Markt-neutral_sharpe 0,29991401047248328 Trotz der Tatsache, dass die Sharpe-Ratio fast überall im algorithmischen Handel verwendet wird, müssen wir andere Kennzahlen für Leistung und Risiko berücksichtigen.