import yfinance as yf
import pandas as pd

from scipy import stats
import numpy as np

import pingouin
def merge_time_series(df_1, df_2, how='outer'):
    df = df_1.merge(df_2, how=how, left_index=True, right_index=True)
    return df

def normalize(df):
    df = df.dropna()
    return (df / df.iloc[0]) * 100

def download_yahoo_data(tickers, normalize_quotes=True,
                      start='1970-01-01', end='2030-12-31'):
    quotes=pd.DataFrame()
    for ticker in tickers:
        df = yf.download(ticker, start=start, end=end, progress=False)
        df = df[['Adj Close']]
        df.columns=[ticker]
        quotes = merge_time_series(quotes, df)

    quotes = quotes.ffill()

    if normalize_quotes:
        quotes = normalize(quotes)

    return quotes

def compute_z_critical_region(alpha):
    return stats.norm.ppf(alpha),  stats.norm.ppf(1-alpha)

def compute_t_critical_region(alpha, df):
    return stats.t.ppf(alpha,df),  stats.t.ppf(1-alpha,df)

Capitulo 6 - Testes de Hipótese#

Quando conseguimos formular uma idea ou opinião de uma forma precisa sobre o valor de quantidades a idea torna-se estatísticamente testável e passa a ser uma hipótese.

Como analista podemos querer explorar questões como:

  • A rentabilidade média de um fundo é realmente diferente da reantabilidade média do seuu benchmark? (para provarmos se o gestor é bom ou bateu o benchmark por sorte);

  • A volatilidade dos retornos de uma acção alterou-se depois da acção ter sido adicionada ao S&P 500?

  • O aumento de market makers em impacto no bid-ask spread de uma acção?

Uma hipótese é definida como uma declaração sobre uma ou mais populações.

Passos num teste de hipóteses:

  1. Declararmos a nossa hipótese;

  2. Identificar o teste estatístico apropriado;

  3. Especificar o nível de significância;

  4. Declarar as regras para a nossa decisão;

  5. Obter os dados relevante e calcular os respectivos testes estatísticos;

  6. Tomar a decisão económica ou de investimento;

Passo 1: Definição da nossa hipótese#

Parece algo trivial mas como vamos ver mais à frente, nos casos práticos, nem sempre o é.

Devemos definir uma hipótese nula \(h_0\) e uma hipótese alternativa \(h_a\).

Hipótese Nula: A hipótese nula é a hipótese a ser testada. É a hipótese que assumimos verdadeira a menos que os nossos testes no levem a ter provas suficientes para a rejeitar.

Hipótese alternativa: A hipótese alternativa é a nossa ideia, aquilo que temos “esperança” em provar. É uma alteração do Status Quo.

Formulação da nossa da nossa hipótese: Podemos formular a nossa hipótese de 3 formas diferentes:

1.

  • \(h_0\): \(\theta\) = \(\theta_0\)

  • \(h_a\): \(\theta \neq \theta_0\)

(versão “diferente de”)

2.

  • \(h_0\): \(\theta \leq \theta_0\)

  • \(h_a\): \(\theta > \theta_0\)

(versão “maior que”)

3

  • \(h_0\): \(\theta \geq \theta_0\)

  • \(h_a\): \(\theta < \theta_0\)

(versão “menor que”)

A primeira hipótese é um teste de hipótese de duas caudas ou lados (two sided or two tailed);

A formulação 2 e 3 são testes de uma cauda (one sided ou one-tailed).

Exercício 6.1

Uma analista suspeita que, no ano mais recente, os retornos excessivos das ações foram inferiores a 5%. Ela quer então testar se os retornos em excesso são, de facto, inferiores a 5%. Designando a média da população como μ, quais hipóteses são mais apropriadas para sua análise?

  • a) \(H_0: µ\) = 5 e \(H_a\): µ ≠ 5

  • b) \(H_0: µ\) = 5 e \(H_a\): µ < 5

  • c) \(H_0: µ\) < 5 e \(H_a\): µ > 5

Hide code cell source
# Resposta correcta é a b) uma vez que a analista pretende testar se os retornos em excesso são menores.

Passo 2: Identificar a estatística de teste relevante#

