1 Pendahuluan

1.1 Latar Belakang

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.

1.2 Variabel Penelitian

  1. Tanggal Perdagangan (Date) Menyatakan indeks waktu harian pengamatan harga saham, digunakan sebagai sumbu waktu pada seluruh analisis deret waktu.

  2. 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.

1.3 Karakteristik Dataset

Data yang dianalisis merupakan data historis deret waktu harga saham harian dengan struktur sebagai berikut:

  • Jumlah Observasi: 181 hari perdagangan.
  • Periode Pengamatan: 14 Agustus 2025 s.d. 15 Mei 2026.
  • Pembagian Data: 80% data training dan 20% data testing, tanpa missing value.

2 Eksplorasi Data dan Statistik Deskriptif

2.1 Tampilan Data

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)")
  )
Tabel 1. Sepuluh Observasi Pertama Dataset (Setelah Diurutkan)
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

2.2 Statistik Deskriptif

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)")
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

2.3 Eksplorasi Visual

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.

3 Konsep dan Metodologi ARIMA (Box-Jenkins)

3.1 Model ARIMA Umum

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”.

3.2 Tahapan Metodologi Box-Jenkins

Metodologi Box-Jenkins yang diterapkan pada laporan ini terdiri atas empat tahapan utama:

  1. Identifikasi (Identification) — memeriksa stasioneritas data (varian melalui Box-Cox, mean melalui uji ADF dan differencing), lalu mengidentifikasi orde \(p\) dan \(q\) melalui plot ACF dan PACF.
  2. Estimasi (Estimation) — mengestimasi parameter untuk seluruh kandidat model menggunakan Maximum Likelihood Estimation (MLE).
  3. Verifikasi Diagnostik (Diagnostic Checking) — menguji signifikansi parameter serta memeriksa asumsi residual (normalitas, homogenitas, independensi) untuk memastikan model layak digunakan.
  4. Peramalan (Forecasting) — menggunakan model terbaik yang lolos verifikasi untuk memprediksi nilai pada data testing, kemudian mengevaluasi akurasinya.

4 Uji Stasioneritas

4.1 Uji Stasioneritas dalam Varian (Box-Cox)

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")
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))
  • Metode: Estimasi \(\lambda\) optimal (metode Guerrero) melalui BoxCox.lambda().
  • Kriteria: Jika \(\lambda\) dibulatkan sama dengan 1, data dianggap sudah stasioner dalam varian.
  • Hasil: \(\lambda = 0.7757\) (dibulatkan menjadi 1).
  • Kesimpulan: Sudah stasioner dalam varian (tidak perlu transformasi).

4.2 Uji Stasioneritas dalam Mean (ADF) Sebelum Differencing

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))
  • Hipotesis: \[ \begin{aligned} H_0 &: \text{Terdapat unit root (data tidak stasioner dalam mean)} \\ H_1 &: \text{Tidak terdapat unit root (data stasioner dalam mean)} \end{aligned} \]
  • Taraf Signifikansi: \(\alpha = 0.05\).
  • Statistik Uji: \(\text{ADF} = -1.1326\) dengan \(\text{lag} = 5\) dan \(p\text{-value} = 0.9143\).
  • Kriteria Keputusan: Tolak \(H_0\) jika \(p\text{-value} < 0.05\).
  • Keputusan: Nilai \(p\text{-value}\) = 0.9143 > 0.05, maka Gagal Tolak \(H_0\).
  • Kesimpulan: Data belum stasioner dalam mean, sehingga diperlukan differencing.

4.3 Differencing dan Uji ADF Setelah Differencing

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))
  • Hipotesis: \[ \begin{aligned} H_0 &: \text{Terdapat unit root (data tidak stasioner dalam mean)} \\ H_1 &: \text{Tidak terdapat unit root (data stasioner dalam mean)} \end{aligned} \]
  • Taraf Signifikansi: \(\alpha = 0.05\).
  • Statistik Uji: \(\text{ADF} = -5.1107\) dengan \(\text{lag} = 5\) dan \(p\text{-value} = 0.0100\).
  • Kriteria Keputusan: Tolak \(H_0\) jika \(p\text{-value} < 0.05\).
  • Keputusan: Nilai \(p\text{-value}\) = 0.0100 < 0.05, maka Tolak \(H_0\).
  • Kesimpulan: Setelah differencing orde 1, data menjadi stasioner dalam mean. Orde differencing yang digunakan pada pemodelan ARIMA adalah d = 1.

5 Identifikasi Model Melalui ACF dan PACF

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)")
  )
Tabel 4. Nilai ACF dan PACF per Lag (1-20)
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")
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.

6 Pembentukan dan Estimasi Model Kandidat

