library(readxl)
library(forecast)
## Warning: package 'forecast' was built under R version 4.4.3
library(tseries)
## Warning: package 'tseries' was built under R version 4.4.3
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
# Load database
fix_db = read_excel("db_FIX.xlsx")
data = fix_db
# Make sure the date is Date
fix_db$fecha = as.Date(fix_db$fecha)
#Initial visual exploratory analysis
plot(fix_db$fecha, fix_db$fix, type = "l",
main = "FIX Exchange Rate",
xlab = "Date",
ylab = "FIX",
col = "#0B3C5D",
lwd = 2)
#Convert to time series
fix_ts <- ts(fix_db$fix)
#Plot the time series
plot(fix_ts, main = "FIX Exchange Rate Time Series", ylab = "FIX", col = "#1B5886")
#Check stationarity with ADF
adf_original <- adf.test(fix_ts)
adf_original
##
## Augmented Dickey-Fuller Test
##
## data: fix_ts
## Dickey-Fuller = -2.0711, Lag order = 4, p-value = 0.5462
## alternative hypothesis: stationary
#p-value was > 0.05 thus differencing needs to be applied
fix_diff <- diff(fix_ts)
#Check for stationary again
#With the ADF Test
adf.test(fix_diff)
##
## Augmented Dickey-Fuller Test
##
## data: fix_diff
## Dickey-Fuller = -2.3241, Lag order = 4, p-value = 0.4436
## alternative hypothesis: stationary
fix_diff2<-diff(fix_diff)
adf.test(fix_diff2)
## Warning in adf.test(fix_diff2): p-value smaller than printed p-value
##
## Augmented Dickey-Fuller Test
##
## data: fix_diff2
## Dickey-Fuller = -7.1446, Lag order = 3, p-value = 0.01
## alternative hypothesis: stationary
# Plot differenced data
autoplot(fix_diff2) +
ggtitle("Differenced Series") +
xlab("Time") + ylab("Differenced Value")
# 2) Analyze ACF and PACF to identify potential model structures and
appropiate lag values
# ACF and PACF
par(mfrow = c(1,2))
acf(fix_diff2, main = "ACF of Differenced Series")
pacf(fix_diff2, main = "PACF of Differenced Series")
par(mfrow = c(1,1))
#Fit candidate models
model1 = arima(fix_ts, order = c(0,2,1))
model2 = arima(fix_ts, order = c(1,2,0))
model3 = arima(fix_ts, order = c(1,2,1))
model4 = arima(fix_ts, order = c(2,2,0))
model5 = arima(fix_ts, order = c(2,2,1))
model6 = arima(fix_ts, order = c(3,2,0))
model7 = arima(fix_ts, order = c(3,2,1))
#Models
model1
##
## Call:
## arima(x = fix_ts, order = c(0, 2, 1))
##
## Coefficients:
## ma1
## -1.0000
## s.e. 0.1782
##
## sigma^2 estimated as 0.01388: log likelihood = 44.7, aic = -85.4
model2
##
## Call:
## arima(x = fix_ts, order = c(1, 2, 0))
##
## Coefficients:
## ar1
## -0.4155
## s.e. 0.1151
##
## sigma^2 estimated as 0.02287: log likelihood = 30.46, aic = -56.92
model3
##
## Call:
## arima(x = fix_ts, order = c(1, 2, 1))
##
## Coefficients:
## ar1 ma1
## 0.0164 -1.000
## s.e. 0.1251 0.139
##
## sigma^2 estimated as 0.01388: log likelihood = 44.71, aic = -83.41
model4
##
## Call:
## arima(x = fix_ts, order = c(2, 2, 0))
##
## Coefficients:
## ar1 ar2
## -0.6062 -0.4981
## s.e. 0.1093 0.1103
##
## sigma^2 estimated as 0.01736: log likelihood = 39.14, aic = -72.27
model5
##
## Call:
## arima(x = fix_ts, order = c(2, 2, 1))
##
## Coefficients:
## ar1 ar2 ma1
## -0.1103 -0.3170 -0.8285
## s.e. 0.1497 0.1393 0.1240
##
## sigma^2 estimated as 0.01342: log likelihood = 46.91, aic = -85.82
model6
##
## Call:
## arima(x = fix_ts, order = c(3, 2, 0))
##
## Coefficients:
## ar1 ar2 ar3
## -0.7998 -0.7381 -0.4045
## s.e. 0.1143 0.1214 0.1153
##
## sigma^2 estimated as 0.01453: log likelihood = 44.67, aic = -81.33
model7
##
## Call:
## arima(x = fix_ts, order = c(3, 2, 1))
##
## Coefficients:
## ar1 ar2 ar3 ma1
## -0.1383 -0.3343 -0.0339 -0.8046
## s.e. 0.2234 0.1726 0.1880 0.1955
##
## sigma^2 estimated as 0.01342: log likelihood = 46.93, aic = -83.85
# Create table of AIC values
model_comparison <- data.frame(
Model = c("ARIMA(0,2,1)", "ARIMA(1,2,0)", "ARIMA(1,2,1)",
"ARIMA(2,2,0)", "ARIMA(2,2,1)", "ARIMA(3,2,0)", "ARIMA(3,2,1)"),
AIC = c(
AIC(model1),
AIC(model2),
AIC(model3),
AIC(model4),
AIC(model5),
AIC(model6),
AIC(model7)
)
)
model_comparison
## Model AIC
## 1 ARIMA(0,2,1) -85.39553
## 2 ARIMA(1,2,0) -56.91814
## 3 ARIMA(1,2,1) -83.41262
## 4 ARIMA(2,2,0) -72.27435
## 5 ARIMA(2,2,1) -85.81802
## 6 ARIMA(3,2,0) -81.33161
## 7 ARIMA(3,2,1) -83.85167
# Order by AIC (lowest is better)
model_comparison <- model_comparison[order(model_comparison$AIC), ]
print(model_comparison)
## Model AIC
## 5 ARIMA(2,2,1) -85.81802
## 1 ARIMA(0,2,1) -85.39553
## 7 ARIMA(3,2,1) -83.85167
## 3 ARIMA(1,2,1) -83.41262
## 6 ARIMA(3,2,0) -81.33161
## 4 ARIMA(2,2,0) -72.27435
## 2 ARIMA(1,2,0) -56.91814
#Do residual diagnosis with Ljung-Box for the best model
checkresiduals(model5)
##
## Ljung-Box test
##
## data: Residuals from ARIMA(2,2,1)
## Q* = 7.1986, df = 7, p-value = 0.4085
##
## Model df: 3. Total lags used: 10
Box.test(model5$residuals, type = "Ljung-Box")
##
## Box-Ljung test
##
## data: model5$residuals
## X-squared = 0.011259, df = 1, p-value = 0.9155
# Forecastinggg
fix_forecast <- forecast(model5, h = 10)
fix_forecast
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## 68 17.39045 17.24196 17.53893 17.16336 17.61753
## 69 17.32131 17.10479 17.53782 16.99018 17.65244
## 70 17.23547 16.98033 17.49061 16.84527 17.62568
## 71 17.18327 16.88208 17.48446 16.72264 17.64390
## 72 17.13265 16.77658 17.48872 16.58809 17.67722
## 73 17.07120 16.66075 17.48164 16.44347 17.69892
## 74 17.01044 16.54541 17.47546 16.29925 17.72163
## 75 16.95303 16.43066 17.47540 16.15414 17.75193
## 76 16.89504 16.31300 17.47708 16.00489 17.78519
## 77 16.83605 16.19275 17.47935 15.85221 17.81989
plot(fix_forecast, main = "10-Step Forecast for FIX Exchange Rate")