Tentang Proyek Portofolio Ini

Dokumen ini merupakan bagian dari rangkaian analisis peramalan kurs USD/IDR periode 2021–2025 menggunakan pemodelan stokastik Geometric Brownian Motion (GBM) dan Simulasi Monte Carlo. Proyek ini bertujuan untuk mengestimasi lintasan nilai tukar harian ke depan berdasarkan volatilitas dan drift historis.

Struktur Publikasi:

  1. [Data Wrangling] Persiapan & Transformasi Data
  2. [Statistik Deskriptif] Eksplorasi Deret Waktu
  3. [Uji Normalitas] Pengujian Asumsi Distribusi Log-Return
  4. [Simulasi] Estimasi Parameter & Monte Carlo
  5. [Analisis] Interval Kepercayaan & Proyeksi Final

🔗 Tautan Terkait: GitHub Repository | Dashboard Interaktif R Shiny


1 Latar Belakang

Model GBM mengasumsikan bahwa log-return harian (\(r_t\)) berdistribusi normal:

\[r_t = \ln\left(\frac{S_t}{S_{t-1}}\right) \sim \mathcal{N}(\mu,\ \sigma^2)\]

Apabila asumsi ini tidak terpenuhi, hasil simulasi Monte Carlo perlu diinterpretasikan dengan kehati-hatian. Validasi dilakukan melalui dua pendekatan:

  1. Uji Kolmogorov-Smirnov (KS Test) — dipilih karena \(n > 1.000\) (Shapiro-Wilk tidak direkomendasikan untuk sampel besar)
  2. Uji Jarque-Bera — menguji normalitas berdasarkan skewness dan kurtosis secara simultan

2 Persiapan: Memuat Paket & Data

2.1 Memuat Paket

# Manajemen data
library(dplyr)

# Uji statistik
library(tseries)    # Uji Jarque-Bera

# Tabel output
library(knitr)
library(kableExtra)

#visualisasi
library(ggplot2)
library(scales)

Instalasi: Jalankan install.packages(c("dplyr", "tseries", "knitr", "kableExtra")) jika paket belum tersedia.

2.2 Memuat Data Return

# Baca langsung dari CSV — tidak bergantung pada file RDS
df_raw <- read.csv(
"../data/Data Historis USD_IDR.csv",
  header           = TRUE,
  stringsAsFactors = FALSE,
  fileEncoding     = "UTF-8-BOM"
)

# Wrangling ulang (ringkas)
df_usd_idr <- df_raw %>%
  select(Tanggal, Terakhir) %>%
  mutate(
    Kurs    = as.numeric(gsub(",", ".", gsub("\\.", "", Terakhir))),
    Tanggal = as.Date(Tanggal, format = "%d/%m/%Y")
  ) %>%
  select(Tanggal, Kurs) %>%
  arrange(Tanggal)

# Hitung log-return
df_return <- df_usd_idr %>%
  mutate(Log_Return = log(Kurs / lag(Kurs))) %>%
  filter(!is.na(Log_Return))

rt <- df_return$Log_Return

cat("Data berhasil dimuat dari CSV.\n")
## Data berhasil dimuat dari CSV.
cat("Jumlah observasi :", length(rt), "\n")
## Jumlah observasi : 1267
cat("Periode          :", format(min(df_return$Tanggal), "%d %B %Y"),
    "–", format(max(df_return$Tanggal), "%d %B %Y"), "\n")
## Periode          : 04 January 2021 – 31 December 2025
cat("Mean return (µ)  :", round(mean(rt), 8), "\n")
## Mean return (µ)  : 0.00012605
cat("Std dev (σ)      :", round(sd(rt),   8), "\n")
## Std dev (σ)      : 0.00321561

3 Tahap 1 — Uji Kolmogorov-Smirnov (KS Test)

3.1 Dasar Teori

Uji KS membandingkan fungsi distribusi kumulatif empiris (ECDF) dari data sampel dengan CDF distribusi normal teoretis. Hipotesis yang diuji:

  • \(H_0\): Data log-return berdistribusi normal
  • \(H_1\): Data log-return tidak berdistribusi normal

Keputusan diambil pada tingkat signifikansi \(\alpha = 0{,}05\): - Jika \(p\text{-value} \geq 0{,}05\)Gagal tolak \(H_0\) (distribusi normal) - Jika \(p\text{-value} < 0{,}05\)Tolak \(H_0\) (tidak normal)

