Komparatif Model ARMA dan ARIMA
## Warning: package 'forecast' was built under R version 4.5.3
## Warning: package 'tseries' was built under R version 4.5.3
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
## Warning: package 'TSA' was built under R version 4.5.3
## Registered S3 methods overwritten by 'TSA':
## method from
## fitted.Arima forecast
## plot.Arima forecast
##
## Attaching package: 'TSA'
## The following objects are masked from 'package:stats':
##
## acf, arima
## The following object is masked from 'package:utils':
##
## tar
## Warning: package 'openxlsx' was built under R version 4.5.3
Membaca data
Penelitian ini menggunakan data sekunder kuantitatif berupa data runtut waktu (time series) harian dari indeks saham FTSE Indonesia.
# Baru jalankan fungsi baca file
data <- read.csv("D:/Tugas Kuliah/Topik dalam Statistik/FTSE Indonesia Price Return Local Historical Data.csv",
sep = ";", quote = "")
head(data)## Date Price
## 1 01/20/2025 3,243.36
## 2 01/21/2025 3,246.58
## 3 01/22/2025 3,287.28
## 4 01/23/2025 3,280.30
## 5 01/24/2025 3,228.29
## 6 01/27/2025 3,228.29
Visualisasi data
ts.plot(data.ts[, "Yt"], type = "l", ylab = "Yt", col = "blue")
title(main = "Harga Saham FTSE Indonesia", cex.sub = 0.8)
points(data.ts[, "Yt"], pch = 20, col = "blue")Split Data Train dan Data Test
Data yang akan digunakan untuk menentukan model terbaik berdasarkan kandidat model akan dilakukan splitting data terlebih dahulu yaitu dengan membagi data menjadi dua bagian bagian pertama yaitu sebagai data training sebesar 80% dan bagian kedua sebagai data testing sebesar 20%.
Visualisasi data training yang akan digunakan untuk mencari model terbaik
ts.plot(train.data, col="blue")
title(main = "Plot data train")
points(train.data, pch = 20, col = "blue")Model ARIMA dan ARMA
Uji kestasioneran rataan data
Mengidentifikasi kestasioneran data dilakukan dengan uji ADF. Uji Augmented Dickey-Fuller (ADF) adalah salah satu alat identifikasi untuk menguji kestasioneran data dan memiliki hipotesis sebagai berikut:
\[H_0: \text{Data tidak stasioner (mengandung unit root)}\]
\[H_1: \text{Data stasioner (tidak mengandung unit root)}\]
##
## Augmented Dickey-Fuller Test
##
## data: train.data
## Dickey-Fuller = -3.67, Lag order = 6, p-value = 0.02681
## alternative hypothesis: stationary
Berdasarkan hasil uji ADF diperoleh p-value sebesar \(0.02681 < 0.05\) yang berarti H0 ditolak, sehingga dapat disimpulkan bahwa Data telah stasioner selanjutnya akan dilakukan identifikasi model tentatif.
Identifikasi kandidat model
Identifikasi kandidat model diperoleh berdasarkan nilai \(p\) dan \(q\) dimana nilai \(d=0\)
Berdasarkan plot ACF terlihat bahwa plot cuts off setelah lag ke-6
sehingga kandidat model yang diperoleh adalah \(ARMA(0,0,1)\)
Berdasarkan plot ACF terlihat bahwa plot cuts off setelah lag ke-6
sehingga kandidat model yang diperoleh adalah \(ARMA(1,0,0)\)
## AR/MA
## 0 1 2 3 4 5 6 7 8 9 10 11 12 13
## 0 x x x x x x x x x x x x x x
## 1 o o x x o o o o o o o o o o
## 2 x o o o o o o o o o o o o o
## 3 x x o o o o o o o o o o o o
## 4 x x o o o o o o o o o x o o
## 5 x x x o o o o o o o o x o o
## 6 x o x x o o o o o o o o o o
## 7 x x x o x o o o o o o o o o
Berdasarkan hasil EACF di atas kandidat model yang diperoleh adalah \(ARMA(1,0,1)\), \(ARMA(2,0,1)\), dan \(ARMA(3,0,1)\)
Dibandingkan dengan auto.arima
##
## Fitting models using approximations to speed things up...
##
## ARIMA(2,1,2) with drift : 2599.568
## ARIMA(0,1,0) with drift : 2601.861
## ARIMA(1,1,0) with drift : 2603.113
## ARIMA(0,1,1) with drift : 2601.867
## ARIMA(0,1,0) : 2599.932
## ARIMA(1,1,2) with drift : 2600.038
## ARIMA(2,1,1) with drift : 2599.959
## ARIMA(3,1,2) with drift : Inf
## ARIMA(2,1,3) with drift : 2600.128
## ARIMA(1,1,1) with drift : 2604.529
## ARIMA(1,1,3) with drift : 2600.66
## ARIMA(3,1,1) with drift : 2601.427
## ARIMA(3,1,3) with drift : Inf
## ARIMA(2,1,2) : 2597.546
## ARIMA(1,1,2) : 2598.105
## ARIMA(2,1,1) : 2598.007
## ARIMA(3,1,2) : Inf
## ARIMA(2,1,3) : 2598.037
## ARIMA(1,1,1) : 2602.625
## ARIMA(1,1,3) : 2598.69
## ARIMA(3,1,1) : 2599.474
## ARIMA(3,1,3) : Inf
##
## Now re-fitting the best model(s) without approximations...
##
## ARIMA(2,1,2) : 2602.185
##
## Best model: ARIMA(2,1,2)
## Series: train.data
## ARIMA(2,1,2)
##
## Coefficients:
## ar1 ar2 ma1 ma2
## -1.4861 -0.7643 1.4748 0.6812
## s.e. 0.3100 0.2224 0.3721 0.3110
##
## sigma^2 = 642.9: log likelihood = -1295.98
## AIC=2601.96 AICc=2602.18 BIC=2620.12
Pendugaan Parameter dan Penentuan Model Terbaik
##
## Call:
## arima(x = train.data, order = c(0, 0, 1), include.mean = TRUE, method = "ML")
##
## Coefficients:
## ma1 intercept
## 0.8514 175.2606
## s.e. 0.0250 5.2795
##
## sigma^2 estimated as 2284: log likelihood = -1480.69, aic = 2965.38
##
## Call:
## arima(x = train.data, order = c(1, 0, 0), include.mean = TRUE, method = "ML")
##
## Coefficients:
## ar1 intercept
## 0.9484 181.9457
## s.e. 0.0186 27.7786
##
## sigma^2 estimated as 646.2: log likelihood = -1304.41, aic = 2612.82
##
## Call:
## arima(x = train.data, order = c(1, 0, 1), include.mean = TRUE, method = "ML")
##
## Coefficients:
## ar1 ma1 intercept
## 0.9547 -0.0623 182.5821
## s.e. 0.0184 0.0646 29.3796
##
## sigma^2 estimated as 644.1: log likelihood = -1303.95, aic = 2613.9
##
## Call:
## arima(x = train.data, order = c(2, 0, 1), include.mean = TRUE, method = "ML")
##
## Coefficients:
## ar1 ar2 ma1 intercept
## 0.0558 0.8426 0.9410 181.9114
## s.e. 0.1399 0.1362 0.1088 27.2718
##
## sigma^2 estimated as 638.1: log likelihood = -1302.7, aic = 2613.41
##
## Call:
## arima(x = train.data, order = c(3, 0, 1), include.mean = TRUE, method = "ML")
##
## Coefficients:
## ar1 ar2 ar3 ma1 intercept
## 0.1505 0.6229 0.1476 0.7608 183.4838
## s.e. 0.1324 0.1358 0.0612 0.1233 30.9546
##
## sigma^2 estimated as 627: log likelihood = -1300.24, aic = 2610.49
##
## Call:
## arima(x = train.data, order = c(2, 1, 2), include.mean = TRUE, method = "ML")
##
## Coefficients:
## ar1 ar2 ma1 ma2
## -1.4800 -0.7598 1.4676 0.6750
## s.e. 0.3199 0.2315 0.3828 0.3216
##
## sigma^2 estimated as 633.7: log likelihood = -1295.98, aic = 2599.97
KndidatModelARIMA <- c("ARMA(0,0,1)", "ARMA(1,0,0)", "ARMA(1,0,1)", "ARMA(2,0,1)","ARMA(3,0,1)", "ARIMA(2,1,2)" )
AICKandidatModel <- c(arma001$aic, arma100$aic, arma101$aic,
arma201$aic, arma301$aic, arima212$aic)
compmodelARIMA <- data.frame(
"Kandidat Model" = KndidatModelARIMA,
"Nilai AIC" = round(AICKandidatModel, 2),
check.names = FALSE
)
compmodelARIMA## Kandidat Model Nilai AIC
## 1 ARMA(0,0,1) 2965.38
## 2 ARMA(1,0,0) 2612.82
## 3 ARMA(1,0,1) 2613.90
## 4 ARMA(2,0,1) 2613.41
## 5 ARMA(3,0,1) 2610.49
## 6 ARIMA(2,1,2) 2599.97
Model diperoleh berdasarkan nilai dari kandidat model (AIC = 2599.97). Oleh karena itu, .Model , maka \(Y_t\) diperoleh dari penjabaran operator . Mengingat model ini telah melalui proses diferensiasi tingkat pertama (\(d=1\)) dan tidak terdapat parameter pada R, maka model ini tidak memiliki nilai konstanta (\(\mu = 0\)). Penjabaran untuk model adalah sebagai berikut: \[\phi_p(B)(1-B)^d Y_t = \mu +\theta_q(B)\,e_t\] \[(1 - \phi_1 B - \phi_2 B^2)(1-B)^1 Y_t =\mu+ (1 + \theta_1 B + \theta_2 B^2)\,e_t\] \[(1 - \phi_1 B - \phi_2 B^2)(Y_t - Y_{t-1}) =\mu+ e_t + \theta_1 e_{t-1} + \theta_2 e_{t-2}\] \[(Y_t - Y_{t-1}) - \phi_1(Y_{t-1} - Y_{t-2}) - \phi_2(Y_{t-2} - Y_{t-3}) =\mu+ e_t + \theta_1 e_{t-1} + \theta_2 e_{t-2}\] \[Y_t - Y_{t-1} - \phi_1 Y_{t-1} + \phi_1 Y_{t-2} - \phi_2 Y_{t-2} + \phi_2 Y_{t-3} = \mu+e_t + \theta_1 e_{t-1} + \theta_2 e_{t-2}\] \[Y_t - (1 + \phi_1)Y_{t-1} + (\phi_1 - \phi_2)Y_{t-2} + \phi_2 Y_{t-3} = \mu+e_t + \theta_1 e_{t-1} + \theta_2 e_{t-2}\] \[Y_t = \mu+(1 + \phi_1)Y_{t-1} - (\phi_1 - \phi_2)Y_{t-2} - \phi_2 Y_{t-3} + \theta_1 e_{t-1} + \theta_2 e_{t-2} + e_t\] Penduga parameter: \(\hat{\phi}_1 = -1.4800\), \(\hat{\phi}_2 = -0.7598\), \(\hat{\theta}_1 = 1.4676\), \(\hat{\theta}_2 = 0.6750\), dengan adalah nilai dugaan bagi \(\sigma^2_e\).(Nilai konstanta pengali untuk bentuk akhir persamaan diperoleh melalui substitusi nilai parameter \(AR\) yang ada) \[Y_t = \mu+(1 + (-1.4800))Y_{t-1} - (-1.4800 - (-0.7598))Y_{t-2} - (-0.7598)Y_{t-3} + 1.4676\,e_{t-1} + 0.6750\,e_{t-2} + e_t\] \[Y_t = \mu+(1 - 1.4800)Y_{t-1} - (-1.4800 + 0.7598)Y_{t-2} + 0.7598\,Y_{t-3} + 1.4676\,e_{t-1} + 0.6750\,e_{t-2} + e_t\] \[Y_t = \mu-0.4800\,Y_{t-1} - (-0.7202)Y_{t-2} + 0.7598\,Y_{t-3} + 1.4676\,e_{t-1} + 0.6750\,e_{t-2} + e_t\] \[Y_t = \mu-0.4800\,Y_{t-1} + 0.7202\,Y_{t-2} + 0.7598\,Y_{t-3} + 1.4676\,e_{t-1} + 0.6750\,e_{t-2} + e_t\]
# Menghitung uji signifikansi untuk parameter Autoregressive (AR)
ar1_phi1 <- -1.4800 / 0.3199
ar1_phi1## [1] -4.626446
## [1] -3.282073
# Menghitung uji signifikansi untuk parameter Moving Average (MA)
ma1_theta1 <- 1.4676 / 0.3828
ma1_theta1## [1] 3.833856
## [1] 2.098881
prmtrdugaan212 <- c("phi(1)", "phi(2)", "theta(1)", "theta(2)")
thitung212 <- c(
abs(ar1_phi1),
abs(ar2_phi2),
abs(ma1_theta1),
abs(ma2_theta2)
)
# Karena hanya ada 4 parameter, nilai t-tabel juga disesuaikan menjadi 4
ttabel <- c("1.981180359", "1.981180359", "1.981180359", "1.981180359")
keputusan <- ifelse(thitung212 > as.numeric(ttabel), "Signifikan", "Tidak Signifikan")
tksigni212 <- data.frame(
"Parameter Dugaan" = prmtrdugaan212,
"T-Hitung" = round(thitung212, 4),
"T-Tabel" = ttabel,
"Keputusan" = keputusan,
check.names = FALSE
)
# Menampilkan tabel hasil
tksigni212## Parameter Dugaan T-Hitung T-Tabel Keputusan
## 1 phi(1) 4.6264 1.981180359 Signifikan
## 2 phi(2) 3.2821 1.981180359 Signifikan
## 3 theta(1) 3.8339 1.981180359 Signifikan
## 4 theta(2) 2.0989 1.981180359 Signifikan
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## ar1 -1.47995 0.31991 -4.6262 3.724e-06 ***
## ar2 -0.75982 0.23150 -3.2822 0.0010302 **
## ma1 1.46756 0.38278 3.8340 0.0001261 ***
## ma2 0.67495 0.32160 2.0987 0.0358396 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Berdasarkan tabel di atas maka pengambilan keputusan dari semua paramater dugaan dari model \(ARIMA(2,1,2)\) semua parameternya signifikan.
Diagnostic model
ARIMA212diag <- stats::arima(train.data, order = c(2,1,2), method = "ML")
checkresiduals(ARIMA212diag)##
## Ljung-Box test
##
## data: Residuals from ARIMA(2,1,2)
## Q* = 4.2017, df = 6, p-value = 0.6494
##
## Model df: 4. Total lags used: 10
Berdasarkan plot di atas terlihat bahwa sisaan tidak mengikuti sebaran normal. Selanjutnya, ditinjau dari plot ACF dan PACF terlihat bahwa tidak ada lag yang signifikan. Hal tersebut menunjukkan bahwa tidak ada gejala autokorelasi pada sisaan.
Uji normalitas data
\[H_0: \text{sisaan menyebar normal}\]
\[H_1: \text{sisaan tidak mengikuti sebaran normal}\]
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: sisaan
## D = 0.42969, p-value < 2.2e-16
## alternative hypothesis: two-sided
Berdasarkan hasil Kolmogorov-Smirnov Test di atas, didapatkan nilai p-value < \(\alpha = 0.05\), maka keputusan yang diambil adalah tolak \(H_0\). Secara matematis, hal ini membuktikan bahwa sisaan dari model tidak mengikuti sebaran normal.
Uji nilai tengah sisaan
\[H_0: \mu = 0\] \[H_1: \mu \neq 0\]
##
## One Sample t-test
##
## data: sisaan
## t = -0.33594, df = 279, p-value = 0.7372
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -3.466146 2.455571
## sample estimates:
## mean of x
## -0.5052873
Berdasarkan hasil uji-t nilai p-value > \(\alpha = 0.05\), maka terima \(H_0\). Ini menunjukkan bahwa secara statistik, nilai harapan (expected value) dari galat terbukti sama dengan nol.
Uji autokorelasi
\[H_0: \text{ tidak ada autokorelasi}\] \[H_1: \text{terdapat autokorelasi}\]
##
## Box-Ljung test
##
## data: sisaan
## X-squared = 13.101, df = 23, p-value = 0.9498
Hasil pengujian memberikan nilai p-value > \(\alpha = 0.05\), maka diambil keputusan terima \(H_0\). Hal ini menyimpulkan bahwa sisaan bersifat saling bebas / tidak terdapat autokorelasi (white noise)
Overfitting
# Overfitting model
# 1. Menjalankan semua kandidat model menggunakan data latih (train.data)
model_arma001 <- arima(train.data, order = c(0, 0, 1), method = "ML")
model_arma100 <- arima(train.data, order = c(1, 0, 0), method = "ML")
model_arma101 <- arima(train.data, order = c(1, 0, 1), method = "ML")
model_arma201 <- arima(train.data, order = c(2, 0, 1), method = "ML")
model_arma301 <- arima(train.data, order = c(3, 0, 1), method = "ML")
model_arima212 <- arima(train.data, order = c(2, 1, 2), method = "ML")
# 2. Membuat daftar nama model untuk di tabel
modelakursi <- c("ARMA(0,0,1)", "ARMA(1,0,0)", "ARMA(1,0,1)", "ARMA(2,0,1)", "ARMA(3,0,1)", "ARIMA(2,1,2)")
# 3. Memanggil dan menggabungkan nilai AIC dari masing-masing model
ModelARIMAaku <- c(
model_arma001$aic,
model_arma100$aic,
model_arma101$aic,
model_arma201$aic,
model_arma301$aic,
model_arima212$aic
)
# 4. Membuat Data Frame (Tabel Komparasi AIC)
Akurasiall <- data.frame(
"Model" = modelakursi,
"AIC" = round(ModelARIMAaku, 4),
"Keputusan" = ifelse(ModelARIMAaku == min(ModelARIMAaku), "Terbaik", "-"),
check.names = FALSE
)
# 5. Menampilkan tabel
Akurasiall## Model AIC Keputusan
## 1 ARMA(0,0,1) 2965.385 -
## 2 ARMA(1,0,0) 2612.817 -
## 3 ARMA(1,0,1) 2613.901 -
## 4 ARMA(2,0,1) 2613.407 -
## 5 ARMA(3,0,1) 2610.490 -
## 6 ARIMA(2,1,2) 2599.965 Terbaik
Peramalan
Data train
predictARIMA212 <- fitted(arima212)
fittedARIMA212 <- cbind(train.data, predictARIMA212)
ts.plot(train.data, col = "blue", ylab = "Harga", xlab = "Day")
title(main = "Harga Saham FTSE Indonesia", cex.sub = 0.8)
points(train.data, pch = 20, col = "blue")
par(col = "red")
lines(predictARIMA212)forecasting <- predict(arima212, n.ahead = 20)
hasilforcasting <- as.data.frame(forecasting)
hasilforcasting## pred se
## 1 164.0412 25.17377
## 2 168.8536 35.38123
## 3 164.7395 42.30216
## 4 167.1717 49.60263
## 5 166.6981 54.74151
## 6 165.5509 60.24560
## 7 167.6085 64.95517
## 8 165.4350 69.26692
## 9 167.0883 73.65929
## 10 166.2930 77.39318
## 11 166.2138 81.30747
## 12 166.9353 84.82615
## 13 165.9277 88.26272
## 14 166.8707 91.63842
## 15 166.2407 94.75618
## 16 166.4566 97.92450
## 17 166.6158 100.87667
## 18 166.2161 103.80505
## 19 166.6866 106.64998
## 20 166.2940 109.38196
plot(arima212, n.ahead = 20, col = "blue", ylab = "Harga", xlab = "Day")
title(main = "Harga Saham FTSE Indonesia", cex.sub = 0.8)
points(train.data, pch = 20, col = "blue")
par(col = "red")
lines(predictARIMA212)Data test
arima212test <- arima(test.data, order = c(2, 1, 2), include.mean = TRUE, method = "ML")
arima212test##
## Call:
## arima(x = test.data, order = c(2, 1, 2), include.mean = TRUE, method = "ML")
##
## Coefficients:
## ar1 ar2 ma1 ma2
## 0.9699 -0.7641 -0.9472 1.0000
## s.e. 0.1298 0.1095 0.0633 0.0705
##
## sigma^2 estimated as 169.9: log likelihood = -249.14, aic = 506.28
predictARIMA212test <- fitted(arima212test)
fittedARIMA212test <- cbind(test.data, predictARIMA212test)
ts.plot(test.data, col = "blue", ylab = "Harga", xlab = "Day")
title(main = "Harga Saham FTSE Indonesia", cex.sub = 0.8)
points(test.data, pch = 20, col = "blue")
par(col = "red")
lines(predictARIMA212test)forecastingtest <- predict(arima212test, n.ahead = 20)
hasilforcastingtest <- as.data.frame(forecastingtest)
hasilforcastingtest## pred se
## 1 4.0476753 13.21711
## 2 3.3295494 19.02479
## 3 0.3044605 25.44238
## 4 -2.0807706 32.14890
## 5 -2.0827701 37.79659
## 6 -0.2622510 41.85615
## 7 1.5049309 44.80206
## 8 1.8278705 47.40098
## 9 0.7908456 50.19982
## 10 -0.4616717 53.30427
## 11 -0.8840931 56.41689
## 12 -0.3367863 59.20363
## 13 0.5167813 61.59942
## 14 0.9264502 63.77304
## 15 0.6715963 65.93229
## 16 0.1114117 68.17460
## 17 -0.2371672 70.44866
## 18 -0.1472266 72.63660
## 19 0.2063385 74.67248
## 20 0.4805282 76.58318
plot(arima212test, n.ahead = 20, col = "blue", ylab = "Harga", xlab = "Day")
title(main = "Harga Saham FTSE Indonesia", cex.sub = 0.8)
points(test.data, pch = 20, col = "blue")
par(col = "red")
lines(predictARIMA212test)Akurasi hasil peramalan
akurasi.arima212training <- accuracy(train.data, predictARIMA212)
akurasi.arima212testing <- accuracy(test.data, predictARIMA212test)
compmodelforecast <- cbind(akurasi.arima212training, akurasi.arima212testing)Data train
predictARIMA212train <- fitted(arima212)
akurasi_train <- accuracy(predictARIMA212train, train.data)
akurasi_train## ME RMSE MAE MPE MAPE ACF1 Theil's U
## Test set -0.5052873 25.12878 18.27147 -2.693206 13.69525 -0.03693997 0.9549405
Data test
arima212test <- arima(test.data, order = c(2, 1, 2), include.mean = TRUE, method = "ML")
predictARIMA212test <- fitted(arima212test)
akurasi_test <- accuracy(predictARIMA212test, test.data)
akurasi_test## ME RMSE MAE MPE MAPE ACF1 Theil's U
## Test set -2.38723 12.93112 8.520728 -14.25868 35.85157 -0.02620034 1.508021
Akurasi <- c("ME", "RMSE", "MAE", "MPE", "MAPE")
ModelARIMA212train <- as.numeric(akurasi_train[1, 1:5])
ModelARIMA212test <- as.numeric(akurasi_test[1, 1:5])
Akurasiall <- rbind(Akurasi, ModelARIMA212train, ModelARIMA212test)
Akurasiall <- as.data.frame(Akurasiall)
colnames(Akurasiall) <- Akurasi
Akurasiall## ME RMSE MAE
## Akurasi ME RMSE MAE
## ModelARIMA212train -0.505287298166563 25.1287830342739 18.2714737039886
## ModelARIMA212test -2.3872295053583 12.9311177147318 8.52072757266074
## MPE MAPE
## Akurasi MPE MAPE
## ModelARIMA212train -2.69320640627161 13.6952458466108
## ModelARIMA212test -14.2586767779819 35.8515749662666
Berdasarkan hasil diatas diperoleh nilai \(RMSE\) dan \(MAE\) pada data pengujian masing-masing sebesar \(12,931\) dan \(8,521\), yang lebih rendah dibandingkan nilai \(RMSE\) dan \(MAE\) pada data pelatihan sebesar \(25,129\) dan \(18,271\). Hasil ini menunjukkan bahwa model mampu mempertahankan performa prediksi yang baik ketika diterapkan pada data yang tidak digunakan dalam proses pembentukan model. Dengan demikian, model \(ARIMA(2,1,2)\) tidak menunjukkan indikasi overfitting yang signifikan dan memiliki kemampuan generalisasi yang cukup baik terhadap data baru. Selanjutnya, berdasarkan nilai Mean Error (ME) dan Mean Percentage Error (MPE), terlihat bahwa kedua metrik tersebut bernilai negatif baik pada data pelatihan maupun data pengujian. Nilai negatif pada kedua ukuran tersebut mengindikasikan adanya kecenderungan model untuk menghasilkan nilai prediksi yang sedikit lebih tinggi dibandingkan nilai aktual (over-forecasting). Namun demikian, besarnya bias yang ditunjukkan relatif kecil sehingga tidak memberikan pengaruh yang berarti terhadap kualitas prediksi model secara keseluruhan. Ditinjau dari nilai RMSE dan MAE yang diperoleh, tingkat kesalahan prediksi model masih berada pada batas yang dapat diterima untuk data finansial yang umumnya memiliki volatilitas tinggi dan pergerakan yang sulit diprediksi secara sempurna. Oleh karena itu, dapat disimpulkan bahwa model \(ARIMA(2,1,2)\) memiliki kinerja yang memadai dalam merepresentasikan dinamika harga saham FTSE Indonesia serta layak digunakan sebagai model peramalan untuk mendukung proyeksi harga saham pada periode mendatang.