In [1]:
options(OutDec = ",") 
#==============================================================================
# Descricao
#==============================================================================
# Os dados a seguir correspondem aos indices diarios da BOVESPA de 3 de
# janeiro de 2011 a 10 de setembro de 2021.
#
# Os dados foram obtidos do sitio http://br.financas.yahoo.com/ 
# 
# Concentraremos nos indices (precos) de fechamento ("Close")
#
#==============================================================================
# Carregando pacotes
#==============================================================================
silence <- suppressPackageStartupMessages # Para omitir mensagens de alertas
silence(library(tseries))      # Teste de Jarque-Bera: 'jarque.bera.test'
silence(library(psych))        # Estatistica descritiva: 'describe'
silence(library(latticeExtra)) # Para construir dois graficos em um so'
In [2]:
#==============================================================================
# Lendo os dados do arquivo BVSP.csv
#==============================================================================
BVSP  <- read.csv("../dados/BVSP.csv",header=TRUE,sep=",")
print(head(BVSP))

# Copiando os indices de fechamento como a serie de precos
preco <- BVSP$Close 
dias  <- as.Date(BVSP$Date) # Dias
n     <- length(preco)      # Numero de observacoes
        Date  Open  High   Low Close Adj.Close  Volume
1 2011-01-03 69310 70471 69305 69962     69962 1862400
2 2011-01-04 69962 70318 69560 70318     70318 2427200
3 2011-01-05 70311 71173 69802 71091     71091 2309200
4 2011-01-06 71093 71167 70469 70579     70579 2546000
5 2011-01-07 70580 70783 69718 70057     70057 1761000
6 2011-01-10 70056 70133 69666 70127     70127 1610800
In [3]:
#==============================================================================
# Grafico da serie de precos
#==============================================================================
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.5,lab=c(15,5,5),
    mar=c(5,5,2,2.5),xpd=T,cex.main=2.0,bty="n")
plot(dias,preco/1000,lwd=2,type="l",col="black",main="",xlab="Dias",
    ylab="Preço (milhares)",ylim=c(20,140),
    xlim=c(as.Date("2011-01-01"),as.Date("2021-12-31")))
No description has been provided for this image
In [4]:
#==============================================================================
# Calculando o retorno de capitalizacao continua, ou simplesmente log-retorno
#==============================================================================
rt <- diff(log(preco))  # Calcula a primeira diferenca
In [5]:
# Grafico da serie de log retornos: r_t = log(1+R_t) = log(P_t)-log(P_{t-1})
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.4,lab=c(15,5,5),
    mar=c(5,5,2,2.5),xpd=T,cex.main=2.0,bty="n")
plot(dias[2:n],rt,lwd=2,col="black",main="",xlab="Dias",ylab="Log Retorno",
    type="l",xlim=c(as.Date("2011-01-01"),as.Date("2021-12-31")),
    ylim=c(-0.16,0.16))
No description has been provided for this image
In [6]:
#==============================================================================
# A serie de precos e log retornos em um unico grafico
#==============================================================================
obj1  <- xyplot(rt    ~ dias,type="l",lwd=2,col=1,xlab="Dias",
    ylab="Log Retorno")
obj2  <- xyplot(preco ~ dias,type="l",lwd=2,col="red",ylab="Preços")
doubleYScale(obj1,obj2,add.ylab2=TRUE,use.style=FALSE)
No description has been provided for this image
In [7]:
#==============================================================================
# Grafico da serie de log retornos ao quadrado
#==============================================================================
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.5,lab=c(15,5,5),
    mar=c(5,5,2,2.5),xpd=T,cex.main=2.0,bty="n")
plot(dias[2:n],rt^2,lwd=2,col=1,main="",xlab="Dias",
    ylab="Log Retorno ao Quadrado",type="l",
    xlim=c(as.Date("2011-01-01"),as.Date("2021-12-31")))
