Relatório Sharpe para a medição do desempenho algorítmico da negociação

Autora:Bem-estar, Criado: 2019-03-18 13:24:11, Atualizado:

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 mais risco?

Estes problemas de comparação de estratégias e avaliação de riscos motivam a utilização do rácio de Sharpe.

Definição da proporção 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:imgEm 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 Sharpe Ratio frequentemente citado por aqueles que realizam estratégias de negociação é o Sharpe anualizado, cujo cálculo depende do período de negociação do qual os retornos são medidos.imgObserve que o próprio rácio de Sharpe deve ser calculado com base no tipo de Sharpe desse período de tempo específico. Para uma estratégia baseada no período de negociação de dias, N = 252 (como há 252 dias de negociação em um ano, não 365), e Ra, Rb devem ser os retornos diários. Da mesma forma, para horas N = 252 × 6,5 = 1638, não N = 252 × 24 = 6048, pois há apenas 6,5 horas em um dia de negociação.

Inclusão de referência

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 yardstick ou um obstáculo que uma determinada estratégia deve superar para que valha a pena considerar. Por exemplo, uma estratégia simples de longo prazo usando ações de grande capitalização dos EUA deve esperar vencer o índice S&P500 em média, ou igualar-se a ele por menos volatilidade.

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.

Limitações

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 pennies under a steam roller). Um fluxo constante de prêmios de opção são gerados pela venda de opções de compra ao longo do tempo, levando a uma baixa volatilidade de retornos, com um forte excesso acima de um benchmark. Neste caso, a estratégia possuiria uma alta taxa de Sharpe (com base em dados históricos).

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.

Uso prático e exemplos

Uma questão óbvia que permaneceu sem resposta até agora neste artigo é Qual é uma boa taxa de Sharpe para uma estratégia?. Pragmaticamente, você deve ignorar qualquer estratégia que possua uma taxa de Sharpe anualizada S<1 após os custos de transação. Os fundos de hedge quantitativos tendem a ignorar quaisquer estratégias que possuem taxas de Sharpe S<2. Um fundo de hedge quantitativo proeminente que eu conheço nem consideraria estratégias que tivessem taxas de Sharpe S<3 enquanto estava em pesquisa.

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.

Exemplos de proporções de Sharpe

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 ((GS, SPY) 0,29991401047248328 Apesar da taxa de Sharpe ser usada em quase todos os lugares na negociação algorítmica, precisamos considerar outras métricas de desempenho e risco.


Mais.