Optimasi

Optimalisasi Portofolio Saham Asuransi

Diyas Arya Nugroho

December 21, 2023


*Kontak *: \(\downarrow\)**
Email
Instagram https://www.instagram.com/diasary_nm/
RPubs https://rpubs.com/diyasarya/

Pendahuluan

Pada penelitian kali ini, saya akan menggunakan lima data saham yang berhubungan dengan asuransi untuk melakukan optimalisasi portofolio:

  1. Asuransi Bintang Tbk. (ASBI.JK)
  2. Asuransi Dayin Mitra Tbk. (ASDM.JK)
  3. Asuransi Jasa Tania Tbk. (ASJT.JK)
  4. Asuransi Maximus Graha Persada. (ASMI.JK)
  5. Asuransi Ramayana Tbk. (ASRM.JK)

Package

Library merupakan kumpulan package yang memuat berbagai fungsi komputasi. Berikut package yang digunakan untuk melakukan optimalisasi portofolio.

pacman::p_load(tidyverse,
               tidyquant,
               tidyr,
               DT,
               timetk,
               forcats,
               plotly,
               timetk,
               rmdformats)

Proses Optimasi

Import Data

Berikut daftar harga saham asuransi dari awal tahun 2023.

saar <- c('ASBI.JK', 'ASDM.JK', 'ASJT.JK', 'ASMI.JK','ASRM.JK')


saars <- tq_get(saar,
                     from = '2023-01-01',
                     to   = Sys.Date(),
                     get  = 'stock.prices')

saars

Return Saham

Return atau pengembalian saham secara matematis dirumuskan sebagai berikut:

Namun, dengan bantuan R dapat menggunakan coding dibawah ini

rtsa <- saars %>%
  group_by(symbol) %>%
  tq_transmute(select     = adjusted,
               mutate_fun = periodReturn,
               period     = 'daily',
               col_rename = 'ret',
               type       = 'log')
 
datatable(rtsa)

Atau dengan mengganti format yang lebih lengkap untuk setiap jenis saham dapat menggunakan fungsi spread. Format ini akan memberikan rata-rata dar return saham dengan mengubah format data menjadi tipe time series dengan fungsi xts().

rarart <- rtsa %>%
  spread(symbol, value = ret) %>%
  tk_xts()

datatable(na.omit(rarart))

Matriks Kovariansi

Untuk melihat hubungan antar satu saham dengan saham yang lain, dapat menggunakan matriks kovariansi dengan codingan seperti dibawah ini:

covmat <- cov(rarart) * 252    # 252 adalah jumlah hari dalam setahun dikurang hari weekend
covmat
##              ASBI.JK       ASDM.JK       ASJT.JK      ASMI.JK      ASRM.JK
## ASBI.JK  0.355583599  0.0072372004  0.0010966503 -0.004091896 -0.001561853
## ASDM.JK  0.007237200  0.0791880906 -0.0002525504 -0.006200785 -0.006792643
## ASJT.JK  0.001096650 -0.0002525504  0.1593561058 -0.013654864  0.012424449
## ASMI.JK -0.004091896 -0.0062007850 -0.0136548644  0.497867933 -0.001457434
## ASRM.JK -0.001561853 -0.0067926428  0.0124244486 -0.001457434  0.046842512

Dapat dilihat hubungan antara ASTJ dengan ASRM memiliki hubungan tertinggi positif yaitu 0.012 sedangkan hubungan tertinggi negatif yaitu antara ASMI dengan ASTJ yaitu -0.013.

Rata-rata pengembalian portofolio saham

rata <- colMeans(rarart)
rata
##       ASBI.JK       ASDM.JK       ASJT.JK       ASMI.JK       ASRM.JK 
##  1.119200e-03  7.016571e-04 -2.019354e-04 -3.170672e-03  6.557652e-05

Berdasarkan hasil output diatas nilai return paling tinggi adalah ASBI yaitu 1.119200e-03 sedangkan terkecil adalah ASJt yaitu -2.019354e-04.

Penerapan Metode Portofolio

Berikut langkah-langkah optimalisasi portofolio dengan pendekatan return dan risiko portofolio:


  1. Menentukan Bobot acak
  2. Rata-rata pengembalian aset
  3. Risiko portofolio
  4. Bobot portofolio

Membuat bobot acak

Pada tahap ini, saya menentukan bobot pada setiap jenis sahamnya secara acak

bobot <- runif(n = length(saars))
bobot <- bobot/sum(bobot)
bobot
## [1] 0.21117922 0.05166490 0.24747378 0.01006444 0.10281889 0.01569567 0.18559409
## [8] 0.17550901

Rata-rata pengembalian aset

Dengan menggunakan bobot acak diawal, saya hitung rata-rata return dikali dengan bobot acak

rtra <- (sum(bobot * rata) + 1)^252 - 1
rtra
## [1] 0.08118728

Hasil dari perhitungan return dengan menggunakan bobot acak didapat 0.01268014 yang berarti portofolio investasi akan mengalami keuntungan berkisar 1.26% per tahun.