Um ponto fulcral da nossa decisão será o valor da estatística de teste. A estatística de teste vai depender do que queremos testar.

Quadro resumo:

Não se preocupem muito entretanto que quando entrarmos nos exemplos vamos perceber.

def compute_t_single_mean(sample_mean, expected_mean, std, n):
  '''
  sample_mean, expected_mean, std, n
  '''
  return ((sample_mean-expected_mean)/(std/np.sqrt(n)))

Passo 3: Especificar um nível de significância#

Ao fazermos um teste de hipóteses temos de definir um nível de significância. Os níveis mais comuns são 10%, 5% ou 1%.

Diferentes níveis de significâcia influenciam a possibilidade de rejeitarmos ou não a hipotese nula. Infelizmente não podemos também aumentar indiscriminadamente o nível de confiança pois estamos a aumentar a probabilidade de não rejeitarmos a hipótese nula falsa e eventualmente podemos estar a cair naquilo que se chama de erro II (falha em rejeitar uma hipótese nula falsa).

Conceitos

  • Nível de significância (\(α\))

  • Nível de confiança (\(1 - α\))

Tipos de erro#

  1. Rejeitamos uma hipótese nula falsa. Decisão correcta;

  2. Rejeitamos uma hipótese nula verdadeira. Erro tipo I;

  3. Não rejeitamos uma hipótese nula falsa. Erro tipo II;

  4. Não rejeitamos uma hipótese nula verdadeira. Decisão correcta.

Questões escolha multipla para testar o conhecimento de erros tipo I e tipo II na Khan Academy

Passo 4: Declarar as regras para a nossa decisão#

Tendo em consideração a distribuição, e depois de decidirmos a o nível de significância podemos analisar os nossos pontos de rejeição. A nossa estatística de teste (que vamos calcular no passo 5) vai ou estar dentro de uma região de aceitação onde não podemos rejeitar a hipótese nula ou vai estar nas regiões de rejeição, onde rejeitamos a hipótese nula.

Passo 5: Obter os dados relevante e calcular os respectivos testes estatísticos#

O quinto passo no teste de hipóteses é obter os dados e calcular a estatística de teste.

A qualidade de nossas conclusões depende não apenas da adequação do modelo estatístico, mas também a qualidade dos dados que usamos na realização do teste. Primeiro, precisamos garantir que o procedimento de amostragem não inclua enviesamentos. Em segundo lugar, precisamos limpar os dados, verificando imprecisões e outros erros de medição nos dados. Uma vez assegurado que a amostra é imparcial e preciso, as informações da amostra são usadas para calcular a estatística de teste apropriada.

EXEMPLO 3 : Usando um Intervalo de Confiança em Testes de Hipóteses

Ao fazermos o nosso teste de hipóteses fizemos definimos hipóteses que dão origem a um teste de duas caudas. Optamos por um nível de significância de 5%.

Com base na nossa amostra calculamos um Z = 1.05. A decisão mais apropriada será:

  • a) Rejeitar a hipótese nula.

  • b) Aceita a hipótese nula.

  • c) Falha em rejeitar a hipótese nula.

Passo 5: Obter os dados relevante e calcular os respectivos testes estatísticos#

O quinto passo no teste de hipóteses é obter os dados e calcular a estatística de teste.

A qualidade de nossas conclusões depende não apenas da adequação do modelo estatístico, mas também a qualidade dos dados que usamos na realização do teste. Primeiro, precisamos garantir que o procedimento de amostragem não inclua enviesamentos. Em segundo lugar, precisamos limpar os dados, verificando imprecisões e outros erros de medição nos dados. Uma vez assegurado que a amostra é imparcial e preciso, as informações da amostra são usadas para calcular a estatística de teste apropriada.

EXEMPLO 3 : Usando um Intervalo de Confiança em Testes de Hipóteses

Ao fazermos o nosso teste de hipóteses fizemos definimos hipóteses que dão origem a um teste de duas caudas. Optamos por um nível de significância de 5%.

Com base na nossa amostra calculamos um Z = 1.05. A decisão mais apropriada será:

  • a) Rejeitar a hipótese nula.

  • b) Aceita a hipótese nula.

  • c) Falha em rejeitar a hipótese nula.