3.2 Pelaksanaan Uji

# Uji KS: bandingkan data dengan distribusi normal N(µ, σ²)
ks_result <- ks.test(
  x    = rt,
  y    = "pnorm",
  mean = mean(rt),
  sd   = sd(rt)
)

# Tampilkan output mentah
print(ks_result)
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  rt
## D = 0.088672, p-value = 4.448e-09
## alternative hypothesis: two-sided

3.3 Ringkasan Hasil KS Test

ks_table <- data.frame(
  Komponen = c(
    "Metode Uji",
    "Jumlah Observasi (n)",
    "Statistik D",
    "p-value",
    "Tingkat Signifikansi (α)",
    "Keputusan",
    "Kesimpulan"
  ),
  Hasil = c(
    "Kolmogorov-Smirnov One-Sample Test",
    formatC(length(rt), format = "d"),
    formatC(ks_result$statistic, format = "f", digits = 6),
    ifelse(ks_result$p.value < 0.001,
           "< 0,001",
           formatC(ks_result$p.value, format = "f", digits = 6)),
    "0,05",
    ifelse(ks_result$p.value < 0.05, "Tolak H₀", "Gagal Tolak H₀"),
    ifelse(ks_result$p.value < 0.05,
           "Log-return TIDAK berdistribusi normal",
           "Log-return berdistribusi normal")
  )
)

kable(ks_table,
      caption = "Tabel 1.1 — Hasil Uji Kolmogorov-Smirnov",
      align   = c("l", "l"),
      col.names = c("Komponen", "Hasil")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "bordered"),
                full_width = FALSE) %>%
  row_spec(6, bold = TRUE,
           color     = ifelse(ks_result$p.value < 0.05, "white", "white"),
           background = ifelse(ks_result$p.value < 0.05, "#c0392b", "#27ae60")) %>%
  row_spec(7, bold = TRUE, color = "#2c3e50",
           background = ifelse(ks_result$p.value < 0.05, "#fdecea", "#eafaf1"))
Tabel 1.1 — Hasil Uji Kolmogorov-Smirnov
Komponen Hasil
Metode Uji Kolmogorov-Smirnov One-Sample Test
Jumlah Observasi (n) 1267
Statistik D 0.088672
p-value < 0,001
Tingkat Signifikansi (α) 0,05
Keputusan Tolak H₀
Kesimpulan Log-return TIDAK berdistribusi normal

4 Tahap 2 — Uji Jarque-Bera

4.1 Dasar Teori

Uji Jarque-Bera (JB) menguji normalitas berdasarkan skewness dan kurtosis secara bersamaan menggunakan statistik:

\[JB = \frac{n}{6}\left(S^2 + \frac{(K-3)^2}{4}\right)\]

di mana \(S\) adalah skewness dan \(K\) adalah kurtosis sampel. Di bawah \(H_0\), statistik JB mengikuti distribusi \(\chi^2\) dengan 2 derajat kebebasan.

  • \(H_0\): Data berdistribusi normal (\(S = 0\) dan \(K = 3\))
  • \(H_1\): Data tidak berdistribusi normal

4.2 Pelaksanaan Uji

# Uji Jarque-Bera menggunakan paket tseries
jb_result <- jarque.bera.test(rt)

# Tampilkan output mentah
print(jb_result)
## 
##  Jarque Bera Test
## 
## data:  rt
## X-squared = 1116.3, df = 2, p-value < 2.2e-16

4.3 Pelaksanaan Uji

# Uji KS: bandingkan data dengan distribusi normal N(µ, σ²)
ks_result <- ks.test(
  x    = rt,
  y    = "pnorm",
  mean = mean(rt),
  sd   = sd(rt)
)

# Tampilkan output mentah
print(ks_result)
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  rt
## D = 0.088672, p-value = 4.448e-09
## alternative hypothesis: two-sided

4.4 Ringkasan Hasil KS Test