No description has been provided for this image
In [8]:
#==============================================================================
# ACF dos log retornos
#==============================================================================
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.5,lab=c(10,5,5),
     mar=c(5,5,2,2.5),cex.main=2.0,bty="n")
acf(rt,lwd=2,col=1,lag.max=16,xlab="Defasagem",main="",ylim=c(-0.2,1))
No description has been provided for this image
In [9]:
#==============================================================================
# ACF dos log retornos ao quadrado
#==============================================================================
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.5,lab=c(10,5,5),
     mar=c(5,5,2,2.5),cex.main=2.0,bty="n")
acf(rt^2,lwd=2,col=1,lag.max=16,xlab="Defasagem",main="",ylim=c(-0.2,1))
No description has been provided for this image
In [10]:
options(digits=4)
r.describe      <- describe(rt)
r.media         <- r.describe[,3]
r.desvpad       <- r.describe[,4]
r.mediana       <- r.describe[,5]
r.assimetria    <- r.describe[,11]
r.exc.curtose   <- r.describe[,12]
STATS           <- cbind(r.media,r.desvpad,r.mediana,r.assimetria,
                       r.exc.curtose)
colnames(STATS) <- c("media","desvpad","mediana","assimetria","exc.curt")                       
rownames(STATS) <- "IBOVESPA"
print(STATS)
             media desvpad   mediana assimetria exc.curt
IBOVESPA 0,0001878 0,01616 0,0003192    -0,8946    12,23
In [11]:
#==============================================================================
# Histograma dos log retornos
#==============================================================================
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.5,lab=c(12,5,5),
    mar=c(5,5,2,2.5),xpd=T,cex.main=2.0,bty="n")
hist(rt,lwd=2,col=0,main="",xlab="Log Retornos",ylab="Densidade",prob=T,
    nclass=50,xlim=c(-0.17,0.17))
xseq <- seq(r.media-7*r.desvpad,r.media+7*r.desvpad,length=1000)
yseq <- dnorm(xseq,r.media,r.desvpad)
lines(xseq,yseq,lwd=3,col="red")
text(-0.09,25,"Certamente não normal",cex=1.2)
No description has been provided for this image
In [12]:
#==============================================================================
# Boxplot dos log retornos
#==============================================================================
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.5,lab=c(10,5,5),
    mar=c(5,5,2,2.5),xpd=T,cex.main=2.0,bty="n")
boxplot(rt,lwd=2,col="red",main="",ylab="Log Retornos",pch=16,
    ylim=c(-0.2,0.2))
No description has been provided for this image
In [13]:
#==============================================================================
# Normal QQ-plot dos log retornos
#==============================================================================
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.5,lab=c(10,5,5),
    mar=c(5,5,2,2.5),xpd=T,cex.main=2.0,bty="n")
qqnorm(rt,lwd=2,col="red",main="",xlab="Quantis teóricos",
    ylab="Quantis amostrais",pch=16,xlim=c(-4,4),ylim=c(-0.2,0.2))
qqline(rt,lwd=2,col="black",xlim=c(-4,4),xpd=F)
No description has been provided for this image
In [14]:
#==============================================================================
# Testando a hipotese de distribuicao normal para os log retornos
#==============================================================================
# Lembre-se de verificar de novo a assimetria e a curtose 
print(STATS[1,4:5])
print("========================")

# Nivel de significancia dos testes
alpha <- 0.05
N     <- length(rt) # Tamanho da serie de log retornos

# Testando a assimetria zero
print("Teste de assimetria")
tSr      <- STATS[1,4]/sqrt(6/N)   # Razao t-Student
print(abs(tSr) > qnorm(1-alpha/2)) # Testanto (TRUE=Rejeitar, FALSE=Nao rejeitar) 
valorpSr <- 2*(1-pnorm(abs(tSr)))  # Valor p 
print(valorpSr)
print("========================")

