| *Kontak | *: \(\downarrow\)** |
| diyasaryanugroho@gmail.com | |
| 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:
- Asuransi Bintang Tbk. (ASBI.JK)
- Asuransi Dayin Mitra Tbk. (ASDM.JK)
- Asuransi Jasa Tania Tbk. (ASJT.JK)
- Asuransi Maximus Graha Persada. (ASMI.JK)
- 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:
- Menentukan Bobot acak
- Rata-rata pengembalian aset
- Risiko portofolio
- 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)