Analisis ini bertujuan melakukan peramalan (forecasting)
harga saham menggunakan metode ARIMA (Autoregressive
Integrated Moving Average) dengan pendekatan
Box-Jenkins. Data yang digunakan adalah harga penutupan
(Price) saham Nippon Television Holdings
Inc.
Alur analisis yang dilakukan meliputi: pemuatan & pembersihan data, pembagian data training/testing, eksplorasi data, uji stasioneritas dalam varian (Box-Cox), uji stasioneritas dalam mean (ADF), differencing, identifikasi model melalui ACF/PACF, pembentukan dan estimasi kandidat model ARIMA, uji signifikansi parameter, verifikasi asumsi residual, pemilihan model terbaik, peramalan pada data testing, hingga evaluasi akurasi peramalan.
| Variabel | Keterangan | Peran |
|---|---|---|
Date |
Tanggal perdagangan | Indeks waktu |
Price |
Harga penutupan (closing) | Variabel yang dianalisis (Y) |
df <- read.csv("C:/Users/ACER/Downloads/Nippon Television Holdings Inc Stock Price History.csv", stringsAsFactors = FALSE)
# Parse tanggal (format asli: MM/DD/YYYY)
df$Date <- as.Date(df$Date, format = "%m/%d/%Y")
# Bersihkan kolom Price: hapus koma ribuan, misal '3,758.0' -> 3758.0
df$Price <- as.numeric(gsub(",", "", df$Price))
# Urutkan ascending berdasarkan tanggal (data terlama di atas)
df <- df[order(df$Date), ]
rownames(df) <- NULL
price <- df$Price
dates <- df$Date
cat(sprintf("Total observasi : %d\n", length(price)))## Total observasi : 181
## Periode : 2025-08-14 s.d. 2026-05-15
data.frame(Tanggal = format(dates, "%d-%m-%Y"), Price = price) %>%
head(10) %>%
tabel_gaya(
caption = "Tabel 1. Sepuluh Observasi Pertama (Setelah Diurutkan)",
col.names = c("Tanggal", "Harga Penutupan (Price, JPY)")
)| Tanggal | Harga Penutupan (Price, JPY) |
|---|---|
| 14-08-2025 | 3758 |
| 15-08-2025 | 3732 |
| 18-08-2025 | 3768 |
| 19-08-2025 | 3904 |
| 20-08-2025 | 3857 |
| 21-08-2025 | 3883 |
| 22-08-2025 | 3919 |
| 25-08-2025 | 3878 |
| 26-08-2025 | 3865 |
| 27-08-2025 | 3873 |
deskriptif <- data.frame(
Statistik = c("Minimum", "Kuartil 1", "Median", "Rata-rata", "Kuartil 3", "Maksimum", "Standar Deviasi"),
Nilai = round(c(
min(price), quantile(price, 0.25), median(price), mean(price),
quantile(price, 0.75), max(price), sd(price)
), 2)
)
deskriptif %>%
tabel_gaya(caption = "Tabel 2. Statistik Deskriptif Harga Saham (Price)")| Statistik | Nilai |
|---|---|
| Minimum | 2919.50 |
| Kuartil 1 | 3249.00 |
| Median | 3758.00 |
| Rata-rata | 3611.39 |
| Kuartil 3 | 3865.00 |
| Maksimum | 4146.00 |
| Standar Deviasi | 339.88 |
N_TOTAL <- length(price)
N_TRAIN <- round(N_TOTAL * 0.8)
N_TEST <- N_TOTAL - N_TRAIN
train <- price[1:N_TRAIN]
test <- price[(N_TRAIN + 1):(N_TRAIN + N_TEST)]
train_dates <- dates[1:N_TRAIN]
test_dates <- dates[(N_TRAIN + 1):(N_TRAIN + N_TEST)]
data.frame(
Keterangan = c("Total Data", "Data Training (80%)", "Data Testing (20%)"),
Jumlah_Observasi = c(N_TOTAL, N_TRAIN, N_TEST),
Periode_Mulai = c(format(min(dates), "%d-%m-%Y"), format(min(train_dates), "%d-%m-%Y"), format(min(test_dates), "%d-%m-%Y")),
Periode_Akhir = c(format(max(dates), "%d-%m-%Y"), format(max(train_dates), "%d-%m-%Y"), format(max(test_dates), "%d-%m-%Y"))
) %>%
tabel_gaya(
caption = "Tabel 3. Pembagian Data Training dan Testing",
col.names = c("Keterangan", "Jumlah Observasi", "Periode Mulai", "Periode Akhir")
)| Keterangan | Jumlah Observasi | Periode Mulai | Periode Akhir |
|---|---|---|---|
| Total Data | 181 | 14-08-2025 | 15-05-2026 |
| Data Training (80%) | 145 | 14-08-2025 | 19-03-2026 |
| Data Testing (20%) | 36 | 23-03-2026 | 15-05-2026 |
par(mfrow = c(2, 1), mar = c(4, 4, 3, 1))
plot(dates, price, type = "l", col = warna_utama, lwd = 1.2,
main = "Time Series Plot - Harga Saham (Price)",
xlab = "Tanggal", ylab = "Price (JPY)")
abline(v = as.numeric(max(train_dates)), col = warna_tersier, lty = 2, lwd = 1.5)
legend("topleft", legend = c("Price", "Batas Train/Test"),
col = c(warna_utama, warna_tersier), lty = c(1, 2), lwd = c(1.2, 1.5), bty = "n")
grid(col = "gray90")
plot(train_dates, train, type = "l", col = warna_utama, lwd = 1.2,
xlim = range(dates), ylim = range(price),
main = "Pembagian Data Training dan Testing",
xlab = "Tanggal", ylab = "Price (JPY)")
lines(test_dates, test, col = warna_aksen, lwd = 1.5)
legend("topleft",
legend = c(sprintf("Training (%d data)", N_TRAIN), sprintf("Testing (%d data)", N_TEST)),
col = c(warna_utama, warna_aksen), lty = 1, lwd = c(1.2, 1.5), bty = "n")
grid(col = "gray90")Dari plot di atas terlihat pola pergerakan harga saham sepanjang periode pengamatan, termasuk tren naik/turun yang menjadi dasar dilakukannya uji stasioneritas pada tahap berikutnya.
Uji Box-Cox (metode Guerrero via BoxCox.lambda())
digunakan untuk memeriksa apakah data memiliki varian yang stabil
sepanjang waktu.
ts_train <- ts(train)
lam_estimated <- BoxCox.lambda(ts_train)
lam_rounded <- round(lam_estimated)
if (lam_rounded == 1) {
train_trans <- train
lam_used <- 1
status_varian <- "Sudah stasioner dalam varian (tidak perlu transformasi)"
} else {
train_trans <- BoxCox(train, lam_estimated)
lam_used <- lam_estimated
status_varian <- "Belum stasioner, dilakukan transformasi Box-Cox"
}
data.frame(
Statistik = c("Estimated Lambda (\u03bb)", "Rounded Value", "Status"),
Nilai = c(round(lam_estimated, 4), lam_rounded, status_varian)
) %>%
tabel_gaya(caption = "Tabel 4. Hasil Uji Box-Cox")| Statistik | Nilai |
|---|---|
| Estimated Lambda (λ) | 0.7757 |
| Rounded Value | 1 |
| Status | Sudah stasioner dalam varian (tidak perlu transformasi) |
par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
plot(train_dates, train, type = "l", col = warna_utama, lwd = 1,
main = "Data Asli", xlab = "Tanggal", ylab = "Price")
grid(col = "gray90")
judul_transformasi <- if (lam_rounded == 1) {
"Data Digunakan\n(Tanpa Transformasi)"
} else {
sprintf("Setelah Box-Cox\n(\u03bb = %.4f)", lam_estimated)
}
plot(train_dates, train_trans, type = "l", col = warna_aksen, lwd = 1,
main = judul_transformasi, xlab = "Tanggal", ylab = "Transformed Price")
grid(col = "gray90")Nilai λ terestimasi sebesar 0.7757 (dibulatkan menjadi 1), sehingga data sudah stasioner dalam varian dan tidak memerlukan transformasi.
uji_adf <- function(series) {
res <- adf.test(na.omit(series))
list(statistic = as.numeric(res$statistic), pvalue = res$p.value, lag = res$parameter)
}
adf_before <- uji_adf(train_trans)data.frame(
Statistik = c("ADF Statistic", "p-value", "Lag", "Kesimpulan"),
Nilai = c(
round(adf_before$statistic, 4),
format.pval(adf_before$pvalue, digits = 4),
adf_before$lag,
ifelse(adf_before$pvalue < 0.05, "Stasioner dalam mean", "Tidak stasioner - perlu differencing")
)
) %>%
tabel_gaya(caption = "Tabel 5. Hasil Uji ADF Sebelum Differencing")| Statistik | Nilai |
|---|---|
| ADF Statistic | -1.1326 |
| p-value | 0.9143 |
| Lag | 5 |
| Kesimpulan | Tidak stasioner - perlu differencing |
par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
plot(train_dates, train_trans, type = "l", col = warna_utama, lwd = 1,
main = "Time Series Plot - Sebelum Differencing",
xlab = "Tanggal", ylab = "Transformed Price")
abline(h = mean(train_trans), col = warna_tersier, lty = 2)
legend("topleft", legend = "Mean", col = warna_tersier, lty = 2, bty = "n")
grid(col = "gray90")
x <- seq_along(train_trans)
cf <- lm(train_trans ~ x)
plot(x, train_trans, type = "l", col = warna_utama, lwd = 1,
main = "Trend Analysis - Sebelum Differencing",
xlab = "Indeks", ylab = "Transformed Price")
abline(cf, col = warna_tersier, lty = 2, lwd = 2)
legend("topleft", legend = sprintf("Trend (slope=%.4f)", coef(cf)[2]), col = warna_tersier, lty = 2, bty = "n")
grid(col = "gray90")train_diff <- diff(train_trans)
train_diff_dates <- train_dates[-1]
adf_after <- uji_adf(train_diff)
d <- ifelse(adf_before$pvalue < 0.05, 0, 1)data.frame(
Statistik = c("ADF Statistic", "p-value", "Lag", "Kesimpulan", "Orde Differencing (d) Terpilih"),
Nilai = c(
round(adf_after$statistic, 4),
format.pval(adf_after$pvalue, digits = 4),
adf_after$lag,
ifelse(adf_after$pvalue < 0.05, "Stasioner dalam mean", "Masih tidak stasioner"),
d
)
) %>%
tabel_gaya(caption = "Tabel 6. Hasil Uji ADF Setelah Differencing Orde 1")| Statistik | Nilai |
|---|---|
| ADF Statistic | -5.1107 |
| p-value | 0.01 |
| Lag | 5 |
| Kesimpulan | Stasioner dalam mean |
| Orde Differencing (d) Terpilih | 1 |
par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
plot(train_diff_dates, train_diff, type = "l", col = warna_aksen, lwd = 1,
main = "Time Series Plot - Setelah Differencing (d=1)",
xlab = "Tanggal", ylab = "Differenced Price")
abline(h = mean(train_diff), col = warna_tersier, lty = 2)
legend("topleft", legend = "Mean", col = warna_tersier, lty = 2, bty = "n")
grid(col = "gray90")
x2 <- seq_along(train_diff)
cf2 <- lm(train_diff ~ x2)
plot(x2, train_diff, type = "l", col = warna_aksen, lwd = 1,
main = "Trend Analysis - Setelah Differencing",
xlab = "Indeks", ylab = "Differenced Price")
abline(cf2, col = warna_tersier, lty = 2, lwd = 2)
legend("topleft", legend = sprintf("Trend (slope=%.6f)", coef(cf2)[2]), col = warna_tersier, lty = 2, bty = "n")
grid(col = "gray90")Karena data belum stasioner dalam mean sebelum differencing, dilakukan differencing orde 1. Setelah differencing, hasil uji ADF menunjukkan data menjadi stasioner, sehingga orde differencing yang digunakan pada model ARIMA adalah d = 1.
series_acf <- if (d == 1) train_diff else train_trans
judul_acf <- if (d == 1) "ACF - Data Setelah Differencing (d=1)" else "ACF - Data Asli (Sudah Stasioner, d=0)"
judul_pacf <- if (d == 1) "PACF - Data Setelah Differencing (d=1)" else "PACF - Data Asli (Sudah Stasioner, d=0)"par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
acf(series_acf, lag.max = 20, col = warna_utama, main = judul_acf)
grid(col = "gray90")
pacf(series_acf, lag.max = 20, col = warna_aksen, main = judul_pacf)
grid(col = "gray90")acf_val <- acf(series_acf, lag.max = 20, plot = FALSE)
pacf_val <- pacf(series_acf, lag.max = 20, plot = FALSE)
n <- length(series_acf)
batas_sig <- 1.96 / sqrt(n)
lag_acf_sig <- which(abs(acf_val$acf[-1]) > batas_sig)
lag_pacf_sig <- which(abs(pacf_val$acf) > batas_sig)
data.frame(
Lag = 1:20,
ACF = round(as.numeric(acf_val$acf[-1]), 4),
Signifikan_ACF = abs(as.numeric(acf_val$acf[-1])) > batas_sig,
PACF = round(as.numeric(pacf_val$acf), 4),
Signifikan_PACF = abs(as.numeric(pacf_val$acf)) > batas_sig
) %>%
tabel_gaya(
caption = "Tabel 7. Nilai ACF dan PACF per Lag (1-20)",
col.names = c("Lag", "ACF", "Signifikan (ACF)", "PACF", "Signifikan (PACF)")
)| Lag | ACF | Signifikan (ACF) | PACF | Signifikan (PACF) |
|---|---|---|---|---|
| 1 | -0.1900 | TRUE | -0.1900 | TRUE |
| 2 | 0.0608 | FALSE | 0.0257 | FALSE |
| 3 | -0.0825 | FALSE | -0.0689 | FALSE |
| 4 | -0.0962 | FALSE | -0.1306 | FALSE |
| 5 | 0.0568 | FALSE | 0.0216 | FALSE |
| 6 | 0.0810 | FALSE | 0.1035 | FALSE |
| 7 | 0.0278 | FALSE | 0.0431 | FALSE |
| 8 | -0.0831 | FALSE | -0.0890 | FALSE |
| 9 | 0.0922 | FALSE | 0.0900 | FALSE |
| 10 | -0.0924 | FALSE | -0.0290 | FALSE |
| 11 | 0.0194 | FALSE | -0.0314 | FALSE |
| 12 | 0.0497 | FALSE | 0.0413 | FALSE |
| 13 | 0.0138 | FALSE | 0.0488 | FALSE |
| 14 | 0.1102 | FALSE | 0.1160 | FALSE |
| 15 | -0.0831 | FALSE | -0.0519 | FALSE |
| 16 | 0.0379 | FALSE | 0.0261 | FALSE |
| 17 | -0.0071 | FALSE | 0.0538 | FALSE |
| 18 | 0.0336 | FALSE | 0.0230 | FALSE |
| 19 | 0.0016 | FALSE | -0.0128 | FALSE |
| 20 | -0.1579 | FALSE | -0.1818 | TRUE |
data.frame(
Statistik = c("Batas Signifikansi (\u00b1)", "Lag ACF Signifikan (kandidat q)", "Lag PACF Signifikan (kandidat p)"),
Nilai = c(
round(batas_sig, 4),
ifelse(length(lag_acf_sig) > 0, paste(lag_acf_sig, collapse = ", "), "Tidak ada"),
ifelse(length(lag_pacf_sig) > 0, paste(lag_pacf_sig, collapse = ", "), "Tidak ada")
)
) %>%
tabel_gaya(caption = "Tabel 8. Ringkasan Lag Signifikan ACF dan PACF")| Statistik | Nilai |
|---|---|
| Batas Signifikansi (±) | 0.1633 |
| Lag ACF Signifikan (kandidat q) | 1 |
| Lag PACF Signifikan (kandidat p) | 1, 20 |
Panduan pembacaan: ACF terpotong di lag k mengindikasikan komponen MA(k) (nilai q), sedangkan PACF terpotong di lag k mengindikasikan komponen AR(k) (nilai p). Nilai-nilai ini menjadi dasar pembentukan kandidat model ARIMA pada tahap berikutnya.
Kandidat model ARIMA dibentuk secara otomatis dari kombinasi lag
signifikan ACF (kandidat q) dan PACF (kandidat p), termasuk kombinasi
lag musiman/tidak berurutan menggunakan argumen fixed.
p_lags <- lag_pacf_sig[lag_pacf_sig <= 20]
q_lags <- lag_acf_sig[lag_acf_sig <= 20]
p_range <- unique(c(0, p_lags))
q_range <- unique(c(0, q_lags))
kandidat <- list()
# 1) Kombinasi individual p dan q
for (p_val in p_range) {
for (q_val in q_range) {
if (p_val == 0 && q_val == 0) next
kandidat <- c(kandidat, list(list(
order = c(p_val, d, q_val),
fixed = NULL,
label = sprintf("ARIMA(%d,%d,%d)", p_val, d, q_val)
)))
}
}
# 2) Kombinasi lag PACF sekaligus: ARIMA([lag1,lag2],d,q)
if (length(p_lags) > 1) {
p_max <- max(p_lags)
fixed_ar <- rep(0, p_max)
for (lg in p_lags) fixed_ar[lg] <- NA
for (q_val in q_range) {
fixed_full <- c(fixed_ar, if (q_val > 0) rep(NA, q_val) else NULL)
label <- sprintf("ARIMA([%s],%d,%d)", paste(p_lags, collapse = ","), d, q_val)
kandidat <- c(kandidat, list(list(order = c(p_max, d, q_val), fixed = fixed_full, label = label)))
}
}
# 3) Kombinasi lag ACF sekaligus: ARIMA(p,d,[lag1,lag2])
if (length(q_lags) > 1) {
q_max <- max(q_lags)
fixed_ma <- rep(0, q_max)
for (lg in q_lags) fixed_ma[lg] <- NA
for (p_val in p_range) {
fixed_full <- c(if (p_val > 0) rep(NA, p_val) else NULL, fixed_ma)
label <- sprintf("ARIMA(%d,%d,[%s])", p_val, d, paste(q_lags, collapse = ","))
kandidat <- c(kandidat, list(list(order = c(p_val, d, q_max), fixed = fixed_full, label = label)))
}
}
data.frame(
No = seq_along(kandidat),
Model = sapply(kandidat, function(x) x$label)
) %>%
tabel_gaya(caption = sprintf("Tabel 9. Daftar %d Model Kandidat ARIMA", length(kandidat)))| No | Model |
|---|---|
| 1 | ARIMA(0,1,1) |
| 2 | ARIMA(1,1,0) |
| 3 | ARIMA(1,1,1) |
| 4 | ARIMA(20,1,0) |
| 5 | ARIMA(20,1,1) |
| 6 | ARIMA([1,20],1,0) |
| 7 | ARIMA([1,20],1,1) |
Setiap kandidat diestimasi dua kali (dengan dan tanpa konstanta).
Jika d > 0, konstanta direpresentasikan sebagai
drift; jika d = 0, konstanta
direpresentasikan sebagai mean.
results_list <- list()
results_names <- c()
ts_train_trans <- ts(train_trans)
for (kand in kandidat) {
for (inc_const in c(TRUE, FALSE)) {
konst <- ifelse(inc_const, "Dengan Konstanta", "Tanpa Konstanta")
key_full <- sprintf("%s_%s", kand$label, konst)
if (d > 0) {
v_include.mean <- FALSE
v_include.drift <- inc_const
} else {
v_include.mean <- inc_const
v_include.drift <- FALSE
}
v_fixed <- kand$fixed
if (!is.null(v_fixed) && inc_const) {
v_fixed <- c(v_fixed, NA)
}
res <- tryCatch({
suppressWarnings(
Arima(ts_train_trans,
order = kand$order,
fixed = v_fixed,
include.mean = v_include.mean,
include.drift = v_include.drift)
)
}, error = function(e) NULL)
if (is.null(res)) next
if (any(is.nan(coef(res))) || any(is.na(coef(res)))) next
results_list[[key_full]] <- res
results_names <- c(results_names, key_full)
}
}
data.frame(
Model = results_names,
AIC = round(sapply(results_list, function(x) x$aic), 2),
BIC = round(sapply(results_list, function(x) x$bic), 2)
) %>%
arrange(AIC) %>%
tabel_gaya(caption = sprintf("Tabel 10. Hasil Estimasi %d Model yang Berhasil Di-fit (Diurutkan Berdasarkan AIC)", length(results_list)))| Model | AIC | BIC |
|---|---|---|
| ARIMA([1,20],1,0)_Tanpa Konstanta | 1586.23 | 1595.14 |
| ARIMA([1,20],1,0)_Dengan Konstanta | 1586.59 | 1598.47 |
| ARIMA([1,20],1,1)_Tanpa Konstanta | 1587.41 | 1599.28 |
| ARIMA(1,1,0)_Tanpa Konstanta | 1587.90 | 1593.84 |
| ARIMA([1,20],1,1)_Dengan Konstanta | 1588.03 | 1602.87 |
| ARIMA(0,1,1)_Tanpa Konstanta | 1588.23 | 1594.17 |
| ARIMA(1,1,0)_Dengan Konstanta | 1588.79 | 1597.70 |
| ARIMA(0,1,1)_Dengan Konstanta | 1589.06 | 1597.97 |
| ARIMA(1,1,1)_Tanpa Konstanta | 1589.68 | 1598.59 |
| ARIMA(1,1,1)_Dengan Konstanta | 1590.63 | 1602.51 |
| ARIMA(20,1,0)_Tanpa Konstanta | 1608.69 | 1671.06 |
| ARIMA(20,1,0)_Dengan Konstanta | 1609.62 | 1674.95 |
| ARIMA(20,1,1)_Tanpa Konstanta | 1609.89 | 1675.22 |
| ARIMA(20,1,1)_Dengan Konstanta | 1610.95 | 1679.25 |
sig_results <- list()
param_table <- data.frame()
for (key in results_names) {
res <- results_list[[key]]
coefs <- coef(res)
if (length(coefs) == 0) {
sig_results[[key]] <- TRUE
next
}
vcov_m <- tryCatch(vcov(res), error = function(e) NULL)
if (is.null(vcov_m) || any(is.na(diag(vcov_m)))) {
sig_results[[key]] <- FALSE
next
}
ses <- sqrt(diag(vcov_m))
tvals <- coefs / ses
pvals <- 2 * pnorm(abs(tvals), lower.tail = FALSE)
all_sig <- all(pvals < 0.05)
sig_results[[key]] <- all_sig
for (i in seq_along(coefs)) {
param_table <- rbind(param_table, data.frame(
Model = key,
Parameter = names(coefs)[i],
Estimasi = round(coefs[i], 4),
SE = round(ses[i], 4),
p_value = round(pvals[i], 4),
Signifikan = ifelse(pvals[i] < 0.05, "Ya", "Tidak")
))
}
}
param_table %>%
tabel_gaya(
caption = "Tabel 11. Estimasi Parameter dan Uji Signifikansi Seluruh Model Kandidat",
col.names = c("Model", "Parameter", "Estimasi", "Std. Error", "p-value", "Signifikan?")
)| Model | Parameter | Estimasi | Std. Error | p-value | Signifikan? |
|---|---|---|---|---|---|
| ARIMA(0,1,1)_Dengan Konstanta | ma1 | -0.1851 | 0.0820 | 0.0240 | Ya |
| ARIMA(0,1,1)_Dengan Konstanta | drift | -4.3625 | 4.0137 | 0.2771 | Tidak |
| ARIMA(0,1,1)_Tanpa Konstanta | ma1 | -0.1765 | 0.0811 | 0.0295 | Ya |
| ARIMA(1,1,0)_Dengan Konstanta | ar1 | -0.1910 | 0.0820 | 0.0198 | Ya |
| ARIMA(1,1,0)_Dengan Konstanta | drift | -4.3616 | 4.1295 | 0.2909 | Tidak |
| ARIMA(1,1,0)_Tanpa Konstanta | ar1 | -0.1856 | 0.0822 | 0.0239 | Ya |
| ARIMA(1,1,1)_Dengan Konstanta | ar1 | -0.3651 | 0.3751 | 0.3303 | Tidak |
| ARIMA(1,1,1)_Dengan Konstanta | ma1 | 0.1813 | 0.3957 | 0.6468 | Tidak |
| ARIMA(1,1,1)_Dengan Konstanta | drift | -4.3771 | 4.2529 | 0.3034 | Tidak |
| ARIMA(1,1,1)_Tanpa Konstanta | ar1 | -0.3800 | 0.3594 | 0.2903 | Tidak |
| ARIMA(1,1,1)_Tanpa Konstanta | ma1 | 0.2020 | 0.3792 | 0.5943 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar1 | -0.1829 | 0.0816 | 0.0249 | Ya |
| ARIMA(20,1,0)_Dengan Konstanta | ar2 | 0.0462 | 0.0833 | 0.5794 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar3 | -0.0716 | 0.0843 | 0.3952 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar4 | -0.1410 | 0.0848 | 0.0963 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar5 | 0.0226 | 0.0853 | 0.7913 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar6 | 0.1625 | 0.0854 | 0.0572 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar7 | 0.0067 | 0.0849 | 0.9370 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar8 | -0.0894 | 0.0857 | 0.2971 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar9 | 0.1019 | 0.0854 | 0.2329 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar10 | -0.0098 | 0.0873 | 0.9103 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar11 | -0.0133 | 0.0856 | 0.8760 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar12 | 0.0109 | 0.0854 | 0.8980 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar13 | 0.0859 | 0.0854 | 0.3145 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar14 | 0.1412 | 0.0864 | 0.1021 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar15 | -0.0541 | 0.0866 | 0.5317 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar16 | 0.0021 | 0.0886 | 0.9809 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar17 | 0.0559 | 0.0883 | 0.5265 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar18 | 0.0409 | 0.0896 | 0.6475 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar19 | -0.0535 | 0.0892 | 0.5491 | Tidak |
| ARIMA(20,1,0)_Dengan Konstanta | ar20 | -0.2066 | 0.0865 | 0.0169 | Ya |
| ARIMA(20,1,0)_Dengan Konstanta | drift | -4.6573 | 4.0626 | 0.2516 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar1 | -0.1790 | 0.0818 | 0.0287 | Ya |
| ARIMA(20,1,0)_Tanpa Konstanta | ar2 | 0.0521 | 0.0834 | 0.5327 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar3 | -0.0630 | 0.0842 | 0.4539 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar4 | -0.1326 | 0.0847 | 0.1175 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar5 | 0.0322 | 0.0851 | 0.7055 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar6 | 0.1714 | 0.0853 | 0.0445 | Ya |
| ARIMA(20,1,0)_Tanpa Konstanta | ar7 | 0.0155 | 0.0847 | 0.8553 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar8 | -0.0802 | 0.0855 | 0.3482 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar9 | 0.1118 | 0.0851 | 0.1889 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar10 | -0.0007 | 0.0870 | 0.9936 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar11 | -0.0045 | 0.0854 | 0.9578 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar12 | 0.0219 | 0.0850 | 0.7966 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar13 | 0.0967 | 0.0850 | 0.2553 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar14 | 0.1503 | 0.0862 | 0.0812 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar15 | -0.0437 | 0.0862 | 0.6125 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar16 | 0.0149 | 0.0880 | 0.8659 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar17 | 0.0687 | 0.0877 | 0.4333 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar18 | 0.0549 | 0.0888 | 0.5364 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar19 | -0.0394 | 0.0885 | 0.6559 | Tidak |
| ARIMA(20,1,0)_Tanpa Konstanta | ar20 | -0.1952 | 0.0861 | 0.0234 | Ya |
| ARIMA(20,1,1)_Dengan Konstanta | ar1 | -0.4927 | 0.3173 | 0.1205 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar2 | -0.0109 | 0.1080 | 0.9200 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar3 | -0.0601 | 0.0933 | 0.5197 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar4 | -0.1672 | 0.0966 | 0.0835 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar5 | -0.0223 | 0.1027 | 0.8280 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar6 | 0.1737 | 0.0943 | 0.0656 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar7 | 0.0505 | 0.1023 | 0.6213 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar8 | -0.0898 | 0.0942 | 0.3405 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar9 | 0.0725 | 0.0978 | 0.4580 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar10 | 0.0234 | 0.1009 | 0.8166 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar11 | -0.0156 | 0.0938 | 0.8675 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar12 | 0.0000 | 0.0940 | 1.0000 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar13 | 0.0967 | 0.0942 | 0.3045 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar14 | 0.1689 | 0.0978 | 0.0841 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar15 | -0.0181 | 0.1017 | 0.8591 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar16 | -0.0145 | 0.0979 | 0.8818 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar17 | 0.0657 | 0.0976 | 0.5008 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar18 | 0.0614 | 0.1007 | 0.5422 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar19 | -0.0454 | 0.1000 | 0.6500 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | ar20 | -0.2097 | 0.0889 | 0.0184 | Ya |
| ARIMA(20,1,1)_Dengan Konstanta | ma1 | 0.3254 | 0.3217 | 0.3118 | Tidak |
| ARIMA(20,1,1)_Dengan Konstanta | drift | -4.5554 | 4.2614 | 0.2851 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar1 | -0.5132 | 0.3078 | 0.0955 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar2 | -0.0086 | 0.1076 | 0.9363 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar3 | -0.0491 | 0.0940 | 0.6010 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar4 | -0.1584 | 0.0964 | 0.1005 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar5 | -0.0143 | 0.1019 | 0.8885 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar6 | 0.1858 | 0.0948 | 0.0501 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar7 | 0.0654 | 0.1027 | 0.5246 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar8 | -0.0784 | 0.0946 | 0.4074 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar9 | 0.0824 | 0.0973 | 0.3971 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar10 | 0.0375 | 0.1014 | 0.7117 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar11 | -0.0046 | 0.0941 | 0.9609 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar12 | 0.0123 | 0.0941 | 0.8958 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar13 | 0.1106 | 0.0945 | 0.2418 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar14 | 0.1830 | 0.0982 | 0.0625 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar15 | -0.0022 | 0.1021 | 0.9830 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar16 | -0.0009 | 0.0976 | 0.9926 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar17 | 0.0817 | 0.0977 | 0.4030 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar18 | 0.0798 | 0.1005 | 0.4276 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar19 | -0.0275 | 0.1001 | 0.7838 | Tidak |
| ARIMA(20,1,1)_Tanpa Konstanta | ar20 | -0.1972 | 0.0892 | 0.0270 | Ya |
| ARIMA(20,1,1)_Tanpa Konstanta | ma1 | 0.3499 | 0.3102 | 0.2593 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar1 | -0.1904 | 0.0804 | 0.0179 | Ya |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar2 | 0.0000 | 0.0841 | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar3 | 0.0000 | 3.6101 | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar4 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar5 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar6 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar7 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar8 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar9 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar10 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar11 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar12 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar13 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar14 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar15 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar16 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar17 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar18 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar19 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Dengan Konstanta | ar20 | -0.1745 | NA | 0.0379 | Ya |
| ARIMA([1,20],1,0)_Dengan Konstanta | drift | -4.6594 | NA | 0.1968 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar1 | -0.1841 | 0.0808 | 0.0226 | Ya |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar2 | 0.0000 | 0.0841 | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar3 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar4 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar5 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar6 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar7 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar8 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar9 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar10 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar11 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar12 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar13 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar14 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar15 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar16 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar17 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar18 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar19 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,0)_Tanpa Konstanta | ar20 | -0.1630 | NA | 0.0527 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar1 | -0.4569 | 0.2781 | 0.1003 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar2 | 0.0000 | 0.0770 | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar3 | 0.0000 | 0.3156 | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar4 | 0.0000 | 3.9050 | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar5 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar6 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar7 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar8 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar9 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar10 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar11 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar12 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar13 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar14 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar15 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar16 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar17 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar18 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar19 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ar20 | -0.1634 | NA | 0.9666 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | ma1 | 0.2932 | NA | 0.2918 | Tidak |
| ARIMA([1,20],1,1)_Dengan Konstanta | drift | -4.6355 | NA | 0.0000 | Ya |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar1 | -0.4834 | 0.2577 | 0.0606 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar2 | 0.0000 | 0.0749 | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar3 | 0.0000 | 0.2936 | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar4 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar5 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar6 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar7 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar8 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar9 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar10 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar11 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar12 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar13 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar14 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar15 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar16 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar17 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar18 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar19 | 0.0000 | NA | 1.0000 | Tidak |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ar20 | -0.1551 | NA | 0.0383 | Ya |
| ARIMA([1,20],1,1)_Tanpa Konstanta | ma1 | 0.3282 | NA | 0.2636 | Tidak |
norm_results <- list()
norm_table <- data.frame()
for (key in results_names) {
resid_clean <- na.omit(residuals(results_list[[key]]))
resid_std <- scale(resid_clean)
ks <- ks.test(resid_std, "pnorm", mean = 0, sd = 1)
ok <- ks$p.value > 0.05
norm_results[[key]] <- ok
norm_table <- rbind(norm_table, data.frame(
Model = key, p_value = round(ks$p.value, 4), Kesimpulan = ifelse(ok, "Normal", "Tidak Normal")
))
}
norm_table %>%
tabel_gaya(
caption = "Tabel 12. Hasil Uji Normalitas Residual (Kolmogorov-Smirnov, \u03b1=5%)",
col.names = c("Model", "p-value", "Kesimpulan")
)| Model | p-value | Kesimpulan |
|---|---|---|
| ARIMA(0,1,1)_Dengan Konstanta | 0.4965 | Normal |
| ARIMA(0,1,1)_Tanpa Konstanta | 0.5709 | Normal |
| ARIMA(1,1,0)_Dengan Konstanta | 0.5709 | Normal |
| ARIMA(1,1,0)_Tanpa Konstanta | 0.5506 | Normal |
| ARIMA(1,1,1)_Dengan Konstanta | 0.6562 | Normal |
| ARIMA(1,1,1)_Tanpa Konstanta | 0.6514 | Normal |
| ARIMA(20,1,0)_Dengan Konstanta | 0.5624 | Normal |
| ARIMA(20,1,0)_Tanpa Konstanta | 0.7537 | Normal |
| ARIMA(20,1,1)_Dengan Konstanta | 0.4288 | Normal |
| ARIMA(20,1,1)_Tanpa Konstanta | 0.7097 | Normal |
| ARIMA([1,20],1,0)_Dengan Konstanta | 0.5315 | Normal |
| ARIMA([1,20],1,0)_Tanpa Konstanta | 0.5965 | Normal |
| ARIMA([1,20],1,1)_Dengan Konstanta | 0.6006 | Normal |
| ARIMA([1,20],1,1)_Tanpa Konstanta | 0.6683 | Normal |
homo_results <- list()
homo_table <- data.frame()
lags_use_h <- c(12, 24, 36)
for (key in results_names) {
resid_clean <- na.omit(residuals(results_list[[key]]))
pvals_lb <- sapply(lags_use_h, function(lg) Box.test(resid_clean^2, lag = lg, type = "Ljung-Box")$p.value)
ok <- all(pvals_lb > 0.05)
homo_results[[key]] <- ok
homo_table <- rbind(homo_table, data.frame(
Model = key, Min_p_value = round(min(pvals_lb), 4), Kesimpulan = ifelse(ok, "Homogen", "Tidak Homogen")
))
}
homo_table %>%
tabel_gaya(
caption = "Tabel 13. Hasil Uji Homogenitas Residual (Ljung-Box Kuadrat Residual, \u03b1=5%)",
col.names = c("Model", "Min p-value", "Kesimpulan")
)| Model | Min p-value | Kesimpulan |
|---|---|---|
| ARIMA(0,1,1)_Dengan Konstanta | 0.1367 | Homogen |
| ARIMA(0,1,1)_Tanpa Konstanta | 0.1709 | Homogen |
| ARIMA(1,1,0)_Dengan Konstanta | 0.1086 | Homogen |
| ARIMA(1,1,0)_Tanpa Konstanta | 0.1346 | Homogen |
| ARIMA(1,1,1)_Dengan Konstanta | 0.1009 | Homogen |
| ARIMA(1,1,1)_Tanpa Konstanta | 0.1240 | Homogen |
| ARIMA(20,1,0)_Dengan Konstanta | 0.1784 | Homogen |
| ARIMA(20,1,0)_Tanpa Konstanta | 0.1845 | Homogen |
| ARIMA(20,1,1)_Dengan Konstanta | 0.2217 | Homogen |
| ARIMA(20,1,1)_Tanpa Konstanta | 0.2234 | Homogen |
| ARIMA([1,20],1,0)_Dengan Konstanta | 0.0349 | Tidak Homogen |
| ARIMA([1,20],1,0)_Tanpa Konstanta | 0.0601 | Homogen |
| ARIMA([1,20],1,1)_Dengan Konstanta | 0.0435 | Tidak Homogen |
| ARIMA([1,20],1,1)_Tanpa Konstanta | 0.0752 | Homogen |
indep_results <- list()
indep_table <- data.frame()
lags_use_i <- c(12, 24, 36, 48)
for (key in results_names) {
resid_clean <- na.omit(residuals(results_list[[key]]))
pvals_lb <- sapply(lags_use_i, function(lg) Box.test(resid_clean, lag = lg, type = "Ljung-Box")$p.value)
ok <- all(pvals_lb > 0.05)
indep_results[[key]] <- ok
indep_table <- rbind(indep_table, data.frame(
Model = key, Min_p_value = round(min(pvals_lb), 4), Kesimpulan = ifelse(ok, "Independen", "Tidak Independen")
))
}
indep_table %>%
tabel_gaya(
caption = "Tabel 14. Hasil Uji Independensi Residual (Ljung-Box, \u03b1=5%)",
col.names = c("Model", "Min p-value", "Kesimpulan")
)| Model | Min p-value | Kesimpulan |
|---|---|---|
| ARIMA(0,1,1)_Dengan Konstanta | 0.7760 | Independen |
| ARIMA(0,1,1)_Tanpa Konstanta | 0.7716 | Independen |
| ARIMA(1,1,0)_Dengan Konstanta | 0.7676 | Independen |
| ARIMA(1,1,0)_Tanpa Konstanta | 0.7680 | Independen |
| ARIMA(1,1,1)_Dengan Konstanta | 0.7589 | Independen |
| ARIMA(1,1,1)_Tanpa Konstanta | 0.7576 | Independen |
| ARIMA(20,1,0)_Dengan Konstanta | 0.9999 | Independen |
| ARIMA(20,1,0)_Tanpa Konstanta | 0.9999 | Independen |
| ARIMA(20,1,1)_Dengan Konstanta | 1.0000 | Independen |
| ARIMA(20,1,1)_Tanpa Konstanta | 0.9999 | Independen |
| ARIMA([1,20],1,0)_Dengan Konstanta | 0.5744 | Independen |
| ARIMA([1,20],1,0)_Tanpa Konstanta | 0.5968 | Independen |
| ARIMA([1,20],1,1)_Dengan Konstanta | 0.5598 | Independen |
| ARIMA([1,20],1,1)_Tanpa Konstanta | 0.5721 | Independen |
Probability plot berikut ditampilkan untuk model-model yang lolos uji signifikansi parameter.
lolos_keys <- results_names[sapply(results_names, function(k) isTRUE(sig_results[[k]]))]
if (length(lolos_keys) > 0) {
ncols <- 2
nrows <- ceiling(length(lolos_keys) / ncols)
par(mfrow = c(nrows, ncols), mar = c(4, 4, 3, 1))
for (key in lolos_keys) {
resid_clean <- na.omit(residuals(results_list[[key]]))
qqnorm(resid_clean, main = sprintf("Probability Plot\n%s", substr(key, 1, 35)),
col = warna_utama, pch = 16, cex = 0.7)
qqline(resid_clean, col = warna_tersier, lwd = 1.5)
grid(col = "gray90")
}
par(mfrow = c(1, 1))
} else {
cat("Tidak ada model yang lolos uji signifikansi parameter.\n")
}comparison <- data.frame(
Model = character(), Sig = logical(), Normal = logical(),
Homo = logical(), Indep = logical(), AIC = numeric(), MSE = numeric(),
stringsAsFactors = FALSE
)
for (key in results_names) {
res <- results_list[[key]]
sig <- isTRUE(sig_results[[key]])
normal <- isTRUE(norm_results[[key]])
homo <- isTRUE(homo_results[[key]])
indep <- isTRUE(indep_results[[key]])
aic <- res$aic
fitted_vals <- fitted(res)
n_fit <- length(fitted_vals)
actual_fit <- tail(train_trans, n_fit)
mse <- mean((actual_fit - fitted_vals)^2, na.rm = TRUE)
comparison <- rbind(comparison, data.frame(
Model = key, Sig = sig, Normal = normal, Homo = homo, Indep = indep, AIC = aic, MSE = mse,
stringsAsFactors = FALSE
))
}
comparison %>%
arrange(AIC) %>%
mutate(across(c(AIC, MSE), ~ round(.x, 4))) %>%
tabel_gaya(
caption = "Tabel 15. Tabel Perbandingan Seluruh Model Kandidat",
col.names = c("Model", "Signifikan", "Normal", "Homogen", "Independen", "AIC", "MSE")
)| Model | Signifikan | Normal | Homogen | Independen | AIC | MSE |
|---|---|---|---|---|---|---|
| ARIMA([1,20],1,0)_Tanpa Konstanta | FALSE | TRUE | TRUE | TRUE | 1586.226 | 3377.528 |
| ARIMA([1,20],1,0)_Dengan Konstanta | FALSE | TRUE | FALSE | TRUE | 1586.592 | 3337.406 |
| ARIMA([1,20],1,1)_Tanpa Konstanta | FALSE | TRUE | TRUE | TRUE | 1587.405 | 3356.109 |
| ARIMA(1,1,0)_Tanpa Konstanta | TRUE | TRUE | TRUE | TRUE | 1587.896 | 3478.190 |
| ARIMA([1,20],1,1)_Dengan Konstanta | FALSE | TRUE | FALSE | TRUE | 1588.025 | 3322.949 |
| ARIMA(0,1,1)_Tanpa Konstanta | TRUE | TRUE | TRUE | TRUE | 1588.226 | 3486.245 |
| ARIMA(1,1,0)_Dengan Konstanta | FALSE | TRUE | TRUE | TRUE | 1588.789 | 3451.502 |
| ARIMA(0,1,1)_Dengan Konstanta | FALSE | TRUE | TRUE | TRUE | 1589.061 | 3458.067 |
| ARIMA(1,1,1)_Tanpa Konstanta | FALSE | TRUE | TRUE | TRUE | 1589.684 | 3473.006 |
| ARIMA(1,1,1)_Dengan Konstanta | FALSE | TRUE | TRUE | TRUE | 1590.634 | 3447.734 |
| ARIMA(20,1,0)_Tanpa Konstanta | FALSE | TRUE | TRUE | TRUE | 1608.692 | 3052.098 |
| ARIMA(20,1,0)_Dengan Konstanta | FALSE | TRUE | TRUE | TRUE | 1609.618 | 3029.104 |
| ARIMA(20,1,1)_Tanpa Konstanta | FALSE | TRUE | TRUE | TRUE | 1609.887 | 3033.173 |
| ARIMA(20,1,1)_Dengan Konstanta | FALSE | TRUE | TRUE | TRUE | 1610.949 | 3013.586 |
**Model terbaik terpilih: ARIMA(1,1,0)_Tanpa Konstanta** — lolos seluruh uji diagnostik (signifikansi, normalitas, homogenitas, independensi) dengan AIC = 1587.90 dan MSE = 3478.1898.
coefs_best <- coef(best_model)
if (length(coefs_best) > 0) {
data.frame(
Parameter = names(coefs_best),
Estimasi = round(coefs_best, 6)
) %>%
tabel_gaya(caption = sprintf("Tabel 16. Estimasi Parameter Model Terbaik: %s", best_key))
} else {
cat("Model terbaik tidak memiliki parameter AR/MA/konstanta yang diestimasi.\n")
}| Parameter | Estimasi |
|---|---|
| ar1 | -0.185637 |
fc_result <- forecast(best_model, h = N_TEST, level = 95)
fc_trans <- as.numeric(fc_result$mean)
lower_trans <- as.numeric(fc_result$lower)
upper_trans <- as.numeric(fc_result$upper)
if (round(lam_used) != 1) {
fc_orig <- InvBoxCox(fc_trans, lam_used)
lower_orig <- InvBoxCox(lower_trans, lam_used)
upper_orig <- InvBoxCox(upper_trans, lam_used)
} else {
fc_orig <- fc_trans
lower_orig <- lower_trans
upper_orig <- upper_trans
}
df_fc <- data.frame(
Periode = 1:N_TEST,
Tanggal = format(test_dates, "%d/%m/%Y"),
Aktual = test,
Forecast = round(fc_orig, 1),
Lower_95 = round(lower_orig, 1),
Upper_95 = round(upper_orig, 1)
)
df_fc$Error <- round(df_fc$Aktual - df_fc$Forecast, 1)
df_fc$APE_pct <- round(abs(df_fc$Error) / df_fc$Aktual * 100, 4)
df_fc %>%
tabel_gaya(
caption = sprintf("Tabel 17. Hasil Forecast vs Aktual - Model %s", best_key),
col.names = c("Periode", "Tanggal", "Aktual", "Forecast", "Lower 95%", "Upper 95%", "Error", "APE (%)")
)| Periode | Tanggal | Aktual | Forecast | Lower 95% | Upper 95% | Error | APE (%) |
|---|---|---|---|---|---|---|---|
| 1 | 23/03/2026 | 3108.0 | 3129.2 | 3012.8 | 3245.6 | -21.2 | 0.6821 |
| 2 | 24/03/2026 | 3176.0 | 3126.4 | 2976.3 | 3276.5 | 49.6 | 1.5617 |
| 3 | 25/03/2026 | 3216.0 | 3126.9 | 2947.2 | 3306.6 | 89.1 | 2.7705 |
| 4 | 26/03/2026 | 3209.0 | 3126.8 | 2922.1 | 3331.5 | 82.2 | 2.5615 |
| 5 | 27/03/2026 | 3256.0 | 3126.8 | 2899.8 | 3353.9 | 129.2 | 3.9681 |
| 6 | 30/03/2026 | 3168.0 | 3126.8 | 2879.5 | 3374.2 | 41.2 | 1.3005 |
| 7 | 31/03/2026 | 3157.0 | 3126.8 | 2860.7 | 3393.0 | 30.2 | 0.9566 |
| 8 | 01/04/2026 | 3194.0 | 3126.8 | 2843.2 | 3410.5 | 67.2 | 2.1039 |
| 9 | 02/04/2026 | 3100.0 | 3126.8 | 2826.7 | 3427.0 | -26.8 | 0.8645 |
| 10 | 03/04/2026 | 3100.0 | 3126.8 | 2811.0 | 3442.7 | -26.8 | 0.8645 |
| 11 | 06/04/2026 | 3106.0 | 3126.8 | 2796.1 | 3457.6 | -20.8 | 0.6697 |
| 12 | 07/04/2026 | 3132.0 | 3126.8 | 2781.9 | 3471.8 | 5.2 | 0.1660 |
| 13 | 08/04/2026 | 3184.0 | 3126.8 | 2768.2 | 3485.5 | 57.2 | 1.7965 |
| 14 | 09/04/2026 | 3178.0 | 3126.8 | 2755.0 | 3498.7 | 51.2 | 1.6111 |
| 15 | 10/04/2026 | 3128.0 | 3126.8 | 2742.2 | 3511.5 | 1.2 | 0.0384 |
| 16 | 13/04/2026 | 3136.0 | 3126.8 | 2729.9 | 3523.8 | 9.2 | 0.2934 |
| 17 | 14/04/2026 | 3142.0 | 3126.8 | 2717.9 | 3535.7 | 15.2 | 0.4838 |
| 18 | 15/04/2026 | 3152.0 | 3126.8 | 2706.3 | 3547.4 | 25.2 | 0.7995 |
| 19 | 16/04/2026 | 3152.0 | 3126.8 | 2695.0 | 3558.7 | 25.2 | 0.7995 |
| 20 | 17/04/2026 | 3189.0 | 3126.8 | 2684.0 | 3569.7 | 62.2 | 1.9505 |
| 21 | 20/04/2026 | 3161.0 | 3126.8 | 2673.2 | 3580.4 | 34.2 | 1.0819 |
| 22 | 21/04/2026 | 3141.0 | 3126.8 | 2662.7 | 3590.9 | 14.2 | 0.4521 |
| 23 | 22/04/2026 | 3057.0 | 3126.8 | 2652.5 | 3601.2 | -69.8 | 2.2833 |
| 24 | 23/04/2026 | 3004.0 | 3126.8 | 2642.4 | 3611.3 | -122.8 | 4.0879 |
| 25 | 24/04/2026 | 2988.5 | 3126.8 | 2632.6 | 3621.1 | -138.3 | 4.6277 |
| 26 | 27/04/2026 | 3031.0 | 3126.8 | 2622.9 | 3630.8 | -95.8 | 3.1607 |
| 27 | 28/04/2026 | 3019.0 | 3126.8 | 2613.4 | 3640.2 | -107.8 | 3.5707 |
| 28 | 30/04/2026 | 2976.5 | 3126.8 | 2604.1 | 3649.5 | -150.3 | 5.0496 |
| 29 | 01/05/2026 | 2986.0 | 3126.8 | 2595.0 | 3658.7 | -140.8 | 4.7153 |
| 30 | 07/05/2026 | 2982.0 | 3126.8 | 2586.0 | 3667.7 | -144.8 | 4.8558 |
| 31 | 08/05/2026 | 2987.5 | 3126.8 | 2577.2 | 3676.5 | -139.3 | 4.6628 |
| 32 | 11/05/2026 | 2935.0 | 3126.8 | 2568.5 | 3685.2 | -191.8 | 6.5349 |
| 33 | 12/05/2026 | 2936.5 | 3126.8 | 2559.9 | 3693.8 | -190.3 | 6.4805 |
| 34 | 13/05/2026 | 2960.5 | 3126.8 | 2551.5 | 3702.2 | -166.3 | 5.6173 |
| 35 | 14/05/2026 | 2921.0 | 3126.8 | 2543.2 | 3710.5 | -205.8 | 7.0455 |
| 36 | 15/05/2026 | 2919.5 | 3126.8 | 2535.0 | 3718.7 | -207.3 | 7.1005 |
actual <- test
forecast_vals <- fc_orig
MAPE <- mean(abs((actual - forecast_vals) / actual)) * 100
SMAPE <- mean(abs(actual - forecast_vals) / ((abs(actual) + abs(forecast_vals)) / 2)) * 100
MSE_test <- mean((actual - forecast_vals)^2)
RMSE_val <- sqrt(MSE_test)
MAE_val <- mean(abs(actual - forecast_vals))
kat <- if (MAPE < 10) {
"Sangat Baik (MAPE < 10%)"
} else if (MAPE < 20) {
"Baik (MAPE 10-20%)"
} else if (MAPE < 50) {
"Cukup (MAPE 20-50%)"
} else {
"Kurang Baik (MAPE > 50%)"
}par(mfrow = c(2, 1), mar = c(4, 4, 4, 1))
plot(train_dates, train, type = "l", col = warna_utama, lwd = 1.2,
xlim = range(dates), ylim = range(c(train, test, lower_orig, upper_orig)),
main = sprintf("Grafik Forecasting Saham Nippon Television\nModel Terbaik: %s", best_key),
xlab = "Tanggal", ylab = "Price (JPY)")
lines(test_dates, test, col = "green3", lwd = 1.5)
lines(test_dates, fc_orig, col = warna_tersier, lty = 2, lwd = 1.5)
polygon(c(test_dates, rev(test_dates)), c(lower_orig, rev(upper_orig)),
col = adjustcolor(warna_tersier, alpha.f = 0.1), border = NA)
abline(v = as.numeric(max(train_dates)), col = "gray50", lty = 3, lwd = 1)
legend("topleft",
legend = c(sprintf("Training (%d data)", N_TRAIN), sprintf("Aktual Testing (%d data)", N_TEST),
"Forecast", "CI 95%"),
col = c(warna_utama, "green3", warna_tersier, adjustcolor(warna_tersier, 0.3)),
lty = c(1, 1, 2, NA), lwd = c(1.2, 1.5, 1.5, NA),
pch = c(NA, NA, NA, 15), pt.cex = c(NA, NA, NA, 2), bty = "n")
grid(col = "gray90")
plot(test_dates, test, type = "b", col = "green3", lwd = 2, pch = 16, cex = 0.8,
ylim = range(c(test, lower_orig, upper_orig)),
main = sprintf("Zoom Area Testing (%d data) | MAPE = %.2f%% | SMAPE = %.2f%%", N_TEST, MAPE, SMAPE),
xlab = "Tanggal", ylab = "Price (JPY)")
lines(test_dates, fc_orig, col = warna_tersier, lty = 2, lwd = 2)
points(test_dates, fc_orig, col = warna_tersier, pch = 15, cex = 0.8)
polygon(c(test_dates, rev(test_dates)), c(lower_orig, rev(upper_orig)),
col = adjustcolor(warna_tersier, alpha.f = 0.15), border = NA)
legend("topleft", legend = c("Aktual", "Forecast", "CI 95%"),
col = c("green3", warna_tersier, adjustcolor(warna_tersier, 0.3)),
lty = c(1, 2, NA), pch = c(16, 15, 15), pt.cex = c(0.8, 0.8, 2), bty = "n")
grid(col = "gray90")data.frame(
Metrik = c("MAPE", "SMAPE", "MSE", "RMSE", "MAE"),
Nilai = c(
sprintf("%.4f%%", MAPE), sprintf("%.4f%%", SMAPE),
sprintf("%.4f", MSE_test), sprintf("%.4f", RMSE_val), sprintf("%.4f", MAE_val)
)
) %>%
tabel_gaya(caption = sprintf("Tabel 18. Nilai Akurasi Peramalan (Data Test, %d observasi)", N_TEST))| Metrik | Nilai |
|---|---|
| MAPE | 2.7103% |
| SMAPE | 2.6666% |
| MSE | 10688.9743 |
| RMSE | 103.3875 |
| MAE | 82.1043 |
Berdasarkan nilai MAPE sebesar 2.7103%, tingkat akurasi model tergolong kategori Sangat Baik (MAPE < 10%). Nilai SMAPE (2.6666%) yang sejalan dengan MAPE mengindikasikan konsistensi pengukuran galat, sedangkan RMSE (103.3875) dan MAE (82.1043) menggambarkan besaran kesalahan peramalan dalam satuan asli harga saham (JPY).
data.frame(
Keterangan = c(
"Total Data", "Data Training (80%)", "Data Testing (20%)",
"Model Terbaik", "Konstanta", "AIC", "BIC",
"MAPE (Data Test)", "SMAPE (Data Test)", "MSE (Data Test)", "Kategori Akurasi"
),
Nilai = c(
length(price), N_TRAIN, N_TEST,
sprintf("ARIMA(%d,%d,%d)", p_best, d_best, q_best),
ifelse(ada_konstanta, "Ada", "Tidak Ada"),
round(best_model$aic, 4), round(best_model$bic, 4),
sprintf("%.4f%%", MAPE), sprintf("%.4f%%", SMAPE), sprintf("%.4f", MSE_test), kat
)
) %>%
tabel_gaya(caption = "Tabel 19. Ringkasan Kesimpulan Akhir Analisis")| Keterangan | Nilai |
|---|---|
| Total Data | 181 |
| Data Training (80%) | 145 |
| Data Testing (20%) | 36 |
| Model Terbaik | ARIMA(1,1,0) |
| Konstanta | Tidak Ada |
| AIC | 1587.8964 |
| BIC | 1593.836 |
| MAPE (Data Test) | 2.7103% |
| SMAPE (Data Test) | 2.6666% |
| MSE (Data Test) | 10688.9743 |
| Kategori Akurasi | Sangat Baik (MAPE < 10%) |
Berdasarkan seluruh tahapan analisis yang telah dilakukan, dapat disimpulkan bahwa:
Secara keseluruhan, model ARIMA yang diperoleh melalui pendekatan Box-Jenkins mampu menangkap pola pergerakan harga saham Nippon Television Holdings Inc. dengan tingkat akurasi yang telah dievaluasi secara menyeluruh melalui uji asumsi klasik ARIMA (signifikansi parameter, normalitas, homogenitas, dan independensi residual).