ks_table <- data.frame(
  Komponen = c(
    "Metode Uji",
    "Jumlah Observasi (n)",
    "Statistik D",
    "p-value",
    "Tingkat Signifikansi (α)",
    "Keputusan",
    "Kesimpulan"
  ),
  Hasil = c(
    "Kolmogorov-Smirnov One-Sample Test",
    formatC(length(rt), format = "d"),
    formatC(ks_result$statistic, format = "f", digits = 6),
    ifelse(ks_result$p.value < 0.001,
           "< 0,001",
           formatC(ks_result$p.value, format = "f", digits = 6)),
    "0,05",
    ifelse(ks_result$p.value < 0.05, "Tolak H₀", "Gagal Tolak H₀"),
    ifelse(ks_result$p.value < 0.05,
           "Log-return TIDAK berdistribusi normal",
           "Log-return berdistribusi normal")
  )
)

kable(ks_table,
      caption = "Tabel 1.1 — Hasil Uji Kolmogorov-Smirnov",
      align   = c("l", "l"),
      col.names = c("Komponen", "Hasil")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "bordered"),
                full_width = FALSE) %>%
  row_spec(6, bold = TRUE,
           color     = "white",
           background = ifelse(ks_result$p.value < 0.05, "#c0392b", "#27ae60")) %>%
  row_spec(7, bold = TRUE, color = "#2c3e50",
           background = ifelse(ks_result$p.value < 0.05, "#fdecea", "#eafaf1"))
Tabel 1.1 — Hasil Uji Kolmogorov-Smirnov
Komponen Hasil
Metode Uji Kolmogorov-Smirnov One-Sample Test
Jumlah Observasi (n) 1267
Statistik D 0.088672
p-value < 0,001
Tingkat Signifikansi (α) 0,05
Keputusan Tolak H₀
Kesimpulan Log-return TIDAK berdistribusi normal

5 Tahap 2 — Uji Jarque-Bera

5.1 Pelaksanaan Uji

# Uji Jarque-Bera menggunakan paket tseries
jb_result <- jarque.bera.test(rt)

# Tampilkan output mentah
print(jb_result)
## 
##  Jarque Bera Test
## 
## data:  rt
## X-squared = 1116.3, df = 2, p-value < 2.2e-16

5.2 Ringkasan Hasil Jarque-Bera

# Hitung skewness dan kurtosis manual untuk ditampilkan
n    <- length(rt)
mu   <- mean(rt)
sig  <- sd(rt)
skew <- (n / ((n-1)*(n-2))) * sum(((rt - mu) / sig)^3)
kurt <- (n*(n+1)/((n-1)*(n-2)*(n-3))) *
        sum(((rt - mu)/sig)^4) -
        3*(n-1)^2/((n-2)*(n-3))

jb_table <- data.frame(
  Komponen = c(
    "Metode Uji",
    "Jumlah Observasi (n)",
    "Skewness (S)",
    "Excess Kurtosis (K−3)",
    "Statistik JB",
    "Derajat Kebebasan",
    "p-value",
    "Tingkat Signifikansi (α)",
    "Keputusan",
    "Kesimpulan"
  ),
  Hasil = c(
    "Jarque-Bera Test",
    formatC(n, format = "d"),
    formatC(skew, format = "f", digits = 6),
    formatC(kurt, format = "f", digits = 6),
    formatC(jb_result$statistic, format = "f", digits = 4),
    "2",
    ifelse(jb_result$p.value < 0.001,
           "< 0,001",
           formatC(jb_result$p.value, format = "f", digits = 6)),
    "0,05",
    ifelse(jb_result$p.value < 0.05, "Tolak H₀", "Gagal Tolak H₀"),
    ifelse(jb_result$p.value < 0.05,
           "Log-return TIDAK berdistribusi normal",
           "Log-return berdistribusi normal")
  )
)

kable(jb_table,
      caption = "Tabel 2.1 — Hasil Uji Jarque-Bera",
      align   = c("l", "l"),
      col.names = c("Komponen", "Hasil")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "bordered"),
                full_width = FALSE) %>%
  row_spec(9, bold = TRUE,
           color      = "white",
           background = ifelse(jb_result$p.value < 0.05, "#c0392b", "#27ae60")) %>%
  row_spec(10, bold = TRUE, color = "#2c3e50",
           background = ifelse(jb_result$p.value < 0.05, "#fdecea", "#eafaf1")) %>%
  pack_rows("Input Statistik", 3, 5) %>%
  pack_rows("Hasil Uji", 6, 10)
