Optimasi Portofolio

Ujian Akhir Semester Optimasi


Kontak : \(\downarrow\)
Email
Instagram https://www.instagram.com/arifin.alicia/
RPubs https://rpubs.com/aliciaarifin/
Nama Alicia Arifin
NIM 20214920001
Prodi Statistika, 2021

Optimaisasi Portofolio

Silahkan cari 5 data saham pada Bursa Efek Indonesia yang termaksud pada saham LQ45. Dari data saham tersebut buta simulasi di R dengan menentukan: - Return saham - Matriks kovariansi - Rata-rata pengembalian portofoli saham - Risiko portofolio saham - Bobot portofolio optimum dari 5 saham

Import Library

library(tidyquant) # untuk mengunduh data
library(highcharter) # visualisasi
library(timetk)
library(dplyr)
library(tidyr)
library(DT)

Saya akan menggunakan 5 perusahaan yang bergerak di bidang tambang yaitu ITMG, INCO, MEDC, ANTM dan ADRO.
Berikut nama perusahaannya : - ADRO, ADARO ENERGY Tbk - ANTM, Aneka Tambang (Persero) Tbk - INCO, Vale Indonesia Tbk - ITMG, Indo Tambangraya Megah Tbk - MEDC, Medco Energi Internasional Tbk

stock <- c("ITMG.JK","INCO.JK","MEDC.JK","ANTM.JK","ADRO.JK")

price_data <- tq_get(stock,
                     from = "2023-01-01",
                     to   = Sys.Date(),
                     get  = "stock.prices")

tail(price_data)

Return

Selanjutnya kita akan menghitung Return per-harinya dengan menggunakan prengembalian logaritmik. Menggunakan pengembalian logaritmik untuk memastikan data stasioner.

log_ret_tidy = price_data %>%
  group_by(symbol)%>%
  tq_transmute(select = adjusted,
            mutate_fun = periodReturn,
            period= "daily",
            type="log")

datatable(log_ret_tidy)

Setelah didapat return per-harinya, kita akan mencoba untuk menggabungkan return per-hari menjadi satu tabel dari baris menjadi kolom. fungsi spread() digunakan untuk mengubah menjadi format lebar, dan juga kita akan menggunakan fungsi xts().

log_ret_xts <- log_ret_tidy%>%
  spread(symbol, value=daily.returns)%>%
  tk_xts()

datatable(log_ret_xts)

Rata-rata Pengembalian

Pada tahap ini kita akan menghitung rata-rata return per-hari untuk setiap aset

mean_return <- colMeans(log_ret_xts)
round(mean_return,5)
##  ADRO.JK  ANTM.JK  INCO.JK  ITMG.JK  MEDC.JK 
## -0.00094 -0.00064 -0.00220 -0.00093  0.00027

Pada rata-rata, diantara kelima perusahaan tersebut dapat menghasilkan return perhari sebesar 0.0029-0.157% per-harinya.

Matriks Kovariansi

Menghitung matriks kovarians untuk semua data saham dengan mengalikannya dengan 252 dalam format tahunan.

cov_mat <- cov(log_ret_xts)*252
round(cov_mat,4)
##         ADRO.JK ANTM.JK INCO.JK ITMG.JK MEDC.JK
## ADRO.JK  0.1388  0.0310  0.0235  0.1017  0.0933
## ANTM.JK  0.0310  0.0681  0.0327  0.0283  0.0375
## INCO.JK  0.0235  0.0327  0.0838  0.0218  0.0484
## ITMG.JK  0.1017  0.0283  0.0218  0.1298  0.0764
## MEDC.JK  0.0933  0.0375  0.0484  0.0764  0.3462

Penerapan Metode Portofolio

Perhitungan return dan resiko portofolio (standar deviasi) merupakan metode yang dilakukan sebelum menerapkan metode portofolio.

# membuat bobot acak 
wts <- runif(n = length(stock))
wts <- wts/sum(wts)

# rata-rata returns aset
port_returns <- (sum(wts * mean_return) + 1)^252 - 1

#Risiko portofolio
port_risk <- sqrt(t(wts) %*% (cov_mat %*% wts))

# Bobot portofolio Shape Ratio
sharpe_ratio <- port_returns/port_risk

Lalu, kita akan lakukan proses pembentukan portofolio secara acak dengan simulasi 5000. Kita mengsimulasikannya karena kita ingin memastikan siknifikansinya secara statistik.


Persiapkan vektor kosong untuk masing-masing langkah di atas:

num_port <- 5000

