Uncategorized

Momento R do Dia – Cointegração e Finanças: tão óbvio, né?

Como sabemos, nove entre dez alunos dizem que econometria não serve para nada. Também sabemos que são os mesmos nove alunos que não mexem uma palha para pesquisar antes de falar bobagens. No post anterior, falei do livro de Chan (2009).

Aliás, ele é citado em um exemplo mais simples sobre a importância da cointegração em finanças disponível nesta página. Trabalhei no código que o autor fez para adaptá-lo ao meu exemplo. Por que? Porque o autor não faz a regressão considerando os vetores como séries de tempo, o que impede o uso do teste de Engle-Granger sobre os resíduos. Assim, tive que alterar o seu código (e o leitor fica com o dever de casa de comparar ambos os códigos).

Mas eu falava de cointegração e finanças, certo? Bem, Chan (2009) cita a cointegração como um ponto importante na estratégia dos traders. Diz ele:

If a price series (of a stock, a pair of stocks, or, in general, a portfolio of stocks) is stationary, then a mean-reverting strategy is guaranteed to be profitable, as long as the stationarity persists into the future (which is by no means guaranteed). However, the converse is not true. You don’t necessarily need a stationary price series in order to have a successful mean-reverting strategy. Even a nonstationary price series can have many short-term reversal opportunities that one can exploit, as many traders have discovered. [Chan(2009), p.131]

Ah, então esta história de reversão à médiaestacionaridade, que a gente estuda tem algo a ver, né? Pois é. Chan tem um blog e nem preciso dizer que o livro dele está lá, anunciado. Mas então, veja você, uma estratégia de reversão à média é lucrativa caso a estacionaridade persista. Um par de preços?

Vejamos os dados de fechamento ajustados do Yahoo Finance para duas séries. Você poderia fazer o download das mesmas manualmente, caso saiba os códigos. Vamos usar a Toyota e a Honda no exemplo. Mas, ao invés de usar o pacote quantmod, como no post anterior, vou trazer os dados diretamente do site para o R. Note que, sim, sei os códigos. Para a Toyota é TW e para a Honda, HMC. Dê uma olhada no gráfico das séries (o azul é o TW).

honda_toyota

library(zoo)
library(tseries)

# Veja como eu fiz:
tw <-read.csv("http://ichart.finance.yahoo.com/table.csv?s=TW&ignore=.csv", stringsAsFactors=F)
hmc<-read.csv("http://ichart.finance.yahoo.com/table.csv?s=HMC&ignore=.csv", stringsAsFactors=F)

# veja a cara de um deles.

head(tw)

# agora, note que vou pegar a data e o preço ajustado (última coluna) da Toyota (tw) e da Honda (HMC)
tw <-zoo(tw[,7], as.Date(tw[,1]))
hmc <-zoo(hmc[,7], as.Date(hmc[,1]))

# vou fundir as duas.

jap.zoo <-merge(tw, hmc, all=FALSE)

# qual o período?

cat("Date range is", format(start(jap.zoo)), "to", format(end(jap.zoo)), "\n")

# verifique que o período é: 11 de outubro de 2000 a 01 de junho de 2015.

# Agora vou fazer manualmente a regressão, sem intercepto (por isso o "+ 0").
# Em seguida, pego o coeficiente (o único) e construo o spread.

library(dynlm)
j1 <-dynlm(tw~hmc+0, data=jap.zoo)
summary(j1)

sprd <- jap.zoo$tw - beta*jap.zoo$hmc  # serie menos a serie estimada

# outra forma de fazer isso é simplesmente dizer que:
# sprd <- j$residuals

Repare que o spread é construído como o resíduo da regressão que chamei de “j”. Podemos visualmente perceber que o spread não é estacionário (use o comando plot(sprd)). Um teste de raiz unitária sobre ele mostrará que ele não é estacionário.

Isto foi feito neste post, quando, em meio ao exercício, fiz o teste de raiz unitária de Engle-Granger sobre os resíduos (veja lá). Só para exemplificar, eis duas especificações da equação do teste, com 4 e 12 defasagens (o número de defasagens, aqui, arbitrariamente escolhido, por pura preguiça).

y1<-j1$residuals
summary(dynlm(d(y1)~L(y1,1)+L(d(y1),c(1,2,3,4))))
summary(dynlm(d(y1)~L(y1,1)+L(d(y1),c(1,2,3,4,5,6,7,8,9,10,11,12))))

O restante fica a seu cargo. Lembre-se que este teste tem tabela com valores próprios (o livro-texto de Gujarati & Porter, aquele que você provavelmente usa ou já viu na biblioteca, tem esta tabela).

Anúncios
Uncategorized

Vai de Coca ou de Pepsi – II

Lembra que eu citei o pacote egcm aqui, ano passado? Resolvi dar uma olhada nos dados novamente. Antes de mais nada, chamo a atenção para o fato de que não estou testando modelos de concorrência (para saber se existe um líder e um seguidor neste mercado ou não, como fazem estes autores). Apesar disto, podemos nos perguntar se ambas as variáveis seriam endógenas ou exógenas (além da questão de cointegração pois, afinal, se houver cointegração, podemos testar a exogeneidade fraca).

Apenas para que possamos nos divertir com os dados do Yahoo Finance, vamos usar o preço de fechamento da PEP e COKE. Os dados são diários, iniciando em 03/01/2007 e terminando em 29/05/2015. Podemos supor que a cointegração seja feita sob a hipótese implícita de exogeneidade da Pepsi ou da Coca.