6.1 Pembentukan Kandidat Model

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)))
Tabel 6. Daftar 7 Model Kandidat ARIMA
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)

6.2 Estimasi Seluruh Model Kandidat

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)))
Tabel 7. Hasil Estimasi 14 Model yang Berhasil Di-fit (Diurutkan Berdasarkan AIC)
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

7 Uji Signifikansi Parameter Seluruh Model Kandidat

  • Hipotesis (untuk setiap parameter \(\beta_j\) pada setiap kandidat model): \[ \begin{aligned} H_0 &: \beta_j = 0 \quad (\text{Parameter tidak berpengaruh signifikan}) \\ H_1 &: \beta_j \neq 0 \quad (\text{Parameter berpengaruh signifikan}) \end{aligned} \]
  • Taraf Signifikansi: \(\alpha = 0.05\), menggunakan statistik uji \(z = \hat{\beta}_j / SE(\hat{\beta}_j)\).
  • Kriteria Keputusan: Suatu model dinyatakan lolos uji signifikansi apabila seluruh parameternya memiliki \(p\text{-value} < 0.05\).
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?")
  )
Tabel 8. Estimasi Parameter dan Uji Signifikansi Seluruh Model Kandidat
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

8 Verifikasi Asumsi Residual Seluruh Model Kandidat

8.1 Uji Normalitas (Kolmogorov-Smirnov)

  • Hipotesis: \(H_0\): Residual berdistribusi normal, vs \(H_1\): Residual tidak berdistribusi normal (\(\alpha=0.05\)).
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")
  )
Tabel 9. Hasil Uji Normalitas Residual (Kolmogorov-Smirnov)
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

8.2 Uji Homogenitas (Ljung-Box Kuadrat Residual)

  • Hipotesis: \(H_0\): Ragam residual homogen (tidak ada efek ARCH), vs \(H_1\): Ragam residual tidak homogen, diuji pada lag 12, 24, dan 36 (\(\alpha=0.05\)).
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")
  )
Tabel 10. Hasil Uji Homogenitas Residual (Ljung-Box Kuadrat Residual)
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

8.3 Uji Independensi (Ljung-Box)

  • Hipotesis: \(H_0\): Residual tidak berautokorelasi (independen), vs \(H_1\): Residual berautokorelasi, diuji pada lag 12, 24, 36, dan 48 (\(\alpha=0.05\)).
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")
  )
Tabel 11. Hasil Uji Independensi Residual (Ljung-Box)
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

8.4 Probability Plot

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")
}

9 Pemilihan Model Terbaik

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")
  )
Tabel 12. Tabel Perbandingan Seluruh Model Kandidat
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.

10 Pengujian Asumsi Klasik pada Model Terpilih

Model terpilih diuji ulang secara lebih rinci untuk memastikan kelayakannya sebagai model akhir.

10.1 Uji Signifikansi Parameter Model Terpilih

10.1.1 Pengaruh Parameter ar1

Hipotesis:

\[H_0: \text{ar1} = 0 \quad \text{(Parameter tidak berpengaruh signifikan)}\]

\[H_1: \text{ar1} \neq 0 \quad \text{(Parameter berpengaruh signifikan)}\]

  • Taraf Signifikansi: \(\alpha = 0.05\).
  • Statistik Uji: \(z = -2.259\) dengan \(SE = 0.0822\) (Estimasi \(= -0.1856\)).
  • Kriteria Keputusan: Tolak \(H_0\) jika \(p\)-value \(< 0.05\).
  • Keputusan: Nilai \(p\)-value \(= 0.0239\), maka Tolak \(H_0\).
  • Kesimpulan: Parameter ar1 berpengaruh signifikan secara statistik terhadap model.

10.2 Uji Normalitas Residual Model Terpilih (Kolmogorov-Smirnov)

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))
  • Hipotesis: \[ \begin{aligned} H_0 &: \text{Residual berdistribusi normal} \\ H_1 &: \text{Residual tidak berdistribusi normal} \end{aligned} \]
  • Taraf Signifikansi: \(\alpha = 0.05\).
  • Statistik Uji: \(D = 0.0661\) dengan \(p\text{-value} = 0.5506\).
  • Kriteria Keputusan: Tolak \(H_0\) jika \(p\text{-value} < 0.05\).
  • Keputusan: Nilai \(p\text{-value}\) = 0.5506 > 0.05, maka Gagal Tolak \(H_0\).
  • Kesimpulan: Residual model terpilih berdistribusi normal, sehingga asumsi normalitas terpenuhi.