# Testando a excesso de curtose zero
print("Teste de curtose")
tKr      <- STATS[1,5]/sqrt(24/N)  # Razao t-Student
print(abs(tKr) > qnorm(1-alpha/2)) # Testanto (TRUE=Rejeitar, FALSE=Nao rejeitar)
valorpKr <- 2*(1-pnorm(abs(tKr)))  # Valor p 
print(valorpKr)
print("========================")

# Testando a normalidade - teste de Jarque Bera
print("Teste de Jarque-Bera: normalidade")
JB    <- tSr^2 + tKr^2
print(JB  >  qchisq(1-alpha,2)) # Testanto (TRUE=Rejeitar, FALSE=Nao rejeitar)
print(jarque.bera.test(rt))     # Verificar o valor p (mesma conclusao)
assimetria   exc.curt 
   -0,8946    12,2347 
[1] "========================"
[1] "Teste de assimetria"
[1] TRUE
[1] 0
[1] "========================"
[1] "Teste de curtose"
[1] TRUE
[1] 0
[1] "========================"
[1] "Teste de Jarque-Bera: normalidade"
[1] TRUE

	Jarque Bera Test

data:  rt
X-squared = 16677, df = 2, p-value <2e-16

In [15]:
#==============================================================================
# Teste para efeitos ARCH 
#==============================================================================
# Passo 1 em nossa analise
#==============================================================================
# Vimos pela ACF dos retornos uma coorelacao serial fraca. 
# Teste de Ljung-Box para os retornos
# Lembre-se da hipotese nula (H_0): independencia dos retornos 

ell <- floor(log(N)) # ell =~ log(N) como valor mais pratico
print(ell)
for(i in 1:ell) 
    print(Box.test(rt, lag = i, type = "Ljung-Box"))

# Conclusao: rejeitamos a hipotese nula de independencia dos retornos.
# Precisamos modelar a media. Utilizaremos um modelo AR.
[1] 7

	Box-Ljung test

data:  rt
X-squared = 26, df = 1, p-value = 4e-07


	Box-Ljung test

data:  rt
X-squared = 31, df = 2, p-value = 2e-07


	Box-Ljung test

data:  rt
X-squared = 31, df = 3, p-value = 7e-07


	Box-Ljung test

data:  rt
X-squared = 32, df = 4, p-value = 2e-06


	Box-Ljung test

data:  rt
X-squared = 41, df = 5, p-value = 8e-08


	Box-Ljung test

data:  rt
X-squared = 55, df = 6, p-value = 4e-10


	Box-Ljung test

data:  rt
X-squared = 75, df = 7, p-value = 1e-13

In [16]:
#==============================================================================
# Passo 2 em nossa analise
#==============================================================================
# Ajuste de um modelo AR

r.ar <- ar.mle(rt)
p    <- r.ar$order
a    <- r.ar$res[(p+1):N] # residuos nao padronizados
n2   <- length(a)    
print(r.ar) # O melhor modelo foi um AR(10) segundo o AIC
Call:
ar.mle(x = rt)

Coefficients:
     1       2       3       4       5       6       7       8       9      10  
-0,085   0,032   0,006  -0,013   0,045  -0,054   0,069  -0,026   0,025   0,041  

Order selected 10  sigma^2 estimated as  0,000254
In [17]:
#==============================================================================
# Verificando a ACF dos log retornos
#==============================================================================
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.5,lab=c(10,5,5),
     mar=c(5,5,2,2.5),cex.main=2.0,bty="n")
acf(a,xlab="Defasagem",main="",lwd=2,col=1,lag.max=15,ylim=c(-0.2,1))
No description has been provided for this image
In [18]:
#==============================================================================
# Calculando varios momentos amostrais dos residuos padronizados 
# do modelo AR(10)
#==============================================================================
options(digits=4)
sigma2          <- r.ar$var        # variancia do erro estimada
sigma           <- sqrt(sigma2)    # desvio padrao do erro estimado
resid           <- a/sigma         # residuos padronizados
r.describe      <- describe(resid)
r.media         <- r.describe[,3]
r.desvpad       <- r.describe[,4]
r.mediana       <- r.describe[,5]
r.assimetria    <- r.describe[,11]
r.exc.curtose   <- r.describe[,12]
STATS           <- cbind(r.media,r.desvpad,r.mediana,r.assimetria,
                       r.exc.curtose)