Ah sim, antes de mais nada, este é um exercício simples, então, repare que COKE está na Nasdaq e PEP na NYSE. A Coca está também na NYSE, mas o símbolo, lá, é KO, e o comportamento da série é bem distinto das duas anteriores, por isso não vou usá-la no exemplo.

Apresento os resultados para ambos e o script está aí embaixo.

No gráfico a seguir, o preço de fechamento da Coca é regredido contra o da Pepsi.

cokepepsi

Aqui, o oposto.

pepsicoke

Agora, em nenhum dos dois casos encontramos cointegração. Vejam os resultados. Primeiro, para a Pepsi como exógena:

COKE.Close[i] = 1.0390 PEP.Close[i] – 0.3149 + R[i], R[i] = 0.9952 R[i-1] + eps[i], eps ~ N(0, 0.0183^2)
(0.0186)                          (0.0797)                    (0.0028)

R[2015-05-29] = 0.3004 (t = 2.144)

WARNING: PEP.Close and COKE.Close do not appear to be cointegrated.

Unit Root Tests of Residuals

Statistic p-value
Augmented Dickey Fuller (ADF) -3.332 0.09251
Phillips-Perron (PP) -20.354 0.11355
Pantula, Gonzales-Farias and Fuller (PGFF) 0.992 0.21422
Elliott, Rothenberg and Stock DF-GLS (ERSD) -1.600 0.27192
Johansen’s Trace Test (JOT) -10.991 0.54535
Schmidt and Phillips Rho (SPR) -23.683 0.05867

Variances
SD(diff(PEP.Close)) = 0.011523
SD(diff(COKE.Close)) = 0.019064
SD(diff(residuals)) = 0.018286
SD(residuals) = 0.140131
SD(innovations) = 0.018258

Half life = 143.412600
R[last] = 0.300437 (t=2.14)

Agora para a Coca como exógena.

PEP.Close[i] = 0.5729 COKE.Close[i] + 1.8999 + R[i], R[i] = 0.9954 R[i-1] + eps[i], eps ~ N(0, 0.0125^2)
(0.0103)                           (0.0426)                   (0.0026)

R[2015-05-29] = -0.0421 (t = -0.404)

WARNING: COKE.Close and PEP.Close do not appear to be cointegrated.

PEP.Close[i] = 0.5729 COKE.Close[i] + 1.8999 + R[i], R[i] = 0.9954 R[i-1] + eps[i], eps ~ N(0, 0.0125^2)
(0.0103) (0.0426) (0.0026)

R[2015-05-29] = -0.0421 (t = -0.404)

WARNING: COKE.Close and PEP.Close do not appear to be cointegrated.

Unit Root Tests of Residuals
Statistic p-value
Augmented Dickey Fuller (ADF) -2.923 0.21901
Phillips-Perron (PP) -16.402 0.22808
Pantula, Gonzales-Farias and Fuller (PGFF) 0.992 0.24437
Elliott, Rothenberg and Stock DF-GLS (ERSD) -1.353 0.37424
Johansen’s Trace Test (JOT) -10.991 0.54535
Schmidt and Phillips Rho (SPR) -18.284 0.13898

Variances
SD(diff(COKE.Close)) = 0.019064
SD(diff(PEP.Close)) = 0.011523
SD(diff(residuals)) = 0.012530
SD(residuals) = 0.104053
SD(innovations) = 0.012508

Half life = 148.750521
R[last] = -0.042066 (t=-0.40)

Pois é, gente. Nada de cointegração para a amostra, segundo este método (e nem pelo método de Johansen, não apresentado aqui).

Eis o script:

# Usando dados do YahooFinance e ilustrando a cointegração via Engle-Granger
# com o pacote egcm.
# Além disso, para os testes de raiz unitária, vou usar também o pacote forecast,
# embora o leitor possa checar que o egcm tem opções.

# Para buscar os dados online do YahooFinance, usamod o pacote quantmod.

library("forecast")
library("quantmod")

getQuote("COKE")
head(COKE)
tail(COKE)

getQuote("PEP")
head(PEP)

# Vamos dar uma olhada nos gráficos e em um teste de raiz unitária, o kpss.

plot(log(PEP$PEP.Close))
ndiffs(log(PEP$PEP.Close), test=c("kpss"))

plot(log(COKE$COKE.Close))
ndiffs(log(COKE$COKE.Close),test=c("kpss"))

# Ok, agora ao trabalho.

library("egcm")

# supondo que exista cointegração com Pepsi supostamente exógena.

soda<-egcm(PEP$PEP.Close, COKE$COKE.Close, log=TRUE)
print(soda)
plot(soda)
summary(soda)

# supondo que exista cointegração, com Coca supostamente exógena.

soda1<-egcm(COKE$COKE.Close,PEP$PEP.Close, log=TRUE)
print(soda1)
plot(soda1)
summary(soda1)

UPDATE: Por acaso tive contato com o livro de Chan [Chan, E. (2009) “Quantitative Trading”, John Wiley & Sons] e não é que o autor usa o mesmo exemplo? Só que ele usa o par (KO, PEP). Como falei lá no alto, eu dei uma olhada nestes dados e, sim, eles não cointegram…tal como no exemplo do livro.