Passo 6: Tomar uma decisão#

Exercício 6.2#

Um analista pretende testar se os retornos ajustados ao risco de uma estratégia de trading (que são positivos) são estatísticamente positivos. Na amostra a média do excesso nos retornos ajustados ao risco face ao mercado é de 0.7% ao mês. A amostra é de 20 anos com dados mensais.

A estatística T calculada é de 2.5. O nível de significância é de 1%.

1) Quais são as hipóteses nula e alternativa?

Hide code cell source
# A hipótese nula é o sistema de trading não ter retornos em excesso face ao mercado portanto H_0 menor ou igual que 0% e
# a hipótese alternativa, o que o trader tem "esperança" em provar, é a hipótese complementar, ou seja h_a > 0%

2) Ao nível de significância de 1% quais são os pontos críticos?

A analisar se com uma ou duas caudas.

compute_t_critical_region(0.01, df=239)
(-2.342051322860583, 2.3420513228605824)

3) Rejeitamos a hipótese nula?

A analisar para que lado é a cauda.

Hide code cell source
# Uma vez que a estística T calculada está fora da região de aceitação rejeitamos a hipótese nula

p-value#

O p-value é o menor nível de significância no qual a hipótese nula pode ser rejeitada.

Quanto mais pequeno o p-value mais forte é a evidência contra a hipótese nula e mais a favor da hipótese alternativa. Em muitos testes temos como output do python um p-value de 0, o que representa que rejeitamos a hipótese nula. Por outro lado algumas vezes também temos um p-value maior que 0.1 o que nos leva a não rejeitar a hipótese nula para os casos mais comuns (\(\alpha\) de 1%, 5% ou 10%).

Quando fizermos os testes directamente em python vamo-nos guiar pelo p-value, que é logo dado como output.

Exercício 6.3 - Tomar uma decisão com base no p-value

Uma analista pretende testar as hipóteses \(H_0\): \(σ^2\) = 0,01 versus \(H_a\): \(σ_2\) ≠ 0,01. Usando software, ela determina que o valor-p para a estatística de teste é 0,03 ou 3%. Quais das seguintes afirmações são corretas?

  • a) Rejeite a hipótese nula nos níveis de significância de 1% e 5%.

  • b) Rejeitar a hipótese nula ao nível de 5%, mas não ao nível de 1% de significado.

  • c) Deixar de rejeitar a hipótese nula nos níveis de 1% e 5% de significado.

Hide code cell source
# b) está correto. A rejeição da hipótese nula requer que o p-value seja menor que
# o nível de significância. Com base neste requisito, a hipótese é rejeitada a um
# nível de significância de 5%, mas não no nível de significância de 1%.

Teste de uma só média#

Exemplo (pág. 382)#

Características de risco e retorno de um fundo de ações

Suponhamos que estamos a analisar o Sendar Equity Fund, um fundo de crescimento midcap que existe há 24 meses. Nesse período, alcançou uma média de retorno mensal de 1,50%, com desvio padrão amostral dos retornos mensais de 3,60%. Dado o seu nível de risco de mercado e de acordo com um modelo CAPM de esperava-se que o fundo obtivesse um retorno mensal médio de 1,10% durante esse período de tempo. Assumindo que os retornos são normalmente distribuídos, os resultados reais são consistente com um retorno mensal esperado de 1,10%?

Passo 1: Formular a hipótese nula

  • \(H_0\): μ = 1.1%

  • \(H_a\): μ ≠ 1.1%

Passo 2: Identificar a estatística de teste apropriada

Teste de uma média só. Ver função matemática no quadro acima. Para nós é a função compute_t_single_mean()

Passo 3: Especificar o nível de significância

\(\alpha\) = 5%

Passo 4: Declarar as regras para a nossa decisão

Ver quais os valores críticos:

compute_t_critical_region(0.025, 23)
(-2.068657610419041, 2.0686576104190406)

Porquê 23? A distribuição T funciona, como já vimos com graus de liberdade (df or degrees of freedom). Os graus de liberdade são iguais a n menos os números de parâmetros a serem avaliados (neste caso 1 porque é sobre um só média).

Se a estatística T que vamos calcular no ponto 5 estiver entre -2.069 e 2.69 não rejeitamos a hipótese nula. Se estiver fora desse range rejeitamos a hipótese nula.

