MSF. CARLOS ADEMIR PÉREZ ALAS.
Albayero Cortez, Marjorie Nohemy. AC19029.
Carranza Soto, Jose Muricio. CS21022 .
Rivas Ramos, Marco Antonio. RR14082 .
Este reporte presenta la implementación en R de tres pruebas fundamentales en el análisis de series de tiempo: la prueba de raíz unitaria de Dickey-Fuller, la prueba de cointegración de Johansen y la prueba de causalidad de Granger.
La prueba de Dickey-Fuller se utiliza para determinar si una serie de tiempo presenta una raíz unitaria, es decir, si es no estacionaria. Esto es crucial porque muchas técnicas econométricas requieren que las series sean estacionarias para obtener resultados válidos.
Hipótesis nula (\(H_0\)): La serie tiene una raíz unitaria (no estacionaria) Hipótesis alternativa (\(H_1\)): La serie es estacionaria
Las hipótesis se plantean de esta manera porque asumimos que la serie es no estacionaria hasta que se demuestre lo contrario, siguiendo el principio de precaución en econometría.
El estadístico de prueba es el valor t calculado para el parámetro \(\alpha\) en la ecuación: \(\Delta y_t = \alpha + \beta t + \gamma y_{t-1} + \sum_{i=1}^p \phi_i \Delta y_{t-i} + \varepsilon_t\)
Se rechaza \(H_0\) si el valor p es menor que el nivel de significancia (usualmente 0.05).
Rechazo de \(H_0\): La serie es estacionaria No rechazo de \(H_0\): La serie es no estacionaria
library(tseries)
library(forecast)
set.seed(123)
n <- 100
serie_estacionaria <- arima.sim(model = list(ar = 0.7), n = n)
serie_no_estacionaria <- cumsum(rnorm(n))
adf_estacionaria <- adf.test(serie_estacionaria)
adf_no_estacionaria <- adf.test(serie_no_estacionaria)
resultados_adf <- data.frame(
Serie = c("Estacionaria", "No Estacionaria"),
Estadistico = c(adf_estacionaria$statistic, adf_no_estacionaria$statistic),
Valor_p = c(adf_estacionaria$p.value, adf_no_estacionaria$p.value),
Decision = c(ifelse(adf_estacionaria$p.value < 0.05, "Estacionaria", "No Estacionaria"),
ifelse(adf_no_estacionaria$p.value < 0.05, "Estacionaria", "No Estacionaria"))
)
print("Resultados Prueba Dickey-Fuller Aumentada:")## [1] "Resultados Prueba Dickey-Fuller Aumentada:"
## Serie Estadistico Valor_p Decision
## 1 Estacionaria -2.955808 0.1806924 No Estacionaria
## 2 No Estacionaria -1.886334 0.6237224 No Estacionaria
La prueba de Johansen permite determinar si existe una relación de cointegración entre múltiples series no estacionarias. Esto identifica relaciones de equilibrio de largo plazo entre variables.
Hipótesis nula (\(H_0\)): No hay vectores de cointegración (\(r = 0\)) Hipótesis alternativa (\(H_1\)): Existe al menos un vector de cointegración (\(r > 0\))
Donde \(r\) representa el rango de cointegración, es decir, el número de relaciones de cointegración independientes.
La prueba utiliza dos estadísticos:
Traza: \(\lambda_{trace}(r) = -T \sum_{i=r+1}^n \ln(1-\hat{\lambda}_i)\)
Valor propio máximo: \(\lambda_{max}(r,r+1) = -T \ln(1-\hat{\lambda}_{r+1})\)
Se compara el estadístico calculado con los valores críticos. Si el estadístico es mayor que el valor crítico, se rechaza \(H_0\).
Rechazo de \(H_0\): Existe al menos una relación de cointegración No rechazo de \(H_0\): No existe relación de cointegración
library(urca)
library(vars)
set.seed(123)
n <- 100
error_comun <- cumsum(rnorm(n))
serie1 <- error_comun + rnorm(n, 0, 0.5)
serie2 <- 2 * error_comun + rnorm(n, 0, 0.5)
serie3 <- -error_comun + rnorm(n, 0, 0.5)
datos <- data.frame(serie1, serie2, serie3)
johansen_test <- ca.jo(datos, type = "trace", ecdet = "const", K = 2)
print("Prueba de Cointegración de Johansen:")## [1] "Prueba de Cointegración de Johansen:"
##
## ######################
## # Johansen-Procedure #
## ######################
##
## Test type: trace statistic , without linear trend and constant in cointegration
##
## Eigenvalues (lambda):
## [1] 4.477649e-01 3.803912e-01 2.285582e-02 1.110223e-16
##
## Values of teststatistic and critical values of test:
##
## test 10pct 5pct 1pct
## r <= 2 | 2.27 7.52 9.24 12.97
## r <= 1 | 49.18 17.85 19.96 24.60
## r = 0 | 107.37 32.00 34.91 41.07
##
## Eigenvectors, normalised to first column:
## (These are the cointegration relations)
##
## serie1.l2 serie2.l2 serie3.l2 constant
## serie1.l2 1.00000000 1.00000000 1.0000000 1.0000000
## serie2.l2 -0.37695085 -2.78028999 -2.0964885 -1.6627094
## serie3.l2 0.22178838 -4.59619375 -0.3111205 -0.3443454
## constant 0.01220806 0.07115203 14.1000324 0.9014492
##
## Weights W:
## (This is the loading matrix)
##
## serie1.l2 serie2.l2 serie3.l2 constant
## serie1.d -1.0665887 -0.03102153 0.01479327 9.313399e-18
## serie2.d 0.5131944 0.00785968 0.02933443 -5.006731e-17
## serie3.d -0.3407881 0.23192872 -0.01474324 2.430316e-16
La prueba de causalidad de Granger determina si una serie de tiempo es útil para predecir otra serie. No prueba causalidad en el sentido filosófico, sino capacidad predictiva.
Hipótesis nula (\(H_0\)): La serie X no causa Granger a la serie Y Hipótesis alternativa (\(H_1\)): La serie X causa Granger a la serie Y
Matemáticamente, para el modelo: \(H_0: \beta_1 = \beta_2 = \cdots = \beta_q = 0\)
Se utiliza el estadístico F de Wald: \[\boxed{ F = \dfrac{(RSS_r - RSS_{ur})/q}{RSS_{ur}/(T-k)} }\]
donde \(RSS_r\) es la suma de residuos al cuadrado del modelo restringido, \(RSS_{ur}\) del modelo no restringido, \(q\) es el número de restricciones, y \(k\) el número de parámetros.
Se rechaza \(H_0\) si el valor p es menor que el nivel de significancia.
Rechazo de \(H_0\): X causa Granger a Y No rechazo de \(H_0\): X no causa Granger a Y
library(vars)
datos_diff <- diff(as.matrix(datos))
var_model_granger <- VAR(datos_diff, p = 2)
causality_1_2 <- causality(var_model_granger, cause = "serie1")
causality_2_1 <- causality(var_model_granger, cause = "serie2")
causality_1_3 <- causality(var_model_granger, cause = "serie1")
causality_3_1 <- causality(var_model_granger, cause = "serie3")
resultados_causalidad <- data.frame(
Direccion = c("serie1 → serie2", "serie2 → serie1",
"serie1 → serie3", "serie3 → serie1"),
Estadistico_F = c(causality_1_2$Granger$statistic,
causality_2_1$Granger$statistic,
causality_1_3$Granger$statistic,
causality_3_1$Granger$statistic),
Valor_p = c(causality_1_2$Granger$p.value,
causality_2_1$Granger$p.value,
causality_1_3$Granger$p.value,
causality_3_1$Granger$p.value),
Decision = c(ifelse(causality_1_2$Granger$p.value < 0.05, "Causa", "No causa"),
ifelse(causality_2_1$Granger$p.value < 0.05, "Causa", "No causa"),
ifelse(causality_1_3$Granger$p.value < 0.05, "Causa", "No causa"),
ifelse(causality_3_1$Granger$p.value < 0.05, "Causa", "No causa"))
)
print("Resultados Pruebas de Causalidad de Granger:")## [1] "Resultados Pruebas de Causalidad de Granger:"
## Direccion Estadistico_F Valor_p Decision
## 1 serie1 → serie2 0.3834425 0.82040961 No causa
## 2 serie2 → serie1 2.4175840 0.04900855 Causa
## 3 serie1 → serie3 0.3834425 0.82040961 No causa
## 4 serie3 → serie1 0.9522333 0.43427736 No causa
# ANÁLISIS COMPLETO: RAÍZ UNITARIA, COINTEGRACIÓN Y CAUSALIDAD
# Cargar librerías necesarias
library(tseries)
library(urca)
library(vars)
library(forecast)
library(knitr)
# Configurar semilla para reproducibilidad
set.seed(123)
# 1. GENERAR DATOS SIMULADOS
n <- 200
# Componente común no estacionario (tendencia estocástica)
tendencia_comun <- cumsum(rnorm(n))
# Generar tres series cointegradas
x1 <- tendencia_comun + rnorm(n, 0, 0.5)
x2 <- 1.5 * tendencia_comun + rnorm(n, 0, 0.5)
x3 <- -0.8 * tendencia_comun + rnorm(n, 0, 0.5)
# Crear data frame
datos <- data.frame(x1, x2, x3)
# 2. PRUEBAS DE RAÍZ UNITARIA
print("=== PRUEBAS DE DICKEY-FULLER AUMENTADA ===")## [1] "=== PRUEBAS DE DICKEY-FULLER AUMENTADA ==="
adf_x1 <- adf.test(datos$x1)
adf_x2 <- adf.test(datos$x2)
adf_x3 <- adf.test(datos$x3)
resultados_adf_completo <- data.frame(
Serie = c("x1", "x2", "x3"),
Estadistico = c(adf_x1$statistic, adf_x2$statistic, adf_x3$statistic),
Valor_p = c(adf_x1$p.value, adf_x2$p.value, adf_x3$p.value),
Decision = c(ifelse(adf_x1$p.value < 0.05, "Estacionaria", "No Estacionaria"),
ifelse(adf_x2$p.value < 0.05, "Estacionaria", "No Estacionaria"),
ifelse(adf_x3$p.value < 0.05, "Estacionaria", "No Estacionaria"))
)
print(resultados_adf_completo)## Serie Estadistico Valor_p Decision
## 1 x1 -2.234668 0.4778167 No Estacionaria
## 2 x2 -2.181303 0.5001661 No Estacionaria
## 3 x3 -2.366832 0.4224658 No Estacionaria
## [1] "=== PRUEBA DE COINTEGRACIÓN DE JOHANSEN ==="
johansen_result <- ca.jo(datos, type = "trace", ecdet = "const", K = 2)
summary_johansen <- summary(johansen_result)
# Determinar rango de cointegración de forma más robusta
test_stats <- johansen_result@teststat
critical_vals <- johansen_result@cval
# Determinar el número máximo de posibles relaciones de cointegración
n_series <- ncol(datos)
max_possible_r <- n_series - 1
rango_cointegracion <- 0
for(i in 1:max_possible_r) {
if(test_stats[i] > critical_vals[i, "5pct"]) {
rango_cointegracion <- i
} else {
break
}
}
resultado_cointegracion <- data.frame(
Rango_Cointegracion = rango_cointegracion,
Interpretacion = ifelse(rango_cointegracion > 0,
"Existen relaciones de cointegración",
"No hay relaciones de cointegración")
)
print(resultado_cointegracion)## Rango_Cointegracion Interpretacion
## 1 0 No hay relaciones de cointegración
# 4. ESTIMAR MODELO APROPIADO SEGÚN COINTEGRACIÓN
if(rango_cointegracion > 0 && rango_cointegracion <= max_possible_r) {
print("Existen relaciones de cointegración. Usando VECM.")
# Estimación segura del VECM
vecm <- cajorls(johansen_result, r = rango_cointegracion)
print("Resultados VECM:")
print(summary(vecm$rlm))
# Para causalidad, convertir a VAR
var_model <- vec2var(johansen_result, r = rango_cointegracion)
} else {
print("No hay cointegración. Usando VAR en diferencias.")
datos_diff <- diff(as.matrix(datos))
var_model <- VAR(datos_diff, p = 2)
print("Resultados VAR en diferencias:")
print(summary(var_model))
}## [1] "No hay cointegración. Usando VAR en diferencias."
## [1] "Resultados VAR en diferencias:"
##
## VAR Estimation Results:
## =========================
## Endogenous variables: x1, x2, x3
## Deterministic variables: const
## Sample size: 197
## Log Likelihood: -761.929
## Roots of the characteristic polynomial:
## 0.5847 0.5847 0.5649 0.5649 0.2848 0.2848
## Call:
## VAR(y = datos_diff, p = 2)
##
##
## Estimation results for equation x1:
## ===================================
## x1 = x1.l1 + x2.l1 + x3.l1 + x1.l2 + x2.l2 + x3.l2 + const
##
## Estimate Std. Error t value Pr(>|t|)
## x1.l1 -0.35804 0.11165 -3.207 0.00157 **
## x2.l1 0.11628 0.09303 1.250 0.21286
## x3.l1 -0.06532 0.11797 -0.554 0.58046
## x1.l2 -0.21121 0.11456 -1.844 0.06678 .
## x2.l2 0.09448 0.09319 1.014 0.31197
## x3.l2 0.01253 0.11753 0.107 0.91522
## const -0.01561 0.08082 -0.193 0.84704
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## Residual standard error: 1.134 on 190 degrees of freedom
## Multiple R-Squared: 0.0614, Adjusted R-squared: 0.03176
## F-statistic: 2.071 on 6 and 190 DF, p-value: 0.0584
##
##
## Estimation results for equation x2:
## ===================================
## x2 = x1.l1 + x2.l1 + x3.l1 + x1.l2 + x2.l2 + x3.l2 + const
##
## Estimate Std. Error t value Pr(>|t|)
## x1.l1 0.41839 0.15091 2.772 0.00612 **
## x2.l1 -0.40559 0.12574 -3.226 0.00148 **
## x3.l1 0.01654 0.15946 0.104 0.91751
## x1.l2 0.19395 0.15484 1.253 0.21190
## x2.l2 -0.07751 0.12596 -0.615 0.53907
## x3.l2 0.27864 0.15886 1.754 0.08104 .
## const -0.00531 0.10924 -0.049 0.96128
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## Residual standard error: 1.533 on 190 degrees of freedom
## Multiple R-Squared: 0.09317, Adjusted R-squared: 0.06453
## F-statistic: 3.253 on 6 and 190 DF, p-value: 0.004562
##
##
## Estimation results for equation x3:
## ===================================
## x3 = x1.l1 + x2.l1 + x3.l1 + x1.l2 + x2.l2 + x3.l2 + const
##
## Estimate Std. Error t value Pr(>|t|)
## x1.l1 -0.109195 0.096288 -1.134 0.2582
## x2.l1 -0.174414 0.080230 -2.174 0.0309 *
## x3.l1 -0.641248 0.101740 -6.303 1.99e-09 ***
## x1.l2 -0.041301 0.098795 -0.418 0.6764
## x2.l2 -0.139594 0.080370 -1.737 0.0840 .
## x3.l2 -0.426630 0.101359 -4.209 3.95e-05 ***
## const 0.009621 0.069698 0.138 0.8904
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## Residual standard error: 0.9781 on 190 degrees of freedom
## Multiple R-Squared: 0.1891, Adjusted R-squared: 0.1635
## F-statistic: 7.383 on 6 and 190 DF, p-value: 4.106e-07
##
##
##
## Covariance matrix of residuals:
## x1 x2 x3
## x1 1.2863 1.364 -0.7216
## x2 1.3637 2.350 -1.0833
## x3 -0.7216 -1.083 0.9567
##
## Correlation matrix of residuals:
## x1 x2 x3
## x1 1.0000 0.7843 -0.6504
## x2 0.7843 1.0000 -0.7224
## x3 -0.6504 -0.7224 1.0000
## [1] "=== PRUEBAS DE CAUSALIDAD DE GRANGER ==="
# Realizar pruebas de causalidad de forma segura
causality_results <- list()
tryCatch({
causality_results$x1_x2 <- causality(var_model, cause = "x1")
}, error = function(e) {
causality_results$x1_x2 <- list(Granger = list(statistic = NA, p.value = NA))
})
tryCatch({
causality_results$x2_x1 <- causality(var_model, cause = "x2")
}, error = function(e) {
causality_results$x2_x1 <- list(Granger = list(statistic = NA, p.value = NA))
})
tryCatch({
causality_results$x1_x3 <- causality(var_model, cause = "x1")
}, error = function(e) {
causality_results$x1_x3 <- list(Granger = list(statistic = NA, p.value = NA))
})
tryCatch({
causality_results$x3_x1 <- causality(var_model, cause = "x3")
}, error = function(e) {
causality_results$x3_x1 <- list(Granger = list(statistic = NA, p.value = NA))
})
# Crear tabla de resultados
resultados_causalidad_completo <- data.frame(
Direccion = c("x1 → x2", "x2 → x1", "x1 → x3", "x3 → x1"),
Estadistico_F = c(
ifelse(!is.null(causality_results$x1_x2$Granger$statistic),
causality_results$x1_x2$Granger$statistic, NA),
ifelse(!is.null(causality_results$x2_x1$Granger$statistic),
causality_results$x2_x1$Granger$statistic, NA),
ifelse(!is.null(causality_results$x1_x3$Granger$statistic),
causality_results$x1_x3$Granger$statistic, NA),
ifelse(!is.null(causality_results$x3_x1$Granger$statistic),
causality_results$x3_x1$Granger$statistic, NA)
),
Valor_p = c(
ifelse(!is.null(causality_results$x1_x2$Granger$p.value),
causality_results$x1_x2$Granger$p.value, NA),
ifelse(!is.null(causality_results$x2_x1$Granger$p.value),
causality_results$x2_x1$Granger$p.value, NA),
ifelse(!is.null(causality_results$x1_x3$Granger$p.value),
causality_results$x1_x3$Granger$p.value, NA),
ifelse(!is.null(causality_results$x3_x1$Granger$p.value),
causality_results$x3_x1$Granger$p.value, NA)
)
)
# Añadir decisión
resultados_causalidad_completo$Decision <- sapply(
resultados_causalidad_completo$Valor_p,
function(p) {
if(is.na(p)) "No calculado"
else if(p < 0.05) "Causa"
else "No causa"
}
)
print(resultados_causalidad_completo)## Direccion Estadistico_F Valor_p Decision
## 1 x1 → x2 2.325617 0.05529250 No causa
## 2 x2 → x1 1.343037 0.25264731 No causa
## 3 x1 → x3 2.325617 0.05529250 No causa
## 4 x3 → x1 2.003817 0.09255854 No causa
# 6. VISUALIZACIÓN DE RESULTADOS
par(mfrow = c(2, 2))
plot(datos$x1, type = "l", main = "Serie x1", col = "blue", ylab = "x1")
plot(datos$x2, type = "l", main = "Serie x2", col = "red", ylab = "x2")
plot(datos$x3, type = "l", main = "Serie x3", col = "green", ylab = "x3")
# Matriz de correlación
cor_matrix <- cor(datos)
print("Matriz de correlación:")## [1] "Matriz de correlación:"
## x1 x2 x3
## x1 1.0000000 0.9762562 -0.9558652
## x2 0.9762562 1.0000000 -0.9672392
## x3 -0.9558652 -0.9672392 1.0000000