# matriks kosong untuk menyimpan bobot
all_wts <- matrix(nrow = num_port, ncol = length(stock))

# vektor kosong untuk menyimpan return portofolio
port_returns <- vector('numeric', length = num_port)

# vektor kosong untuk menyimpan standar deviasi portofolio
port_risk <- vector('numeric', length = num_port)

# vektor kosong untuk menyimpan portofolio shape ratio
sharpe_ratio <- vector('numeric', length = num_port)

Mari kita loop ke 5000 kali.

for (i in seq_along(port_returns)) {
  
  wts <- runif(length(stock))
  wts <- wts/sum(wts)
  
  all_wts[i,] <- wts
  
  
  port_ret <- sum(wts * mean_return)
  port_ret <- ((port_ret + 1)^252) - 1
  
  port_returns[i] <- port_ret
  
  
  port_sd <- sqrt(t(wts) %*% (cov_mat  %*% wts))
  port_risk[i] <- port_sd
  
  sr <- port_ret/port_sd
  sharpe_ratio[i] <- sr
  
}

Pada codingan di bawah ini kita akan membuat tabel data untuk menyimpan semua nilai secara bersamaan.

portfolio_values <- tibble(Return = port_returns,
                             Risk = port_risk,
                      SharpeRatio = sharpe_ratio)

# mengubah matriks menjadi tampilan tibble
all_wts <- tk_tbl(all_wts)

# mengganti nama kolom
colnames(all_wts) <- colnames(log_ret_xts)

portfolio_values <- tk_tbl(cbind(all_wts, portfolio_values))
datatable(portfolio_values)

Sekarang kita punya bobot di setiap aset dengan risiko, return dan shape ratio dari setiap portofolionya.
Sekarang kita akan coba melihat portofolio mana yang paling penting dengan varians minimum dan juga shape ratio tertinggi. ## Variansi Minimum

library(forcats)
library(ggplot2)
library(plotly)

min_var <- portfolio_values[which.min(portfolio_values$Risk),]

p <- min_var %>%
  gather(ADRO.JK:MEDC.JK, key = Asset,
         value = Weights) %>%
  mutate(Asset = as.factor(Asset)) %>%
  ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
  geom_bar(stat = 'identity') +
  theme_minimal() +
  labs(x = 'Aset', 
       y = 'Bobot', 
       title = "Bobot Portofolio dengan Variansi Minimum") +
  scale_y_continuous(labels = scales::percent) +
  theme(legend.position = "none" )

ggplotly(p)

Kalau dilihat dari hasil plot di atas, dapat dilihat bahwa portofolio varian minimum tidak mmeiliki alokasi untuk saham MEDC dan ADRO. Mayoritas portofolio diinvestasikan di saham ANTM, INCO dan ITMG. Perusahaan ANTM memiliki bobot sebesar 42,62%, INCO sebesar 29,92% dan ITMG sebesar 21,28%. Kalau dilihat jumlah Bobot MEDC dan ADRO tidak mencapai 10%.

Portofolio Tangensi

max_sr <- portfolio_values[which.max(portfolio_values$SharpeRatio),]

p <- max_sr %>%
  gather(ADRO.JK:MEDC.JK, key = Asset,
         value = Weights) %>%
  mutate(Asset = as.factor(Asset)) %>%
  ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
  geom_bar(stat = 'identity') +
  theme_minimal() +
  labs(x = 'Aset', 
       y = 'Bobot', 
       title = "Bobot Portofolio Tangensi (Maksimum Sharpe Ratio)") +
  scale_y_continuous(labels = scales::percent) +
  theme(legend.position = "none" )

ggplotly(p)

Rupanya portofolio dengan shape ratio tertingginya hanya memiliki sedikit investasi di INCO dan ANTM. Bobot portofolio tangensi maksimum ada di MEDC.

Batas Efisien Portofolio

Mari memplot semua portofolio acak dan memvisualisasikan batas efisien.

p <- portfolio_values %>%
  ggplot(aes(x = Risk, y = Return, color = SharpeRatio)) +
  geom_point() +
  theme_classic() +
  scale_y_continuous(labels = scales::percent) +
  scale_x_continuous(labels = scales::percent) +
  labs(x = 'Risiko Tahunan',
       y = 'Pengembalian Tahunan',
       title = "Optimasi Portofolio & Perbatasan yang Efisien") +
  geom_point(aes(x = Risk,y = Return), data = min_var, color = 'red') +
  geom_point(aes(x = Risk,y = Return), data = max_sr, color = 'red') 

ggplotly(p)