Passo 5: Calcular a estatística de teste

Função python da fórmula matemática acima para testes t de uma só média#

compute_t_single_mean(sample_mean=1.5, expected_mean=1.1, std=3.6, n=24)
0.5443310539518171

Alternativa \(z\)#

Para amostras grandes, os profissionais às vezes usam um teste z em vez de um teste t para testes relativos a uma média. A justificação para usar o teste z neste contexto são duas.

Primeiro, em amostras grandes, a média amostral deve seguir a distribuição normal pelo menos aproximadamente, como já dissemos, cumprindo o pressuposto de normalidade do z-teste.

Em segundo lugar, a diferença entre os pontos de rejeição para o teste t e o teste z torna-se muito pequeno quando o tamanho da amostra é grande.

Num número muito limitado de casos, podemos conhecer a variância da população; Nesses casos o uso a estatística z é teoricamente correta

Exemplo (pág.384)#

Iremos só fazer a questão 2 uma vez que a questão 1 é igual à anterior.

Suponhamos que queremos testar se o retorno diário no ACE High Yield Total Index é diferente de zero. Obtendo uma amostra de 1.304 retornos diários, encontramos um retorno médio diário de 0.0157%, com desvio padrão de 0.3157%.

2. Usando a estatística de teste z-distribuída como uma aproximação, teste se o retorno médio diário é diferente de zero ao nível de 5% de significância.

Passo 1: Formular a hipótese nula

  • \(H_0\): μ = 0%

  • \(H_a\): μ ≠ 0%

(duas caudas)

Passo 2: Identificar a estatística de teste apropriada

Teste de uma média só. Iremos usar a alternativa z.

Para nós é a função compute_z_single_mean()

Passo 3: Especificar o nível de significância

\(\alpha\) = 5%

(duas caudas)

Passo 4: Declarar as regras para a nossa decisão

Ver quais os valores críticos:

compute_z_critical_region(0.025)
(-1.9599639845400545, 1.959963984540054)

A fórmula compute_z_critical_region() já não tem qualquer necessidade de DF. Apenas usa o \(\alpha\) (uma cauda) ou o \(\alpha/2\) (duas caudas).

Passo 5: Calcular a estatística de teste

def compute_z_single_mean(sample_mean, expected_mean, std, n):
  '''
  sample_mean, expected_mean, std, n
  '''
  return ((sample_mean-expected_mean)/(std/np.sqrt(n)))

compute_z_single_mean(sample_mean=0.0157, expected_mean=0, std=0.3157, n=1304)
1.7958243923896375

Passo 6: Tomar uma decisão

Exemplo (pág.386/387)#

Continuando o exemplo dos retornos no ACE High Yield Total Return Index, suponhamos que queremos testar se esses retornos são diferentes para dois períodos de tempo diferentes, Período 1 e Período 2.

Passo 1: Formular a hipótese nula

  • \(H_0\): μ_periodo_1 = μ_periodo_2

  • \(H_a\): μ_periodo_1 \(\neq\) μ_periodo_2

(duas caudas)

Passo 2: Identificar a estatística de teste apropriada

Teste de diferenças em médias.

Para nós é a função compute_t_diference_in_means() mas um pouco mais complicado pois inclui o cálculo de variância médio:

ou com a nossa fórmula compute_std_p_from_t_diference_in_means()

Passo 3: Especificar o nível de significância

\(\alpha\) = 5%

(duas caudas)

Passo 4: Declarar as regras para a nossa decisão

Ver quais os valores críticos:

compute_t_critical_region(0.025, 445+859)
(-1.96178487198399, 1.9617848719839897)

Passo 5: Calcular a estatística de teste

def compute_t_diference_in_means(mean_1, mean_2, std_p, n_1, n_2):
  a = (mean_1-mean_2) - 0
  b = np.sqrt((std_p/n_1) + (std_p/n_2))
  return a/b

def compute_std_p_from_t_diference_in_means(n_1, n_2, std_1, std_2):
  a = (n_1-1) * std_1
  b=  (n_2-1) * std_2
  c = (n_1 + n_2 - 2)
  return (a + b) / c

