Pendahuluan

Dalam dokumen ini, akan dilakukan analisis visual terhadap data harga saham dari tiga emiten: GGRM, ICBP, dan UNVR selama 3 tahun terakhir. Data berasal dari file .csv dan dianalisis menggunakan ggplot2, dplyr, dan lubridate.

Import dan Persiapan Data

library(ggplot2)
library(lubridate)
library(dplyr)
library(zoo)

# Import masing-masing file
ggrm <- read.csv("C:/KULIAH/Semester 6/Bintel/Data Historis GGRM.csv") %>% mutate(symbol = "GGRM")
icbp <- read.csv("C:/KULIAH/Semester 6/Bintel/Data Historis ICBP.csv") %>% mutate(symbol = "ICBP")
unvr <- read.csv("C:/KULIAH/Semester 6/Bintel/Data Historis UNVR.csv") %>% mutate(symbol = "UNVR")

# Gabungkan semua data
data_saham <- bind_rows(ggrm, icbp, unvr)

# Format tanggal dan seleksi kolom penting
datasaham <- data.frame(
  Time = as.Date(data_saham$Tanggal, format = '%d/%m/%Y'),
  Price = data_saham$Terakhir,
  Symbol = data_saham$symbol
)

Pemeriksaan Data

# Struktur data
str(datasaham)
## 'data.frame':    2169 obs. of  3 variables:
##  $ Time  : Date, format: "2025-03-27" "2025-03-26" ...
##  $ Price : num  10.2 10.35 9.88 9.85 9.95 ...
##  $ Symbol: chr  "GGRM" "GGRM" "GGRM" "GGRM" ...
# Jumlah NA pada harga
sum(is.na(datasaham$Price))
## [1] 0
# Duplikasi data
datasaham %>% group_by(Symbol, Time) %>% summarise(n = n()) %>% filter(n > 1)
## # A tibble: 0 × 3
## # Groups:   Symbol [0]
## # ℹ 3 variables: Symbol <chr>, Time <date>, n <int>
# Range tanggal & jumlah data per saham
datasaham %>% group_by(Symbol) %>% summarise(Min_Date = min(Time), Max_Date = max(Time))
## # A tibble: 3 × 3
##   Symbol Min_Date   Max_Date  
##   <chr>  <date>     <date>    
## 1 GGRM   2022-03-28 2025-03-27
## 2 ICBP   2022-03-28 2025-03-27
## 3 UNVR   2022-03-28 2025-03-27
datasaham %>% group_by(Symbol) %>% summarise(Jumlah_Data = n())
## # A tibble: 3 × 2
##   Symbol Jumlah_Data
##   <chr>        <int>
## 1 GGRM           723
## 2 ICBP           723
## 3 UNVR           723

Visualisasi Data

Plot Time Series per Saham (Facet)

ggplot(datasaham, aes(x = Time, y = Price, color = Symbol)) +
  geom_line(size = 1) +
  facet_wrap(~Symbol, scales = "free_y") +
  labs(title = "Time Series Saham GGRM, ICBP, UNVR (3 Tahun)",
       x = "Tahun", y = "Harga Saham") +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Plot Time Series Semua Saham (Dalam Satu Grafik)

ggplot(datasaham, aes(x = Time, y = Price, color = Symbol)) +
  geom_line(size = 1) +
  labs(title = "Time Series Multiple Saham (GGRM, ICBP, UNVR) - 3 Tahun",
       x = "Tahun", y = "Harga Saham") +
  theme_minimal()

Time Series dengan Garis Pemisah Tahun

ggplot(datasaham, aes(x = Time, y = Price, color = Symbol)) +
  geom_line(size = 1) +
  geom_vline(xintercept = as.numeric(as.Date(c("2022-01-01", "2023-01-01", "2024-01-01"))),
             linetype = "dashed", color = "black") +
  labs(title = "Time Series Saham dengan Pemisah Tahun",
       x = "Tahun", y = "Harga Saham") +
  theme_minimal()

Boxplot Harga Saham

ggplot(datasaham, aes(x = Symbol, y = Price, fill = Symbol)) +
  geom_boxplot() +
  labs(title = "Boxplot Harga Saham (GGRM, ICBP, UNVR)",
       x = "Saham", y = "Harga Saham") +
  theme_minimal()

Plot Moving Average (MA) 30 Hari

Moving average digunakan untuk menghaluskan data harga dan mengidentifikasi tren jangka menengah. MA 30 hari membantu melihat pergerakan rata-rata saham tiap bulan secara visual.

datasaham_ma <- datasaham %>%
  group_by(Symbol) %>%
  arrange(Time) %>%
  mutate(MA30 = rollmean(Price, k = 30, fill = NA, align = "right"))

ggplot(datasaham_ma, aes(x = Time)) +
  geom_line(aes(y = Price, color = "Harga Aktual")) +
  geom_line(aes(y = MA30, color = "MA 30 Hari"), linetype = "dashed") +
  facet_wrap(~Symbol, scales = "free_y") +
  labs(title = "Harga Saham dan Moving Average 30 Hari",
       y = "Harga", x = "Tanggal", color = "Legenda") +
  theme_minimal()
## Warning: Removed 29 rows containing missing values or values outside the scale range
## (`geom_line()`).

Return Harian Saham

Return harian memberikan gambaran volatilitas dan perubahan nilai saham dari hari ke hari. Ini penting untuk menilai risiko jangka pendek.

datasaham_ret <- datasaham %>%
  group_by(Symbol) %>%
  arrange(Time) %>%
  mutate(Return = (Price / lag(Price)) - 1)

ggplot(datasaham_ret, aes(x = Time, y = Return, color = Symbol)) +
  geom_line(alpha = 0.7) +
  facet_wrap(~Symbol, scales = "free_y") +
  labs(title = "Return Harian Saham",
       x = "Tanggal", y = "Return (%)") +
  theme_minimal()
## Warning: Removed 3 rows containing missing values or values outside the scale range
## (`geom_line()`).

Distribusi Harga (Density Plot)

Distribusi harga memperlihatkan di rentang berapa harga saham paling sering muncul.

ggplot(datasaham, aes(x = Price, fill = Symbol)) +
  geom_density(alpha = 0.5) +
  labs(title = "Distribusi Harga Saham (Density Plot)",
       x = "Harga", y = "Kerapatan") +
  theme_minimal()