Quando se realiza uma estratégia de negociação algorítmica, é tentador considerar o retorno anualizado como a métrica de desempenho mais útil. No entanto, há muitas falhas ao usar esta medida isoladamente. O cálculo dos retornos para certas estratégias não é completamente direto. Isto é especialmente verdadeiro para estratégias que não são direcionais, como variantes neutras do mercado ou estratégias que fazem uso de alavancagem. Estes fatores tornam difícil comparar duas estratégias baseadas apenas em seus retornos.
Além disso, se nos forem apresentadas duas estratégias que possuem retornos idênticos, como saberemos qual delas contém mais risco? Além disso, o que queremos dizer com
Estes problemas de comparação de estratégias e avaliação de riscos motivam a utilização do rácio de Sharpe.
William Forsyth Sharpe é um economista ganhador do Prêmio Nobel, que ajudou a criar o Modelo de Preço de Ativos de Capital (CAPM) e desenvolveu a Relação Sharpe em 1966 (mais tarde atualizada em 1994).
A razão de Sharpe S é definida pela seguinte relação:Em que Ra é o rendimento do período do ativo ou da estratégia e Rb é o rendimento do período de um índice de referência adequado.
O rácio compara a média média dos retornos excessivos do ativo ou da estratégia com o desvio-padrão desses retornos.
O
A fórmula para o rácio Sharpe acima alude ao uso de um índice de referência. Um índice de referência é usado como um
A escolha do benchmark pode às vezes ser incerta. Por exemplo, um fundo de câmbio de setor (ETF) deve ser usado como benchmark de desempenho para ações individuais, ou o próprio S&P500? Por que não o Russell 3000? Igualmente, uma estratégia de fundo de hedge deve ser comparada a um índice de mercado ou a um índice de outros fundos de hedge? Há também a complicação da taxa livre de risco. Devem ser usados títulos do governo nacional? Uma cesta de títulos internacionais? Notas de curto ou longo prazo? Uma mistura?
Em um caso particular, para estratégias neutras para o mercado, há uma complicação particular em relação a se usar a taxa livre de risco ou zero como referência. O índice de mercado em si não deve ser utilizado, pois a estratégia é, por conceção, neutra para o mercado. A escolha correta para uma carteira neutra para o mercado não é subtrair a taxa livre de risco porque é autofinanciamento. Uma vez que você ganha um interesse de crédito, Rf, de manter uma margem, o cálculo real de retornos é: (Ra + Rf) −Rf = Ra. Portanto, não há subtração real da taxa livre de risco em dólares para estratégias neutras.
Apesar da prevalência do rácio de Sharpe no âmbito das finanças quantitativas, ele tem algumas limitações.
Em primeiro lugar, o rácio de Sharpe é retrospectivo. Ele conta apenas com a distribuição de retornos históricos e volatilidade, não aqueles que ocorrem no futuro. Ao fazer julgamentos com base no rácio de Sharpe, há uma suposição implícita de que o passado será semelhante ao futuro.
O cálculo do rácio de Sharpe assume que os retornos usados são normalmente distribuídos (ou seja, gaussiano). Infelizmente, os mercados muitas vezes sofrem de curtose acima da de uma distribuição normal. Essencialmente, a distribuição de retornos tem "caudas mais pesadas" e, portanto, os eventos extremos são mais propensos a ocorrer do que uma distribuição gaussiana nos levaria a acreditar.
Isso pode ser visto claramente em estratégias que são altamente propensas a tais riscos. Por exemplo, a venda de opções de compra (também conhecida como
Embora este ponto possa parecer óbvio para alguns, os custos de transação devem ser incluídos no cálculo do rácio de Sharpe para que ele seja realista. Existem inúmeros exemplos de estratégias de negociação que têm altos Sharpes (e, portanto, uma probabilidade de grande lucratividade) apenas para serem reduzidas a estratégias de baixa Sharpe, baixa lucratividade, uma vez que os custos realistas tenham sido considerados. Isso significa usar os retornos líquidos ao calcular o excesso do índice de referência. Assim, os custos de transação devem ser considerados no cálculo upstream do rácio de Sharpe.
Uma questão óbvia que permaneceu sem resposta até agora neste artigo é
A taxa de Sharpe geralmente aumenta com a frequência de negociação. Algumas estratégias de alta frequência terão altas taxas de Sharpe de um único dígito (e às vezes baixas duplas), pois podem ser lucrativas quase todos os dias e certamente todos os meses.
Este foi um artigo bastante teórico até este ponto. Agora vamos voltar nossa atenção para alguns exemplos reais. Vamos começar simplesmente, considerando uma compra e retenção de uma ação individual por muito tempo e, em seguida, considerar uma estratégia neutra de mercado. Ambos esses exemplos foram realizados na biblioteca de análise de dados Python pandas.
A primeira tarefa é realmente obter os dados e colocá-los em um objeto Panda DataFrame. No artigo sobre implementação do mestre de valores mobiliários em Python e MySQL, eu criei um sistema para alcançar isso. Alternativamente, podemos usar esse código mais simples para pegar os dados do Yahoo Finance diretamente e colocá-los diretamente em um Panda DataFrame. Na parte inferior deste script, eu criei uma função para calcular a taxa de Sharpe anualizada com base em um fluxo de retornos de período de tempo:
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()
Agora que temos a capacidade de obter dados do Yahoo Finance e calcular diretamente a taxa de Sharpe anualizada, podemos testar uma estratégia de compra e retenção para duas ações.
Podemos criar uma função auxiliar adicional que nos permite ver rapidamente Sharpe buy-and-hold em várias ações para o mesmo período (codificado):
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'])
Para o Google, o rácio Sharpe para compra e detenção é 0,7501.
Equity_sharpe (GOOG) 0,75013831274645904
Equity_sharpe 0,21777027767830823
Agora, podemos tentar o mesmo cálculo para uma estratégia neutra de mercado. O objetivo desta estratégia é isolar completamente o desempenho de uma determinada ação do mercado em geral. A maneira mais simples de alcançar isso é fazer um curto de uma quantidade igual (em dólares) de um fundo negociado em bolsa (ETF) que foi projetado para rastrear tal mercado. A escolha mais óbvia para o mercado de ações de grande capitalização dos EUA é o índice S&P500, que é rastreado pelo SPDR ETF, com o ticker de SPY.
Para calcular o rácio Sharpe anualizado de tal estratégia, obteremos os preços históricos para SPY e calcularemos os retornos percentuais de maneira semelhante às ações anteriores, com a exceção de que não usaremos o benchmark livre de risco.
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'])
Para o Google, o rácio Sharpe para a estratégia de mercado neutro longo/curto é de 0,7597.
O mercado_neutral_sharpe (GOOG, SPY) 0,75966612163452329
mercado_neutral_sharpe ((