A Função compute_std_p_from_t_diference_in_means está a combinar o desvio padrão de duas amostras quando se supõe que é idêntico, como neste caso ser o mesmo activo. Isso serve para podermos calcular o compute_t_diference_in_means para analisarmos se a média entre as amostras é diferente.

compute_std_p_from_t_diference_in_means(n_1=445, n_2=859, std_1=0.31580, std_2=0.38760)
0.36311520737327185
compute_t_diference_in_means(mean_1=0.01775, mean_2=0.01134, std_p=0.363, n_1=445, n_2=859)
0.18215559221262695

Passo 6: Tomar uma decisão

Exemplo (pág.389)#

Ao analisar os retornos trimestrais para um período de três anos para dois carteiras geridas activamente especializadas em metais preciosos. As duas carteiras são semelhantes em risco e tinham custos de gestão quase idênticos.

Um grande investimento empresa de serviços avaliou o Portfólio B como sendo melhor que Portfólio A.

Ao investigar desempenho relativo das carteiras, suponhamos que queremos testar a hipótese de que o retorno trimestral médio da Carteira A é igual ao retorno trimestral médio na Carteira B durante o período de três anos. Uma vez que as duas carteiras compartilham essencialmente o mesmo conjunto de fatores de risco, seus retornos não são independentes, então teste de comparações em par é apropriado. Vamos usar um nível de significância de 10%.

Passo 1: Formular a hipótese nula

  • \(H_0\): μ = 0%

  • \(H_a\): μ ≠ 0%

(duas caudas)

Passo 2: Identificar a estatística de teste apropriada

Para nós é a função compute_t_mean_of_differences()

Passo 3: Especificar o nível de significância

\(\alpha\) = 5%

(duas caudas)

Passo 4: Declarar as regras para a nossa decisão

Ver quais os valores críticos:

compute_t_critical_region(0.05, 11)
(-1.7958848187036696, 1.7958848187036691)

Porquê 11? A distribuição \(t\) funciona, como já vimos, com graus de liberdade (df or degrees of freedom). Os graus de liberdade são iguais a n menos os números de parâmetros a serem avaliados (neste caso 1 porque é uma só diferença de médias).

DICA: Onde se podem enganar.

  • Teste de duas caudas ou uma só cauda tem influência no \(\alpha\) a colocar na fórmula.

  • df nunca é igual a n, ou é n-1 ou n-2 etc etc

def compute_t_mean_of_differences(mean_dif, std_dif):
  return (mean_dif-0) / (std_dif/np.sqrt(12))

compute_t_mean_of_differences(mean_dif=4.40083, std_dif=5.47434)
2.7847963975468613

Passo 6: Tomar uma decisão

S&P 500 vs MSCI World - Médias das diferenças (Exemplo real com output python)#

tickers = ['VT', 'SPY']
nomes = tickers
ret = download_yahoo_data(tickers, nomes).resample('BM').last().pct_change().dropna()

# ret = ret['2020-04':]
ret = ret['2013-08':'2018-07']

from pingouin import ttest

ttest(ret['VT'], ret['SPY'], alternative='two-sided', paired=True)
/tmp/ipykernel_158773/1900226107.py:3: FutureWarning: 'BM' is deprecated and will be removed in a future version, please use 'BME' instead.
  ret = download_yahoo_data(tickers, nomes).resample('BM').last().pct_change().dropna()
T dof alternative p-val CI95% cohen-d BF10 power
T-test -2.076727 59 two-sided 0.042191 [-0.01, -0.0] 0.093692 1.04 0.110133

Outros testes#

Teste de uma variância - Quando queremos por exemplo ver se a variância de um determinado fundo foi abaixo do valor pretendido (exemplo 12 pag. 394)

Testes de diferenças entre variâncias - Quando queremos por exemplo ver se a variância de uma acção se alterou depois de entrada de regulação (exemplo 13 pag. 398)

Testes de correlação - Em muitos contextos de investimentos, queremos avaliar a força da relação linear entre duas variáveis; ou seja, queremos avaliar a correlação entre elas. Um teste de significância de um coeficiente de correlação permite-nos avaliar se o relação entre duas variáveis ​​aleatórias é o resultado do acaso.