Tabel 2.1 — Hasil Uji Jarque-Bera
Komponen Hasil
Metode Uji Jarque-Bera Test
Jumlah Observasi (n) 1267
Input Statistik
Skewness (S) -0.434896
Excess Kurtosis (K−3) 4.538207
Statistik JB 1116.2937
Hasil Uji
Derajat Kebebasan 2
p-value < 0,001
Tingkat Signifikansi (α) 0,05
Keputusan Tolak H₀
Kesimpulan Log-return TIDAK berdistribusi normal

6 Tahap 2.5 — Visualisasi Distribusi dan Uji Grafis

Untuk melengkapi pengujian formal di atas, bagian ini menyajikan evaluasi visual menggunakan histogram (dengan overlay kurva teoretis) dan QQ-Plot.

6.1 Histogram Distribusi Log-Return

library(ggplot2)

df_plot_rt <- data.frame(Log_Return = rt)

plot_hist <- ggplot(df_plot_rt, aes(x = Log_Return)) +
  geom_histogram(aes(y = ..density..), bins = 50, 
                 fill = "#34495e", colour = "white", alpha = 0.8) +
  geom_density(colour = "#e74c3c", linewidth = 1) +
  stat_function(
    fun = dnorm,
    args = list(mean = mean(rt), sd = sd(rt)),
    colour = "#2ecc71", linewidth = 1, linetype = "dashed"
  ) +
  labs(
    title = "Histogram Log-Return USD/IDR vs Kurva Normal Teoretis",
    subtitle = "Garis Merah = Kepadatan Empiris | Garis Hijau Putus-putus = Distribusi Normal Sempurna",
    x = "Log-Return Harian",
    y = "Density"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    plot.title = element_text(face = "bold", colour = "#1a252f"),
    panel.grid.major = element_line(colour = "#dce3ea", linewidth = 0.4)
  )

# Tampilkan di dokumen HTML
plot_hist

# Simpan ke laptop
ggsave("plot_histogram_return.png", plot = plot_kurs_or_hist <- plot_hist, width = 10, height = 5, dpi = 300)

6.2 Quantile-Quantile Plot (QQ-Plot)

plot_qq <- ggplot(df_plot_rt, aes(sample = Log_Return)) +
  stat_qq(colour = "#3498db", alpha = 0.6, size = 1.5) +
  stat_qq_line(colour = "#e74c3c", linewidth = 0.8, linetype = "dashed") +
  labs(
    title = "QQ-Plot Log-Return USD/IDR",
    subtitle = "Penyimpangan di ujung garis mengonfirmasi fenomena Fat Tails (Ekor Tebbal)",
    x = "Kuantil Teoretis (Normal)",
    y = "Kuantil Sampel (Empiris)"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    plot.title = element_text(face = "bold", colour = "#1a252f"),
    panel.grid.major = element_line(colour = "#dce3ea", linewidth = 0.4)
  )

# Tampilkan di dokumen HTML
plot_qq

# Simpan ke laptop
ggsave("plot_qq_return.png", plot = plot_qq, width = 8, height = 5.5, dpi = 300)

7 Tahap 3 — Rekapitulasi Kedua Uji

recap <- data.frame(
  Uji = c("Kolmogorov-Smirnov", "Jarque-Bera"),
  Statistik = c(
    formatC(ks_result$statistic, format = "f", digits = 6),
    formatC(jb_result$statistic, format = "f", digits = 4)
  ),
  p_value = c(
    ifelse(ks_result$p.value < 0.001, "< 0,001",
           formatC(ks_result$p.value, format = "f", digits = 6)),
    ifelse(jb_result$p.value < 0.001, "< 0,001",
           formatC(jb_result$p.value, format = "f", digits = 6))
  ),
  Keputusan = c(
    ifelse(ks_result$p.value < 0.05, "Tolak H₀", "Gagal Tolak H₀"),
    ifelse(jb_result$p.value < 0.05, "Tolak H₀", "Gagal Tolak H₀")
  ),
  Keterangan = c(
    "Berbasis jarak ECDF vs CDF normal",
    "Berbasis skewness & kurtosis simultan"
  )
)

kable(recap,
      caption = "Tabel 3.1 — Rekapitulasi Hasil Uji Normalitas",
      align   = c("l", "r", "r", "c", "l"),
      col.names = c("Uji", "Statistik", "p-value", "Keputusan", "Keterangan")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "bordered"),
                full_width = TRUE) %>%
  column_spec(4, bold = TRUE,
              color      = "white",
              background = ifelse(
                c(ks_result$p.value, jb_result$p.value) < 0.05,
                "#c0392b", "#27ae60"
              ))
