Pasar modal merupakan salah satu instrumen penting dalam perekonomian karena menjadi sarana bagi perusahaan untuk memperoleh pendanaan sekaligus sarana bagi investor untuk menanamkan modal. Harga saham mencerminkan persepsi pasar terhadap kinerja dan prospek suatu perusahaan, sehingga pergerakannya bersifat fluktuatif dan dipengaruhi berbagai faktor, baik faktor fundamental perusahaan maupun faktor eksternal seperti kondisi ekonomi makro dan sentimen pasar.
Fluktuasi harga saham yang dinamis dan sulit diprediksi menimbulkan kebutuhan akan metode analisis yang mampu memodelkan pola pergerakan harga secara sistematis, sekaligus memberikan proyeksi nilai di masa mendatang sebagai dasar pengambilan keputusan investasi maupun manajemen risiko. Salah satu pendekatan yang umum digunakan dalam analisis data deret waktu finansial adalah model ARIMA (Autoregressive Integrated Moving Average) dengan metodologi Box-Jenkins, karena kemampuannya menangkap pola autokorelasi dan tren pada data historis tanpa memerlukan asumsi variabel eksogen tertentu.
Pada laporan ini, dilakukan analisis komputasi statistika terhadap data harga penutupan (closing price) saham Nippon Television Holdings Inc., sebuah perusahaan media penyiaran yang sahamnya diperdagangkan secara publik dan menunjukkan pola pergerakan harga yang fluktuatif, sehingga relevan dijadikan objek penerapan model ARIMA untuk mengevaluasi kemampuannya menangkap pola historis dan menghasilkan peramalan yang akurat.
Tanggal Perdagangan (Date)
Menyatakan indeks waktu harian pengamatan harga saham, digunakan sebagai
sumbu waktu pada seluruh analisis deret waktu.
Harga Penutupan (Price) Merupakan
harga penutupan (closing price) saham pada setiap hari
perdagangan, dinyatakan dalam mata uang Yen Jepang (JPY). Variabel
inilah yang menjadi objek utama pemodelan ARIMA pada laporan
ini.
Data yang dianalisis merupakan data historis deret waktu harga saham harian dengan struktur sebagai berikut:
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
data.frame(Tanggal = format(dates, "%d-%m-%Y"), Price = price) %>%
head(10) %>%
tabel_gaya(
caption = "Tabel 1. Sepuluh Observasi Pertama Dataset (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)]
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 = sprintf("Pembagian Data Training (%d) dan Testing (%d)", N_TRAIN, N_TEST),
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")
par(mfrow = c(1, 1))
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.
Model ARIMA(p,d,q) menggabungkan tiga komponen: Autoregressive (AR) orde \(p\) yang menjelaskan nilai saat ini berdasarkan nilai masa lalunya, Integrated (I) orde \(d\) yang merupakan proses differencing untuk mencapai stasioneritas, dan Moving Average (MA) orde \(q\) yang menjelaskan nilai saat ini berdasarkan galat peramalan masa lalu. Menggunakan notasi backshift operator \(B\) (dengan \(B Y_t = Y_{t-1}\)), model ARIMA(p,d,q) dituliskan sebagai:
\[ \phi_p(B)\,(1-B)^d\,Y_t = c + \theta_q(B)\,e_t \]
dengan:
\[ \phi_p(B) = 1 - \phi_1 B - \phi_2 B^2 - \dots - \phi_p B^p \]
\[ \theta_q(B) = 1 + \theta_1 B + \theta_2 B^2 + \dots + \theta_q B^q \]
keterangan: \(Y_t\) = nilai deret waktu pada waktu \(t\); \(\phi_i\) = koefisien AR ke-\(i\); \(\theta_j\) = koefisien MA ke-\(j\); \(c\) = konstanta; \(e_t\) = galat white noise pada waktu \(t\).
Untuk mengilustrasikan perbedaan karakteristik pola AR dan MA secara visual, berikut disimulasikan proses AR(1) dengan \(\phi=0.7\) dan proses MA(1) dengan \(\theta=0.7\):
set.seed(123)
n_ilus <- 100
ar_ilus <- arima.sim(model = list(ar = 0.7), n = n_ilus)
ma_ilus <- arima.sim(model = list(ma = 0.7), n = n_ilus)
par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
plot(ar_ilus, type = "l", col = warna_utama, lwd = 1.2,
main = "Ilustrasi Proses AR(1), \u03d5 = 0.7",
xlab = "Waktu (t)", ylab = "Nilai")
grid(col = "gray90")
plot(ma_ilus, type = "l", col = warna_aksen, lwd = 1.2,
main = "Ilustrasi Proses MA(1), \u03b8 = 0.7",
xlab = "Waktu (t)", ylab = "Nilai")
grid(col = "gray90")
par(mfrow = c(1, 1))
Proses AR menunjukkan pola pergerakan yang cenderung smooth dan memiliki momentum (nilai saat ini terpengaruh kuat oleh nilai sebelumnya), sedangkan proses MA menunjukkan pola yang lebih fluktuatif karena setiap guncangan (shock) hanya berpengaruh terbatas pada beberapa periode ke depan sebelum “dikoreksi”.
Metodologi Box-Jenkins yang diterapkan pada laporan ini terdiri atas empat tahapan utama:
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 3. 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")
par(mfrow = c(1, 1))
BoxCox.lambda().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)
p_val_adf1_str <- ifelse(adf_before$pvalue < 0.01, "< 0.01", sprintf("%.4f", adf_before$pvalue))
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")
par(mfrow = c(1, 1))
train_diff <- diff(train_trans)
train_diff_dates <- train_dates[-1]
adf_after <- uji_adf(train_diff)
p_val_adf2_str <- ifelse(adf_after$pvalue < 0.01, "< 0.01", sprintf("%.4f", adf_after$pvalue))
d <- ifelse(adf_before$pvalue < 0.05, 0, 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")
par(mfrow = c(1, 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")
par(mfrow = c(1, 1))
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 4. 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 5. 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 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 6. 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) menggunakan Maximum Likelihood Estimation. 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 7. 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 & !is.na(pvals))
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(!is.na(pvals[i]) & pvals[i] < 0.05, "Ya", "Tidak")
))
}
}
param_table %>%
tabel_gaya(
caption = "Tabel 8. 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 9. Hasil Uji Normalitas Residual (Kolmogorov-Smirnov)",
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 10. Hasil Uji Homogenitas Residual (Ljung-Box Kuadrat Residual)",
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 11. Hasil Uji Independensi Residual (Ljung-Box)",
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")
}
Model terbaik dipilih di antara kandidat yang lolos seluruh uji diagnostik (signifikansi, normalitas, homogenitas, independensi) dengan AIC terkecil. Apabila tidak ada kandidat yang lolos seluruhnya, dipilih model dengan AIC terkecil sebagai kompromi.
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 12. 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.
Model terpilih diuji ulang secara lebih rinci untuk memastikan kelayakannya sebagai model akhir.
Hipotesis:
\[H_0: \text{ar1} = 0 \quad \text{(Parameter tidak berpengaruh signifikan)}\]
\[H_1: \text{ar1} \neq 0 \quad \text{(Parameter berpengaruh signifikan)}\]
resid_final_std <- scale(resid_final)
ks_final <- ks.test(resid_final_std, "pnorm", mean = 0, sd = 1)
ks_final
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: resid_final_std
## D = 0.066108, p-value = 0.5506
## alternative hypothesis: two-sided
p_val_ks_str <- ifelse(ks_final$p.value < 0.001, "< 0.001", sprintf("%.4f", ks_final$p.value))
pvals_homo_final <- sapply(c(12, 24, 36), function(lg) Box.test(resid_final^2, lag = lg, type = "Ljung-Box")$p.value)
min_p_homo_final <- min(pvals_homo_final)
p_val_homo_str <- ifelse(min_p_homo_final < 0.001, "< 0.001", sprintf("%.4f", min_p_homo_final))
pvals_indep_final <- sapply(c(12, 24, 36, 48), function(lg) Box.test(resid_final, lag = lg, type = "Ljung-Box")$p.value)
min_p_indep_final <- min(pvals_indep_final)
p_val_indep_str <- ifelse(min_p_indep_final < 0.001, "< 0.001", sprintf("%.4f", min_p_indep_final))
\[ \hat{Y}'_t = - 0.1856\,Y'_{t-1} \]
dengan \(Y'_t\) menyatakan hasil differencing orde 1 dari harga saham pada waktu \(t\) (setelah transformasi Box-Cox bila digunakan), dan \(e_t\) adalah galat (white noise) pada waktu \(t\).
Model akhir yang digunakan adalah ARIMA(1,1,0) dengan AIC \(= 1587.8964\) dan BIC \(= 1593.836\).
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 13. 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")
par(mfrow = c(1, 1))
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 14. 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).
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.