Podemos notar que fora a série calcário que já é estacionária em nível as demais séries apresentam raiz unitária, ao calcular a primeira diferença todas se apresentam estacionárias.
A presença de tendência e sazonalidade pode ser observada na decomposição da série em todas as séries. Consequentemente, é aconselhável empregar o comando auto.sarima para verificar a determinação do modelo na explicação da série.
Curiosamente o auto.arima determina primeira diferença para o calcario que já é estacionário em primeira ordem como observado pelo teste ADF. O metodo de Bai_perron será empregado para determinar a existência de quebra estrutural.
#cimento
ts_cimento <- ts(ts_cimento, start = c(1979, 12), frequency = 12)
summary(ur.za((ts_cimento), model = c("both"), lag = NULL))
##
## ################################
## # Zivot-Andrews Unit Root Test #
## ################################
##
##
## Call:
## lm(formula = testmat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -140.829 -4.421 -0.528 4.643 86.979
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -10.25975 3.33100 -3.080 0.00224 **
## y.l1 0.87524 0.02193 39.918 < 2e-16 ***
## trend 0.39044 0.07220 5.408 1.20e-07 ***
## du -23.71999 4.38255 -5.412 1.17e-07 ***
## dt -0.34571 0.07041 -4.910 1.41e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 15.4 on 343 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.9569, Adjusted R-squared: 0.9564
## F-statistic: 1902 on 4 and 343 DF, p-value: < 2.2e-16
##
##
## Teststatistic: -5.6901
## Critical values: 0.01= -5.57 0.05= -5.08 0.1= -4.82
##
## Potential break point at position: 121
#calcario
ts_calcario <- ts(ts_calcario, start = c(1979, 12), frequency = 12)
summary(ur.za((ts_calcario), model = c("both"), lag = NULL))
##
## ################################
## # Zivot-Andrews Unit Root Test #
## ################################
##
##
## Call:
## lm(formula = testmat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -45.372 -1.976 -0.362 1.927 36.203
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 12.03281 2.04169 5.894 9.04e-09 ***
## y.l1 0.78174 0.03285 23.798 < 2e-16 ***
## trend 0.11637 0.02261 5.147 4.47e-07 ***
## du -4.85195 1.40760 -3.447 0.000637 ***
## dt -0.07513 0.01955 -3.842 0.000145 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 5.736 on 343 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.9404, Adjusted R-squared: 0.9397
## F-statistic: 1354 on 4 and 343 DF, p-value: < 2.2e-16
##
##
## Teststatistic: -6.6443
## Critical values: 0.01= -5.57 0.05= -5.08 0.1= -4.82
##
## Potential break point at position: 123
#diesel
ts_diesel <- ts(ts_diesel, start = c(1979, 12), frequency = 12)
summary(ur.za((ts_diesel), model = c("both"), lag = NULL))
##
## ################################
## # Zivot-Andrews Unit Root Test #
## ################################
##
##
## Call:
## lm(formula = testmat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -91.664 -5.037 -0.957 3.839 70.550
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 27.69641 6.59503 4.200 3.41e-05 ***
## y.l1 0.86496 0.02239 38.628 < 2e-16 ***
## trend 0.33119 0.11724 2.825 0.00501 **
## du -31.98726 6.00292 -5.329 1.80e-07 ***
## dt -0.32191 0.11833 -2.720 0.00685 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 16.5 on 343 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.9401, Adjusted R-squared: 0.9394
## F-statistic: 1345 on 4 and 343 DF, p-value: < 2.2e-16
##
##
## Teststatistic: -6.0307
## Critical values: 0.01= -5.57 0.05= -5.08 0.1= -4.82
##
## Potential break point at position: 65
#combustivel
ts_combustivel <- ts(ts_combustivel, start = c(1979, 12), frequency = 12)
summary(ur.za((ts_combustivel), model = c("both"), lag = NULL))
##
## ################################
## # Zivot-Andrews Unit Root Test #
## ################################
##
##
## Call:
## lm(formula = testmat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -63.578 -4.475 -0.975 3.483 47.451
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 21.51981 4.94734 4.350 1.80e-05 ***
## y.l1 0.89373 0.02338 38.234 < 2e-16 ***
## trend -0.04991 0.01506 -3.314 0.001018 **
## du 11.72512 2.95163 3.972 8.67e-05 ***
## dt 0.19311 0.05816 3.320 0.000996 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 10.74 on 343 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.979, Adjusted R-squared: 0.9788
## F-statistic: 4006 on 4 and 343 DF, p-value: < 2.2e-16
##
##
## Teststatistic: -4.5464
## Critical values: 0.01= -5.57 0.05= -5.08 0.1= -4.82
##
## Potential break point at position: 231
O cimento é estacionário com um nível de confiança de 1% e apresenta uma quebra estrutural em dezembro de 1989. Essa data específica está dentro do prazo indicado pelo CADE como o início do cartel, conforme evidenciado por documentos de reuniões realizadas entre 1987 e 1989 entre as cimenteiras. O calcário, por outro lado, também permanece estacionário, mas sofre uma ruptura em fevereiro de 1990, dois meses após a ocorrência no cimento. Essa discrepância pode sugerir que a quebra foi atribuída aos custos de produção e não ao próprio cartel. O diesel, da mesma forma, permanece estacionário e sofre uma quebra em abril de 1985, aparentemente desconectado da fratura no cimento. Ao contrário, a série envolvendo combustível não é estacionária com um nível de confiança de 10% e se rompe em fevereiro de 1999, aparentemente sem relação com a quebra no cimento. Em conclusão, embora a quebra no cimento esteja dentro do período em análise, ela poderia ser explicada pela quebra do calcário, um dos componentes utilizados em sua produção. Uma investigação mais meticulosa poderia fornecer informações sobre se uma pode realmente ser explicada pela outra, e isso deve ser prosseguido. Pois apesar de ambas as quebras ocorrerem, a proximidade das quebras em termos de tempo não implica necessariamente uma relação causal.
# Create a data frame for ggplot
df <- data.frame(date = as.Date(time(ts_cimento)), ts_cimento = as.vector(ts_cimento), ts_calcario = as.vector(ts_calcario))
# Subset the data to the desired time period (1987 to 1990)
df_subset <- subset(df, date >= as.Date("1987-01-01") & date <= as.Date("1990-12-31"))
ggplot(df_subset, aes(x = date)) +
geom_line(aes(y = ts_cimento, color = "ts_cimento"), size = 1) +
geom_line(aes(y = ts_calcario, color = "ts_calcario"), size = 1) +
labs(title = "Time Series Plot", x = "Date", y = "Value") +
scale_color_manual(name = "Series", values = c("ts_cimento" = "blue", "ts_calcario" = "red")) +
theme_minimal() +
geom_vline(xintercept = as.Date("1989-12-01"), linetype = "dashed", color = "blue") +
geom_vline(xintercept = as.Date("1990-02-01"), linetype = "dashed", color = "red")
Eu executo esse esquema com a intenção de atingir dois objetivos: Verificar se as quebras ocorrem na mesma orientação e determinar o grau de proporcionalidade. Deduzo que, apesar da ocorrência de intervalos de tempo comparáveis, não há evidências aparentes que sugiram que uma quebra cause a outra. Consequentemente, deve existir um fator exógeno adicional que contribua para esse fenômeno. Outra questão fundamental é que a quebra é negativa, o que não corresponde as ações esperadas do cartel divulgadas pelo CADE.
ur.ls <- function(y, model = c("crash", "break"), breaks = 1, lags = NULL, method = c("GTOS","Fixed"), pn = 0.1, print.results = c("print", "silent")){
#Starttime
starttime <- Sys.time()
#Check sanity of the function call
if (any(is.na(y)))
stop("\nNAs in y.\n")
y <- as.vector(y)
if(pn >= 1 || pn <= 0){
stop("\n pn has to be between 0 and 1.")
}
if(method == "Fixed" && is.null(lags) == TRUE){
stop("\n If fixed lag length should be estimated, the number
\n of lags to be included should be defined explicitely.")
}
#Add lagmatrix function
lagmatrix <- function(x,max.lag){
embed(c(rep(NA,max.lag),x),max.lag+1)
}
#Add diffmatrix function
diffmatrix <- function(x,max.diff,max.lag){
#Add if condition to make it possible to differentiate between matrix and vector
if(is.vector(x) == TRUE ){
embed(c(rep(NA,max.lag),diff(x,max.lag,max.diff)),max.diff)
}
else if(is.matrix(x) == TRUE){
rbind(matrix(rep(NA,max.lag), ncol = ncol(x)), matrix(diff(x,max.lag,max.diff), ncol = ncol(x)))
}
#if matrix the result should be 0, if only a vector it should be 1
else if(as.integer(is.null(ncol(x))) == 0 ){
rbind(matrix(rep(NA,max.lag), ncol = ncol(x)), matrix(diff(x,max.lag,max.diff), ncol = ncol(x)))
}
}
#Number of observations
n <- length(y)
model <- match.arg(model)
lags <- as.integer(lags)
method <- match.arg(method)
breaks <- as.integer(breaks)
#Percentage to eliminate endpoints in the lag calculation
pn <- pn
#Critical Values for the one break test
model.one.crash.cval <- matrix(c(-4.239, -3.566, -3.211)
, nrow = 1, ncol = 3, byrow = TRUE)
colnames(model.one.crash.cval) <- c("1%","5%","10%")
model.one.break.cval <- matrix(c(.1 , -5.11, -4.5, -4.21,
.2 , -5.07, -4.47, -4.20,
.3 , -5.15, -4.45, -4.18,
.4 , -5.05, -4.50, -4.18,
.5 , -5.11, -4.51, -4.17), nrow = 5, ncol = 4, byrow = TRUE)
colnames(model.one.break.cval) <- c("lambda","1%","5%","10%")
# All critical values were derived in samples of size T = 100. Critical values
# in Model C (intercept and trend break) depend (somewhat) on the location of the
# break (λ = T_B /T) and are symmetric around λ and (1-λ). Model C critical values
# at additional break locations can be interpolated.
#
# Critical values for the endogenous two break test
# Model A - "crash" model
# invariant to the location of the crash
model.two.crash.cval <- matrix(c("LM_tau", -4.545, -3.842, -3.504,
"LM_rho", -35.726, -26.894, -22.892), nrow = 2, ncol = 4, byrow = TRUE )
colnames(model.two.crash.cval) <- c("Statistic","1%","5%","10%")
# Model C (i) - "break" model, breaks in the data generating process
# Model C (i) - "break" model invariant to the location of the crash
model.two.break.dgp.cval <- matrix(c("LM_tau", -5.823, -5.286, -4.989,
"LM_rho", -52.550, -45.531, -41.663), nrow = 2, ncol = 4, byrow = TRUE )
# Model C (ii) - "break" model, breaks are not considered in the data generating process
# Model C (ii) - "break" model depends on the location of the crash
## highest level of list is the location of the second breakpoint - so the share inside
## the matrix refers to the first breakpoint
model.two.break.tau.cval <- matrix(c( -6.16, -5.59, -5.27, -6.41, -5.74, -5.32, -6.33, -5.71, -5.33,
NA , NA, NA , -6.45, -5.67, -5.31, -6.42, -5.65, -5.32,
NA , NA, NA , NA , NA , NA , -6.32, -5.73, -5.32)
, nrow = 3, ncol = 9, byrow = TRUE )
rownames(model.two.break.tau.cval) <- c("Break 1 - 0.2", "Break 1 - 0.4", "Break 1 - 0.6")
colnames(model.two.break.tau.cval) <- c("Break 2 - 0.4 - 1%", "Break 2 - 0.4 - 5%", "Break 2 - 0.4 - 10%",
"Break 2 - 0.6 - 1%", "Break 2 - 0.6 - 5%", "Break 2 - 0.6 - 10%",
"Break 2 - 0.8 - 1%", "Break 2 - 0.8 - 5%", "Break 2 - 0.8 - 10%")
model.two.break.rho.cval <- matrix(c( -55.4 , -47.9, -44.0, -58.6, -49.9, -44.4, -57.6, -49.6, -44.6,
NA , NA, NA ,-59.3, -49.0, -44.3, -58.8, -48.7, -44.5,
NA , NA, NA , NA , NA , NA ,-57.4, -49.8, -44.4)
, nrow = 3, ncol = 9, byrow = TRUE )
rownames(model.two.break.rho.cval) <- c("Break 1 - 0.2", "Break 1 - 0.4", "Break 1 - 0.6")
colnames(model.two.break.rho.cval) <- c("Break 2 - 0.4 - 1%", "Break 2 - 0.4 - 5%", "Break 2 - 0.4 - 10%",
"Break 2 - 0.6 - 1%", "Break 2 - 0.6 - 5%", "Break 2 - 0.6 - 10%",
"Break 2 - 0.8 - 1%", "Break 2 - 0.8 - 5%", "Break 2 - 0.8 - 10%")
#Number of observations to eliminate in relation to the sample length
pnnobs <- round(pn*n)
#Define the start values
startl <- 0
myBreakStart <- startl + 1 + pnnobs
myBreakEnd <- n - pnnobs
#Calculate Dy
y.diff <- diffmatrix(y, max.diff = 1, max.lag = 1)
#Calculation
#trend for 1:n like in ur.sp
trend <- 1:n
#Define minimum gap between the two possible break dates.
#the gap is 2 in the crash case and 3 periods in the case of a break model
gap <- 2 + as.numeric(model == "break")
myBreaks <- matrix(NA, nrow = n - 2 * pnnobs, ncol = breaks)
if(breaks == 1){
myBreaks [,1] <- myBreakStart:myBreakEnd
} else if (breaks == 2){
myBreaks[, 1:breaks] <- cbind(myBreakStart:myBreakEnd,(myBreakStart:myBreakEnd)+gap)
}
#Define the variables to hold the minimum t-stat
tstat <- NA
mint <- 1000
tstat.matrix <- matrix(NA, nrow = n, ncol = n )
tstat.result <- matrix()
#Create lists to store the results
#Lists for the one break case
result.reg.coef <- list()
result.reg.resid <- list()
result.matrix <- list()
#Function to analyze the optimal lags to remove autocorrelation from the residuals
#Lag selection with general to specific procedure based on Ng,Perron (1995)
myLagSelection <- function(y.diff, S.tilde, datmat, pmax, Dummy.diff){
n <- length(y.diff)
# General to specific approach to determine the lag which removes autocorrelation from the residuals
# Ng, Perron 1995
qlag <- pmax
while (qlag >= 0) {
# Define optimal lags to include to remove autocorrelation from the residuals
# select p.value of the highest lag order and check if significant
#test.coef <- coef(summary(lm(y.diff ~ 0 + lagmatrix(S.tilde,1)[,-1] + datmat[,-1][, 1:(qlag + 1)] + Dummy.diff)))
#lm.fit implementation
test.reg.data <- na.omit(cbind(y.diff,lagmatrix(S.tilde,1)[,-1], datmat[,-1][, 1:(qlag + 1)], Dummy.diff))
test.reg.lm. <-(lm.fit(x = test.reg.data[,-1], y = test.reg.data[, 1]))
df.lm.fit <- length(test.reg.data[,1]) - test.reg.lm.$qr$rank
sigma2 <- sum((test.reg.data[,1] - test.reg.lm.$fitted.values)^2)/df.lm.fit
varbeta <- sigma2 * chol2inv(qr.R(test.reg.lm.$qr), size = ncol(test.reg.data) -2)
SE <- sqrt(diag(varbeta))
tstat <- na.omit(coef(test.reg.lm.))/SE
pvalue <- 2* pt(abs(tstat), df = df.lm.fit, lower.tail = FALSE)
# print(test.coef)
# print(paste("lm result:",qlag,test.coef[qlag + 1 , 4]))
# print(paste("lm.fit:",qlag,pvalue[qlag+1]))
# print(c("Number of qlag",qlag))
if(pvalue[qlag+1] <= 0.1){
slag <- qlag
# print("break")
break
}
qlag <- qlag - 1
slag <- qlag
}
# print(slag)
return(slag)
}
# Function to calculate the test statistic and make the code shorter, because the function can be used in both cases for
# the one break as well as the two break case
myLSfunc <- function(Dt, DTt, y.diff, est.function = c("estimation","results")){
Dt.diff <- diffmatrix(Dt, max.diff = 1, max.lag = 1)
DTt.diff <- diffmatrix(DTt, max.diff = 1, max.lag = 1)
S.tilde <- 0
S.tilde <- c(0, cumsum(lm.fit(x = na.omit(cbind(Dt.diff[,])), y=na.omit(y.diff))$residuals))
S.tilde.diff <- diffmatrix(S.tilde,max.diff = 1, max.lag = 1)
# Define optimal lags to include to remove autocorrelation
# max lag length pmax to include is based on Schwert (1989)
pmax <- min(round((12*(n/100)^0.25)),lags)
# Create matrix of lagged values of S.tilde.diff from 0 to pmax
# and check if there is autocorrelation if all these lags are included and iterate down to 1
datmat <- matrix(NA,n, pmax + 2)
datmat[ , 1] <- S.tilde.diff
# Add column of 0 to allow the easy inclusion of no lags into the test estimation
datmat[ , 2] <- rep(0, n)
if(pmax > 0){
datmat[, 3:(pmax + 2) ] <- lagmatrix(S.tilde.diff, pmax)[,-1]
colnames(datmat) <- c("S.tilde.diff", "NoLags", paste("S.tilde.diff.l",1:pmax, sep = ""))
} else if(lags == 0){
colnames(datmat) <- c("S.tilde.diff", "NoLags")
}
if(method == "Fixed"){
slag <- lags
} else if(method == "GTOS"){
slag <- NA
if(model == "crash"){
slag <- myLagSelection(y.diff, S.tilde, datmat, pmax, Dt.diff)
} else if(model == "break"){
slag <- myLagSelection(y.diff, S.tilde, datmat, pmax, DTt.diff)
}
}
S.tilde <- NA
if(model == "crash"){
S.tilde <- c(0, cumsum(lm.fit(x = na.omit(cbind(Dt.diff[,])), y=na.omit(y.diff))$residuals))
S.tilde.diff <- diffmatrix(S.tilde, max.diff = 1, max.lag = 1)
#Add lag of S.tilde.diff to control for autocorrelation in the residuals
if(est.function == "results"){
break.reg <- summary(lm(y.diff ~ 0 + lagmatrix(S.tilde, 1)[,-1] + datmat[,2:(slag+2)] + Dt.diff))
} else if (est.function == "estimation"){
#lm.fit() implementation
roll.reg.data <- na.omit(cbind(y.diff, lagmatrix(S.tilde,1)[,-1], datmat[,2:(slag+2)], Dt.diff))
roll.reg.lm. <- lm.fit(x = roll.reg.data[,-1], y = roll.reg.data[, 1])
df.lm.fit <- length(roll.reg.data[, 1]) - roll.reg.lm.$qr$rank
sigma2 <- sum((roll.reg.data[, 1] - roll.reg.lm.$fitted.values)^2)/df.lm.fit
varbeta <- sigma2*chol2inv(qr.R(roll.reg.lm.$qr), size = ncol(roll.reg.data) - 2)
SE <- sqrt(diag(varbeta))
tstat.lm.fit <- na.omit(coef(roll.reg.lm.))/SE
pvalue <- 2 * pt(abs(tstat.lm.fit),df = df.lm.fit, lower.tail = FALSE)
coef.roll.reg.lm <- cbind(na.omit(coef(roll.reg.lm.)), SE, tstat.lm.fit, pvalue)
tstat.lm.fit <- tstat.lm.fit[1]
# tstat.lm <- coef(break.reg)[1,3]
return(coef.roll.reg.lm)
}
# print(paste("lm.fit", tstat.lm.fit[1]))
# print(paste("lm", tstat.lm))
#print(roll.reg)
if(est.function == "estimation"){
return(coef.roll.reg.lm)
} else if(est.function == "results"){
return(break.reg)
}
} else if(model =="break"){
S.tilde <- c(0, cumsum(lm.fit(x = na.omit(cbind(DTt.diff[,])), y=na.omit(y.diff))$residuals))
S.tilde.diff <- diffmatrix(S.tilde, max.diff = 1, max.lag = 1)
#Add lag of S.tilde.diff to control for autocorrelation in the residuals
if(est.function == "results"){
break.reg <- summary(lm(y.diff ~ 0 + lagmatrix(S.tilde,1)[,-1] + datmat[,2:(slag+2)] + DTt.diff))
} else if (est.function == "estimation"){
#lm.fit() implementation
roll.reg.data <- na.omit(cbind(y.diff, lagmatrix(S.tilde,1)[,-1], datmat[,2:(slag+2)], DTt.diff))
roll.reg.lm. <- lm.fit(x = roll.reg.data[,-1], y = roll.reg.data[, 1])
df.lm.fit <- length(roll.reg.data[, 1]) - roll.reg.lm.$qr$rank
sigma2 <- sum((roll.reg.data[, 1] - roll.reg.lm.$fitted.values)^2)/df.lm.fit
varbeta <- sigma2*chol2inv(qr.R(roll.reg.lm.$qr), size = ncol(roll.reg.data) -2)
SE <- sqrt(diag(varbeta))
tstat.lm.fit <- na.omit(coef(roll.reg.lm.))/SE
pvalue <- 2 * pt(abs(tstat.lm.fit),df = df.lm.fit, lower.tail = FALSE)
coef.roll.reg.lm <- cbind(na.omit(coef(roll.reg.lm.)), SE, tstat.lm.fit, pvalue)
tstat.lm.fit <- tstat.lm.fit[1]
return(coef.roll.reg.lm)
# tstat.lm <- coef(break.reg)[1,3]
}
#Return Value
#print(roll.reg)
#print(paste("lm.fit", tstat.lm.fit))
#print(paste("lm", tstat.lm))
#print("break")
if(est.function == "estimation"){
return(coef.roll.reg.lm)
} else if(est.function == "results"){
return(break.reg)
}
}
# print(roll.reg)
if(est.function == "estimation"){
return(coef.roll.reg.lm)
} else if(est.function == "results"){
return(break.reg)
}
}
# Start of the actual function call
if(breaks == 1)
{
# Function to calculate the rolling t-stat
# One Break Case
for(myBreak1 in myBreaks[,1]){
#Dummies for one break case
Dt1 <- as.matrix(cbind(trend, trend >= (myBreak1 + 1)))
# Dummy with break in intercept and in trend
DTt1 <- as.matrix(cbind(Dt1, c(rep(0, myBreak1), 1:(n - myBreak1))))
colnames(Dt1) <- c("Trend","D")
colnames(DTt1) <- c("Trend","D","DTt")
#print(paste("Break1: ",myBreak1, sep = ""))
#Combine all Dummies into one big matrix to make it easier to include in the regressions
Dt <- cbind(Dt1)
DTt <- cbind(DTt1)
result.reg <- myLSfunc(Dt, DTt, y.diff, est.function = c("estimation"))
#Extract the t-statistic and if it is smaller than all previous
#t-statistics replace it and store the values of all break variables
#Extract residuals and coefficients and store them in a list
#result.matrix[[myBreak1]] <- result.reg
#result.reg.coef[[myBreak1]] <- coefficients(result.reg)
tstat <- result.reg[1,3]
tstat.result[myBreak1] <- result.reg[1,3]
#print(tstat)
if(tstat < mint){
mint <- tstat
mybestbreak1 <- myBreak1
}
}#End of first for loop
} else if(breaks == 2) {
## Two Break Case
#First for loop for the two break case
for(myBreak1 in myBreaks[,1]){
#Dummies for one break case
Dt1 <- as.matrix(cbind(trend, trend >= (myBreak1 + 1)))
# Dummy with break in intercept and in trend
DTt1 <- as.matrix(cbind(Dt1, c(rep(0, myBreak1), 1:(n - myBreak1))))
colnames(Dt1) <- c("Trend","D")
colnames(DTt1) <- c("Trend","D","DTt")
#print(paste("Break1: ",myBreak1, sep = ""))
#Second for loop for the two break case
for(myBreak2 in myBreaks[which(myBreaks[,2] < myBreakEnd & myBreaks[,2] >= myBreak1 + gap),2]){
#Dummies for two break case
Dt2 <- as.matrix(trend >= (myBreak2 + 1))
DTt2 <- as.matrix(cbind(Dt2, c(rep(0, myBreak2), 1:(n - myBreak2))))
colnames(Dt2) <- c("D2")
colnames(DTt2) <- c("D2","DTt2")
#print(paste("Break2: ",myBreak2, sep = ""))
#Combine all Dummies into one big matrix to make it easier to include in the regressions
Dt <- cbind(Dt1, Dt2)
DTt <- cbind(DTt1, DTt2)
result.reg <- myLSfunc(Dt, DTt, y.diff, est.function = c("estimation"))
#Extract the t-statistic and if it is smaller than all previous
#t-statistics replace it and store the values of all break variables
#Extract residuals and coefficients and store them in a list
#matrix to hold all the tstats
tstat.matrix[myBreak1, myBreak2] <- result.reg[1,3]
tstat <- result.reg[1,3]
#print(tstat)
if(tstat < mint){
mint <- tstat
mybestbreak1 <- myBreak1
mybestbreak2 <- myBreak2
}
}#End of second for loop
}#End of first for loop
} else if(breaks > 2){
print("Currently more than two possible structural breaks are not implemented.")
}
#Estimate regression results, based on the determined breaks and the selected lag
# to obtain all necessary information
Dt1 <- as.matrix(cbind(trend, trend >= (mybestbreak1 + 1)))
# Dummy with break in intercept and in trend
DTt1 <- as.matrix(cbind(Dt1, c(rep(0, mybestbreak1), 1:(n - mybestbreak1))))
colnames(Dt1) <- c("Trend","D")
colnames(DTt1) <- c("Trend","D","DTt")
#print(paste("Break1: ",myBreak1, sep = ""))
if(breaks == 2){
#Dummies for two break case
Dt2 <- as.matrix(trend >= (mybestbreak2 + 1))
DTt2 <- as.matrix(cbind(Dt2, c(rep(0, mybestbreak2), 1:(n - mybestbreak2))))
colnames(Dt2) <- c("D2")
colnames(DTt2) <- c("D2","DTt2")
#print(paste("Break2: ",myBreak2, sep = ""))
#Combine all Dummies into one big matrix to make it easier to include in the regressions
Dt <- cbind(Dt1, Dt2)
DTt <- cbind(DTt1, DTt2)
} else if (breaks == 1){
Dt <- Dt1
DTt <- DTt1
}
break.reg <- myLSfunc(Dt, DTt, y.diff, est.function = c("results"))
endtime <- Sys.time()
myruntime <- difftime(endtime,starttime, units = "mins")
if(print.results == "print"){
print(mint)
print(paste("First possible structural break at position:", mybestbreak1))
print(paste("The location of the first break - lambda_1:", round(mybestbreak1/n, digits = 1),", with the number of total observations:", n))
if(breaks == 2){
print(paste("Second possible structural break at position:", mybestbreak2))
print(paste("The location of the second break - lambda_2:", round(mybestbreak2/n, digits = 1),", with the number of total observations:", n))
# Output Critical Values
cat("Critical values:\n")
print(model.two.break.tau.cval)
}else if(breaks == 1){
if(model == "crash"){
cat("Critical values - Crash model:\n")
print(model.one.crash.cval)
} else if(model == "break"){
cat("Critical values - Break model:\n")
print(model.one.break.cval)
}
}
if(method == "Fixed"){
print(paste("Number of lags used:",lags))
} else if(method == "GTOS"){
print(paste("Number of lags determined by general-to-specific lag selection:"
,as.integer(substring(unlist(attr(delete.response(terms(break.reg)), "dataClasses")[3]),9))-1))
}
cat("Runtime:\n")
print(myruntime)
}
# Create complete list with all the information and not only print it
if(breaks == 2){
results.return <- list(mint, mybestbreak1, mybestbreak2, myruntime)
names(results.return) <- c("t-stat", "First break", "Second break", "Runtime")
} else if(breaks == 1){
results.return <- list(mint, mybestbreak1, myruntime)
names(results.return) <- c("t-stat", "First break", "Runtime")
}
return(list(results.return, break.reg))
}#End of ur.ls function
# Application of the basic Lee-Strazizich test without any parallelization
# Definition of values to be used in the application
# Number of possible structural breaks
myBreaks <- 1
# Assumed break in the series, "crash" - break in intercept; "break" - break in intercept and trend
myModel <- "break"
# Number of lags to be used in fixed specification or maximum number of lags, when using the GTOS method
myLags <- 12
y <- ts_cimento
myLS_test <- ur.ls(y=y , model = myModel, breaks = myBreaks, lags = myLags, method = "GTOS",pn = 0.1, print.results = "print" )
## [1] -3.567245
## [1] "First possible structural break at position: 104"
## [1] "The location of the first break - lambda_1: 0.3 , with the number of total observations: 349"
## Critical values - Break model:
## lambda 1% 5% 10%
## [1,] 0.1 -5.11 -4.50 -4.21
## [2,] 0.2 -5.07 -4.47 -4.20
## [3,] 0.3 -5.15 -4.45 -4.18
## [4,] 0.4 -5.05 -4.50 -4.18
## [5,] 0.5 -5.11 -4.51 -4.17
## [1] "Number of lags determined by general-to-specific lag selection: 11"
## Runtime:
## Time difference of 0.02741095 mins
y <- ts_calcario
myLS_test <- ur.ls(y=y , model = myModel, breaks = myBreaks, lags = myLags, method = "GTOS",pn = 0.1, print.results = "print" )
## [1] -4.867287
## [1] "First possible structural break at position: 110"
## [1] "The location of the first break - lambda_1: 0.3 , with the number of total observations: 349"
## Critical values - Break model:
## lambda 1% 5% 10%
## [1,] 0.1 -5.11 -4.50 -4.21
## [2,] 0.2 -5.07 -4.47 -4.20
## [3,] 0.3 -5.15 -4.45 -4.18
## [4,] 0.4 -5.05 -4.50 -4.18
## [5,] 0.5 -5.11 -4.51 -4.17
## [1] "Number of lags determined by general-to-specific lag selection: 12"
## Runtime:
## Time difference of 0.0114938 mins
ts_calcario[110]
## [1] 129.4204
y <- ts_diesel
myLS_test <- ur.ls(y=y , model = myModel, breaks = myBreaks, lags = myLags, method = "GTOS",pn = 0.1, print.results = "print" )
## [1] -3.876402
## [1] "First possible structural break at position: 105"
## [1] "The location of the first break - lambda_1: 0.3 , with the number of total observations: 349"
## Critical values - Break model:
## lambda 1% 5% 10%
## [1,] 0.1 -5.11 -4.50 -4.21
## [2,] 0.2 -5.07 -4.47 -4.20
## [3,] 0.3 -5.15 -4.45 -4.18
## [4,] 0.4 -5.05 -4.50 -4.18
## [5,] 0.5 -5.11 -4.51 -4.17
## [1] "Number of lags determined by general-to-specific lag selection: 7"
## Runtime:
## Time difference of 0.02056672 mins
y <- ts_combustivel
myLS_test <- ur.ls(y=y , model = myModel, breaks = myBreaks, lags = myLags, method = "GTOS",pn = 0.1, print.results = "print" )
## [1] -2.903458
## [1] "First possible structural break at position: 202"
## [1] "The location of the first break - lambda_1: 0.6 , with the number of total observations: 349"
## Critical values - Break model:
## lambda 1% 5% 10%
## [1,] 0.1 -5.11 -4.50 -4.21
## [2,] 0.2 -5.07 -4.47 -4.20
## [3,] 0.3 -5.15 -4.45 -4.18
## [4,] 0.4 -5.05 -4.50 -4.18
## [5,] 0.5 -5.11 -4.51 -4.17
## [1] "Number of lags determined by general-to-specific lag selection: 9"
## Runtime:
## Time difference of 0.02870893 mins
Somente a série calcário apresentou estacionariedade com uma quebra, sugerindo a quebra em Janeiro de 1989.
# Application of the basic Lee-Strazizich test without any parallelization
# Definition of values to be used in the application
# Number of possible structural breaks
myBreaks <- 2
# Assumed break in the series, "crash" - break in intercept; "break" - break in intercept and trend
myModel <- "break"
# Number of lags to be used in fixed specification or maximum number of lags, when using the GTOS method
myLags <- 12
y <- ts_cimento
myLS_test <- ur.ls(y=y , model = myModel, breaks = myBreaks, lags = myLags, method = "GTOS",pn = 0.1, print.results = "print" )
## [1] -4.325359
## [1] "First possible structural break at position: 84"
## [1] "The location of the first break - lambda_1: 0.2 , with the number of total observations: 349"
## [1] "Second possible structural break at position: 130"
## [1] "The location of the second break - lambda_2: 0.4 , with the number of total observations: 349"
## Critical values:
## Break 2 - 0.4 - 1% Break 2 - 0.4 - 5% Break 2 - 0.4 - 10%
## Break 1 - 0.2 -6.16 -5.59 -5.27
## Break 1 - 0.4 NA NA NA
## Break 1 - 0.6 NA NA NA
## Break 2 - 0.6 - 1% Break 2 - 0.6 - 5% Break 2 - 0.6 - 10%
## Break 1 - 0.2 -6.41 -5.74 -5.32
## Break 1 - 0.4 -6.45 -5.67 -5.31
## Break 1 - 0.6 NA NA NA
## Break 2 - 0.8 - 1% Break 2 - 0.8 - 5% Break 2 - 0.8 - 10%
## Break 1 - 0.2 -6.33 -5.71 -5.33
## Break 1 - 0.4 -6.42 -5.65 -5.32
## Break 1 - 0.6 -6.32 -5.73 -5.32
## [1] "Number of lags determined by general-to-specific lag selection: 8"
## Runtime:
## Time difference of 3.254675 mins
y <- ts_calcario
myLS_test <- ur.ls(y=y , model = myModel, breaks = myBreaks, lags = myLags, method = "GTOS",pn = 0.1, print.results = "print" )
## [1] -5.794528
## [1] "First possible structural break at position: 102"
## [1] "The location of the first break - lambda_1: 0.3 , with the number of total observations: 349"
## [1] "Second possible structural break at position: 108"
## [1] "The location of the second break - lambda_2: 0.3 , with the number of total observations: 349"
## Critical values:
## Break 2 - 0.4 - 1% Break 2 - 0.4 - 5% Break 2 - 0.4 - 10%
## Break 1 - 0.2 -6.16 -5.59 -5.27
## Break 1 - 0.4 NA NA NA
## Break 1 - 0.6 NA NA NA
## Break 2 - 0.6 - 1% Break 2 - 0.6 - 5% Break 2 - 0.6 - 10%
## Break 1 - 0.2 -6.41 -5.74 -5.32
## Break 1 - 0.4 -6.45 -5.67 -5.31
## Break 1 - 0.6 NA NA NA
## Break 2 - 0.8 - 1% Break 2 - 0.8 - 5% Break 2 - 0.8 - 10%
## Break 1 - 0.2 -6.33 -5.71 -5.33
## Break 1 - 0.4 -6.42 -5.65 -5.32
## Break 1 - 0.6 -6.32 -5.73 -5.32
## [1] "Number of lags determined by general-to-specific lag selection: 11"
## Runtime:
## Time difference of 1.714561 mins
y <- ts_diesel
myLS_test <- ur.ls(y=y , model = myModel, breaks = myBreaks, lags = myLags, method = "GTOS",pn = 0.1, print.results = "print" )
## [1] -4.936647
## [1] "First possible structural break at position: 42"
## [1] "The location of the first break - lambda_1: 0.1 , with the number of total observations: 349"
## [1] "Second possible structural break at position: 105"
## [1] "The location of the second break - lambda_2: 0.3 , with the number of total observations: 349"
## Critical values:
## Break 2 - 0.4 - 1% Break 2 - 0.4 - 5% Break 2 - 0.4 - 10%
## Break 1 - 0.2 -6.16 -5.59 -5.27
## Break 1 - 0.4 NA NA NA
## Break 1 - 0.6 NA NA NA
## Break 2 - 0.6 - 1% Break 2 - 0.6 - 5% Break 2 - 0.6 - 10%
## Break 1 - 0.2 -6.41 -5.74 -5.32
## Break 1 - 0.4 -6.45 -5.67 -5.31
## Break 1 - 0.6 NA NA NA
## Break 2 - 0.8 - 1% Break 2 - 0.8 - 5% Break 2 - 0.8 - 10%
## Break 1 - 0.2 -6.33 -5.71 -5.33
## Break 1 - 0.4 -6.42 -5.65 -5.32
## Break 1 - 0.6 -6.32 -5.73 -5.32
## [1] "Number of lags determined by general-to-specific lag selection: 8"
## Runtime:
## Time difference of 3.088442 mins
y <- ts_combustivel
myLS_test <- ur.ls(y=y , model = myModel, breaks = myBreaks, lags = myLags, method = "GTOS",pn = 0.1, print.results = "print" )
## [1] -4.854035
## [1] "First possible structural break at position: 107"
## [1] "The location of the first break - lambda_1: 0.3 , with the number of total observations: 349"
## [1] "Second possible structural break at position: 242"
## [1] "The location of the second break - lambda_2: 0.7 , with the number of total observations: 349"
## Critical values:
## Break 2 - 0.4 - 1% Break 2 - 0.4 - 5% Break 2 - 0.4 - 10%
## Break 1 - 0.2 -6.16 -5.59 -5.27
## Break 1 - 0.4 NA NA NA
## Break 1 - 0.6 NA NA NA
## Break 2 - 0.6 - 1% Break 2 - 0.6 - 5% Break 2 - 0.6 - 10%
## Break 1 - 0.2 -6.41 -5.74 -5.32
## Break 1 - 0.4 -6.45 -5.67 -5.31
## Break 1 - 0.6 NA NA NA
## Break 2 - 0.8 - 1% Break 2 - 0.8 - 5% Break 2 - 0.8 - 10%
## Break 1 - 0.2 -6.33 -5.71 -5.33
## Break 1 - 0.4 -6.42 -5.65 -5.32
## Break 1 - 0.6 -6.32 -5.73 -5.32
## [1] "Number of lags determined by general-to-specific lag selection: 4"
## Runtime:
## Time difference of 3.954312 mins
Testando para duas quebras os resultados se mantém, sendo apenas a série calcário considerada estacionária. Compreendendo a critica de Lee-Stravicich a Zivot-Andrews, considera-se preferivel os resultados apresentados pelo método Multiplicador de Lagrange. Desta forma compreendo que a abordagem com quebra estrutural não é muito conclusiva. Talvez seguir outra metodologia possa ser mais esclarecedor.