Tabel 3.1 — Rekapitulasi Hasil Uji Normalitas
Uji Statistik p-value Keputusan Keterangan
D Kolmogorov-Smirnov 0.088672 < 0,001 Tolak H₀ Berbasis jarak ECDF vs CDF normal
X-squared Jarque-Bera 1116.2937 < 0,001 Tolak H₀ Berbasis skewness & kurtosis simultan

8 Tahap 4 — Interpretasi & Implikasi GBM

8.1 Interpretasi Hasil

## === INTERPRETASI HASIL UJI NORMALITAS ===
## Uji Kolmogorov-Smirnov : TOLAK H₀ (D = 0.088672, p < 0,001)
## Uji Jarque-Bera        : TOLAK H₀ (JB = 1116.2937, p < 0,001)
## Kedua uji secara konsisten menolak hipotesis nol pada α = 0,05.
## Artinya, log-return USD/IDR secara formal TIDAK berdistribusi normal sempurna.
## 
## Penyebab utama penolakan:
##   • Skewness = -0.4349 → distribusi tidak simetris sempurna
##   • Excess kurtosis = 4.5382 → ekor distribusi lebih tebal dari normal
##     (fenomena 'fat tails' yang umum pada data keuangan)

8.2 Implikasi terhadap Penggunaan GBM

## === IMPLIKASI TERHADAP MODEL GBM ===
## Meskipun uji formal menolak normalitas sempurna, GBM tetap
## dapat digunakan dengan pertimbangan berikut:
## 1. JUSTIFIKASI PENGGUNAAN GBM:
##    • GBM adalah model standar industri untuk pemodelan harga aset keuangan
##      (Black-Scholes, 1973) dan tetap digunakan secara luas meskipun
##      normalitas tidak terpenuhi secara sempurna.
##    • Penyimpangan terjadi terutama di ekor distribusi (return ekstrem),
##      sementara bagian tengah (return normal sehari-hari) mendekati normal.
##    • Central Limit Theorem mendukung pendekatan normal untuk return
##      agregat dalam jangka panjang.
## 2. CATATAN PENTING DALAM INTERPRETASI:
##    • Interval kepercayaan dari simulasi Monte Carlo mungkin UNDERESTIMATE
##      risiko ekstrem (krisis, shock mendadak) karena ekor lebih tebal.
##    • Hasil simulasi lebih valid untuk kondisi normal (bukan krisis).
##    • Semakin panjang horizon simulasi, asumsi normalitas semakin kritis.
## 3. KEPUTUSAN:
##    ✓ GBM LAYAK digunakan untuk simulasi Monte Carlo kurs USD/IDR
##      dengan catatan interpretasi di atas.

9 Tahap 5 — Simpan Hasil Uji

# Simpan hasil uji normalitas untuk referensi laporan
hasil_normalitas <- list(
  ks_statistic  = as.numeric(ks_result$statistic),
  ks_pvalue     = ks_result$p.value,
  ks_keputusan  = ifelse(ks_result$p.value < 0.05, "Tolak H0", "Gagal Tolak H0"),
  jb_statistic  = as.numeric(jb_result$statistic),
  jb_pvalue     = jb_result$p.value,
  jb_keputusan  = ifelse(jb_result$p.value < 0.05, "Tolak H0", "Gagal Tolak H0"),
  skewness      = skew,
  excess_kurt   = kurt,
  gbm_layak     = TRUE,   # Keputusan akhir penggunaan GBM
  catatan       = "GBM layak digunakan dengan catatan fat tails"
)

saveRDS(hasil_normalitas, "hasil_normalitas.rds")

cat("✓ Hasil uji disimpan ke: hasil_normalitas.rds\n\n")
## ✓ Hasil uji disimpan ke: hasil_normalitas.rds
cat("=== RINGKASAN UNTUK LAPORAN ===\n")
## === RINGKASAN UNTUK LAPORAN ===
cat(sprintf("KS Test  : D = %.6f, p %s → %s\n",
    hasil_normalitas$ks_statistic,
    ifelse(hasil_normalitas$ks_pvalue < 0.001, "< 0,001",
           round(hasil_normalitas$ks_pvalue, 6)),
    hasil_normalitas$ks_keputusan))