colnames(STATS) <- c("media","desvpad","mediana","assimetria","exc.curt")
rownames(STATS) <- "IBOVESPA"  
print(STATS)

# Se os erros forem normais, entao os residuos devem ter
# media e mediana 0 (zero), desvio padrao 1 (um), 
# assimetria 0 (zero) e excesso de curtose 0 (zero).
# Possivelmente a presenca de nao normalidade.
              media desvpad   mediana assimetria exc.curt
IBOVESPA -0,0002323   1,002 0,0007451    -0,7339    10,34
In [19]:
#==============================================================================
# Passo 3 em nossa analise
#==============================================================================
# Teste de Ljung-Box para os residuos (resid) do modelo AR(10)
# Lembre-se da hipotese nula (H_0): independencia dos residuos

for(i in (p+1):(p+ell+1)) 
    print(Box.test(resid, lag = i, type = "Ljung-Box",fitdf = p))

# Agora, os p-valores sao todos grandes. 
# Conclusao: nao rejeitamos a hipotese nula de independencia dos residuos
	Box-Ljung test

data:  resid
X-squared = 1,4, df = 1, p-value = 0,2


	Box-Ljung test

data:  resid
X-squared = 1,5, df = 2, p-value = 0,5


	Box-Ljung test

data:  resid
X-squared = 5,1, df = 3, p-value = 0,2


	Box-Ljung test

data:  resid
X-squared = 7,2, df = 4, p-value = 0,1


	Box-Ljung test

data:  resid
X-squared = 7,3, df = 5, p-value = 0,2


	Box-Ljung test

data:  resid
X-squared = 10, df = 6, p-value = 0,1


	Box-Ljung test

data:  resid
X-squared = 10, df = 7, p-value = 0,2


	Box-Ljung test

data:  resid
X-squared = 13, df = 8, p-value = 0,1

In [20]:
#==============================================================================
# Passo 4 em nossa analise
#==============================================================================
# Teste para efeitos ARCH
# Teste de Ljung-Box para os residuos ao quadrado do modelo AR(10)
# Lembre-se da hipotese nula (H_0): independencia dos residuos ao quadrado

resid2 <- resid^2
for(i in 1:ell)
    print(Box.test(resid2, lag = i, type = "Ljung-Box"))

# Os p-valores sao todos pequenos.
# Conclusao: rejeitamos a hipotese nula de independencia dos residuos 
# ao quadrado.
	Box-Ljung test

data:  resid2
X-squared = 424, df = 1, p-value <2e-16


	Box-Ljung test

data:  resid2
X-squared = 882, df = 2, p-value <2e-16


	Box-Ljung test

data:  resid2
X-squared = 1159, df = 3, p-value <2e-16


	Box-Ljung test

data:  resid2
X-squared = 1351, df = 4, p-value <2e-16


	Box-Ljung test

data:  resid2
X-squared = 1504, df = 5, p-value <2e-16


	Box-Ljung test

data:  resid2
X-squared = 1530, df = 6, p-value <2e-16


	Box-Ljung test

data:  resid2
X-squared = 1738, df = 7, p-value <2e-16

In [21]:
#==============================================================================
# Verificando a ACF dos retornos ao quadrado
#==============================================================================
par(mfrow=c(1,1),lwd=2.0,cex.lab=1.5,cex.axis=1.5,lab=c(10,5,5),
     mar=c(5,5,2,2.5),cex.main=2.0,bty="n")
acf(resid2,xlab="Defasagem",main="",lwd=2,col=1,lag.max=16,ylim=c(-0.2,1))
No description has been provided for this image