Risiko portofolio

Risiko portofolio

# Assuming you have 5 stocks
riskacak <- runif(5)
riskacak <- riskacak / sum(riskacak)

# Convert acak to a matrix or one-column vector if necessary
riskacak_matrix <- matrix(riskacak, nrow = 5, ncol = 1)

# Calculate portfolio risk
risk <- sqrt(t(riskacak_matrix) %*% (covmat %*% riskacak_matrix))
risk
##           [,1]
## [1,] 0.1983559

Berdasarkan hasil perhitungan diatas, didapat 0,3014607 yang berarti risiko dari portofolio investasi dalam kategori sedang.

Bobot portofolio sharpe ratio

Bobot portofolio sharpe ratio

# bobot portofolio sharpe ratio
shra <- rtra/risk
shra
##          [,1]
## [1,] 0.409301

Nilai sharpe ratio adalah 0,04206233 yang berarti keuntungan sebesar 4% dengan risiko 3%.

Membentuk protofolio secara acak

Membuat protfolio secara acak dengan simulasi 5000 kali untuk memastikan signifikansinya secara statistik, sebagai berikut:

num_port <- 5000

all_wts <- matrix(nrow = num_port, ncol = length(saars))
rtra <- vector('numeric', length = num_port)
risk <- vector('numeric', length = num_port)
shra <- vector('numeric', length = num_port)

Lalu jalankan loop sebanyak 5000 kali, sebagai berikut:

# Number of portfolios to simulate
num_portfolios <- length(rtra)

# Initialize all_wts with the correct dimensions
all_wts <- matrix(nrow = num_portfolios, ncol = 5)

for (i in seq_along(rtra)) {
  
  # Generate random weights for 5 stocks
  acak1 <- runif(5)
  acak1 <- acak1/sum(acak1)
  
  all_wts[i,] <- acak1 
  
  # Calculate portfolio return
  port_ret <- sum(acak1 * rata)
  port_ret <- ((port_ret + 1)^252) - 1
  
  rtra[i] <- port_ret
  
  # Calculate portfolio risk
  port_sd <- sqrt(t(acak1) %*% (covmat  %*% acak1))
  risk[i] <- port_sd
  
  # Calculate Sharpe Ratio
  sr <- port_ret/port_sd
  shra[i] <- sr
}

Lalu membuat tabel data untuk menyimpan semua nilai nya, sebagai berikut:

portfolio_values <- tibble(Return = rtra,
                             Risk = risk,
                      SharpeRatio = shra)


all_wts <- tk_tbl(all_wts)

colnames(all_wts) <- colnames(rarart)

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

datatable(portfolio_values)

Tabel diatas menunjukan bobot untuk setiap jenis saham dengan perhitungan return dan risiko, juga terdaat nilai sharpe_rationya. Selanjutnya, dapat menentukan portofolio mana yang paling optimal dengan melihat variansi yang paling minimum dan nilai sharpe ratio maksimum.


Untuk itu, perlu melakukan perhitungan variansi dari setiap jenis saham.

Variansi minimum

library(forcats)  # menggunakan fungsi `fct_reorder`

# Minumum Variansi
min_var <- portfolio_values[which.min(portfolio_values$Risk),]
min_var
p <- min_var %>%
  gather(ASBI.JK:ASRM.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)

Dari hasil perhitungan variansi didapat yang paling minimum adalah ASBI dengan nilai variansi sebesar 0,038.
nilai variansi ASMI adalah 0,065.
nilai variansi ASJT adalah 0,133.
nilai variansi ASDM adalah 0,308.
nilai variansi ASRM adalah 0,455.

# Maksimum Sharpe Ratio
max_sr <- portfolio_values[which.max(portfolio_values$SharpeRatio),]

p <- max_sr %>%
  gather(ASBI.JK:ASRM.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)

Nilai sharpe ratio tertinggi adalah ASDM yaitu 0,482, ASBI yaitu 0,264, ASRM yaitu 0,234, ASJT yaitu 0,020, dan ASMI yaitu 0.

Batas Efisien Portofolio

Plot semua portofolio acak dan akan di visualisasikan sesuai dengan batas efisien nya, sebagai berikut:

p <- portfolio_values %>%
  ggplot(aes(x = Risk, y = Return, color = SharpeRatio)) +
  geom_point() +
  scale_color_gradient(low = "#BA292E", high = "#3149FF") +
  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 = 'yellow') +
  geom_point(aes(x = Risk, y = Return), data = max_sr, color = 'yellow') +
  annotate('text', x = 0.31, y = 0.31, label = "Portofolio Tangensi") +
  annotate('text', x = 0.24, y = 0.11, label = "Portofolio Varians minimum") +
  annotate(geom = 'segment', x = 0.3023, xend = 0.3023,  y = 0.23, 
           yend = 0.29, color = 'red', arrow = arrow(type = "open")) +
  annotate(geom = 'segment', x = 0.25, xend = 0.25,  y = 0.015, 
           yend = 0.10, color = 'red', arrow = arrow(type = "open"))
  
ggplotly(p)