10.3 Uji Homogenitas Residual Model Terpilih (Ljung-Box Kuadrat Residual)

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))
  • Hipotesis: \[ \begin{aligned} H_0 &: \text{Ragam residual homogen (tidak ada efek ARCH)} \\ H_1 &: \text{Ragam residual tidak homogen (terdapat efek ARCH)} \end{aligned} \]
  • Taraf Signifikansi: \(\alpha = 0.05\), diuji pada lag 12, 24, dan 36.
  • Statistik Uji: \(p\text{-value}\) minimum \(= 0.1346\).
  • Kriteria Keputusan: Tolak \(H_0\) jika \(p\text{-value} < 0.05\).
  • Keputusan: Nilai \(p\text{-value}\) = 0.1346 > 0.05, maka Gagal Tolak \(H_0\).
  • Kesimpulan: Ragam residual homogen, sehingga asumsi homoskedastisitas terpenuhi.

10.4 Uji Independensi Residual Model Terpilih (Ljung-Box)

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))
  • Hipotesis: \[ \begin{aligned} H_0 &: \text{Residual tidak berautokorelasi (independen)} \\ H_1 &: \text{Residual berautokorelasi} \end{aligned} \]
  • Taraf Signifikansi: \(\alpha = 0.05\), diuji pada lag 12, 24, 36, dan 48.
  • Statistik Uji: \(p\text{-value}\) minimum \(= 0.7680\).
  • Kriteria Keputusan: Tolak \(H_0\) jika \(p\text{-value} < 0.05\).
  • Keputusan: Nilai \(p\text{-value}\) = 0.7680 > 0.05, maka Gagal Tolak \(H_0\).
  • Kesimpulan: Residual tidak berautokorelasi (independen), sehingga asumsi ini terpenuhi.

11 Model Akhir

11.1 Persamaan Model Akhir

\[ \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\).

12 Forecasting dan Evaluasi Akurasi

12.1 Hasil Forecast vs Aktual

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 (%)")
  )
Tabel 13. Hasil Forecast vs Aktual - Model ARIMA(1,1,0)_Tanpa Konstanta
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%)"
}

12.2 Grafik Forecasting

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))

12.3 Evaluasi Akurasi Peramalan

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))
Tabel 14. Nilai Akurasi Peramalan (Data Test, 36 observasi)
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).

13 Kesimpulan dan Interpretasi

  1. Stasioneritas: Hasil uji Box-Cox menunjukkan status stasioneritas varian: Sudah stasioner dalam varian (tidak perlu transformasi). Hasil uji ADF menentukan orde differencing yang digunakan adalah d = 1.
  2. Model Terbaik: Melalui tahapan identifikasi ACF/PACF, pembentukan kandidat, estimasi, uji signifikansi, dan verifikasi asumsi residual, model terbaik yang terpilih adalah ARIMA(1,1,0) dengan konstanta tidak ada, AIC = 1587.8964, dan BIC = 1593.836.
  3. Kelayakan Model: Model terpilih telah diuji ulang secara individual pada residualnya (normalitas, homogenitas, independensi) sebagaimana dipaparkan pada bagian Pengujian Asumsi Klasik pada Model Terpilih.
  4. Akurasi Peramalan: Hasil peramalan pada data testing menghasilkan MAPE = 2.7103% dan SMAPE = 2.6666%, yang termasuk dalam kategori akurasi “Sangat Baik (MAPE < 10%)”.

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.

14 Daftar Pustaka

  1. Box, G. E. P., Jenkins, G. M., Reinsel, G. C., & Ljung, G. M. (2015). Time Series Analysis: Forecasting and Control (5th ed.). Hoboken, NJ: Wiley.
  2. Hyndman, R. J., & Athanasopoulos, G. (2021). Forecasting: Principles and Practice (3rd ed.). Melbourne: OTexts. Diakses dari: https://otexts.com/fpp3/
  3. Hyndman, R. J., & Khandakar, Y. (2008). Automatic Time Series Forecasting: The forecast Package for R. Journal of Statistical Software, 27(3), 1–22.
  4. Dickey, D. A., & Fuller, W. A. (1979). Distribution of the Estimators for Autoregressive Time Series with a Unit Root. Journal of the American Statistical Association, 74(366a), 427–431.
  5. Ljung, G. M., & Box, G. E. P. (1978). On a Measure of Lack of Fit in Time Series Models. Biometrika, 65(2), 297–303.
  6. Box, G. E. P., & Cox, D. R. (1964). An Analysis of Transformations. Journal of the Royal Statistical Society: Series B, 26(2), 211–243.
  7. Trapletti, A., & Hornik, K. (2024). tseries: Time Series Analysis and Computational Finance. R package.
  8. Sumber Data: Data historis harga saham harian Nippon Television Holdings Inc. (format ekspor khas platform data pasar modal). Catatan: mohon disesuaikan dengan URL/tanggal unduh sumber data asli Anda untuk keperluan sitasi yang akurat.