## KS Test  : D = 0.088672, p < 0,001 → Tolak H0
cat(sprintf("JB Test  : JB = %.4f, p %s → %s\n",
    hasil_normalitas$jb_statistic,
    ifelse(hasil_normalitas$jb_pvalue < 0.001, "< 0,001",
           round(hasil_normalitas$jb_pvalue, 6)),
    hasil_normalitas$jb_keputusan))
## JB Test  : JB = 1116.2937, p < 0,001 → Tolak H0
cat(sprintf("Skewness : %.4f\n", hasil_normalitas$skewness))
## Skewness : -0.4349
cat(sprintf("Ex. Kurt : %.4f\n", hasil_normalitas$excess_kurt))
## Ex. Kurt : 4.5382
cat(sprintf("GBM Layak: %s\n",   hasil_normalitas$gbm_layak))
## GBM Layak: TRUE

10 Ringkasan Bagian 4

Tabel 5.1 — Ringkasan Aktivitas Bagian 4
Sub-Tahap Aktivitas Output Utama
4.1 Uji Kolmogorov-Smirnov Statistik D, p-value, keputusan H₀
4.2 Uji Jarque-Bera Statistik JB, p-value, keputusan H₀
4.3 Rekapitulasi kedua uji Tabel perbandingan kedua uji
4.4 Interpretasi & implikasi GBM Justifikasi kelayakan GBM
4.5 Simpan hasil uji hasil_normalitas.rds

11 Langkah Selanjutnya

Dengan validasi normalitas yang sudah dilakukan, analisis berlanjut ke tahap inti:

  • Bagian 5 — Estimasi Parameter GBM: Menggunakan \(\mu\) dan \(\sigma\) dari Bagian 2 untuk mendefinisikan proses stokastik kurs secara formal.
  • Bagian 6 — Simulasi Monte Carlo: Mensimulasikan 1.000, 5.000, dan 10.000 lintasan kurs ke depan menggunakan persamaan GBM diskrit:

\[S_{t+\Delta t} = S_t \cdot \exp\left[\left(\mu - \frac{\sigma^2}{2}\right)\Delta t + \sigma\sqrt{\Delta t}\,Z_t\right], \quad Z_t \sim \mathcal{N}(0,1)\]


sessionInfo()
## R version 4.5.1 (2025-06-13 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26200)
## 
## Matrix products: default
##   LAPACK version 3.12.1
## 
## locale:
## [1] LC_COLLATE=English_United States.utf8 
## [2] LC_CTYPE=English_United States.utf8   
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C                          
## [5] LC_TIME=English_United States.utf8    
## 
## time zone: Asia/Jakarta
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] scales_1.4.0     ggplot2_4.0.2    kableExtra_1.4.0 knitr_1.51      
## [5] tseries_0.10-61  dplyr_1.2.0     
## 
## loaded via a namespace (and not attached):
##  [1] sass_0.4.10        generics_0.1.4     xml2_1.5.2         stringi_1.8.7     
##  [5] lattice_0.22-7     digest_0.6.38      magrittr_2.0.4     evaluate_1.0.5    
##  [9] grid_4.5.1         RColorBrewer_1.1-3 fastmap_1.2.0      jsonlite_2.0.0    
## [13] viridisLite_0.4.2  textshaping_1.0.5  jquerylib_0.1.4    cli_3.6.5         
## [17] rlang_1.1.7        withr_3.0.2        cachem_1.1.0       yaml_2.3.12       
## [21] otel_0.2.0         tools_4.5.1        curl_7.0.0         vctrs_0.7.1       
## [25] R6_2.6.1           zoo_1.8-15         lifecycle_1.0.5    stringr_1.6.0     
## [29] ragg_1.5.1         pkgconfig_2.0.3    pillar_1.11.1      bslib_0.10.0      
## [33] gtable_0.3.6       glue_1.8.0         quantmod_0.4.28    systemfonts_1.3.2 
## [37] xfun_0.56          tibble_3.3.0       tidyselect_1.2.1   rstudioapi_0.18.0 
## [41] farver_2.1.2       htmltools_0.5.9    labeling_0.4.3     rmarkdown_2.30    
## [45] xts_0.14.1         svglite_2.2.2      compiler_4.5.1     quadprog_1.5-8    
## [49] S7_0.2.1           TTR_0.24.4

Dokumen ini merupakan bagian dari seri analisis kurs USD/IDR menggunakan pendekatan Geometric Brownian Motion dan Simulasi Monte Carlo.