Pemodelan dan Teori Risiko
~ Mid Exam ~
| Kontak | : \(\downarrow\) |
| diyasaryanugroho@gmail.com | |
| https://www.instagram.com/diasary_nm/ | |
| RPubs | https://rpubs.com/diyasarya/ |
Soal 1
Consider a portfolio consisting of five stocks from different sectors in Indonesia and analyze the diversification benefits of combining stocks. Your answer should cover at least the following steps:
library(quantmod)
library(plotly)
library(PerformanceAnalytics)
# a. Use quantmod for downloading stock data.
saham <- c('BBCA.JK', 'ASII.JK', 'TLKM.JK', 'UNVR.JK', 'ICBP.JK')
sahamlabel = c("Bank Central Asia Tbk.", "Astra International Tbk.", "Telkom Indonesia (Persero)", "Unilever Indonesia Tbk.", "Indofood CBP Sukses Makmur Tbk.")
HargaPenutupan <- NULL
for (data in saham)
HargaPenutupan <- cbind(HargaPenutupan,getSymbols.yahoo(data, from="2022-01-01", auto.assign=FALSE)[,4]) # kombinasikan data harga saham (data frame)
HargaPenutupan <- HargaPenutupan[apply(HargaPenutupan,1,function(x) all(!is.na(x))),] # hapus semua data tanpa harga (jika ada)
names(HargaPenutupan)[names(HargaPenutupan) ==
c("BBCA.JK.Close", "ASII.JK.Close", "TLKM.JK.Close", "UNVR.JK.Close", "ICBP.JK.Close")] <-
c("BBCA", "ASII", "TLKM", "UNVR", "ICBP")Saham yang digunakan dalam diversifikasi portofolio yaitu,
1.
Bank Central ASia (BBCA.JK)
2. Astra International (ASII.JK)
3. Telkom Indonesia (TLKM.JK)
4. Unilever Indonesia (UNVR.JK)
5. Indofood CBP Sukses Makmur (ICBP.JK)
# b. Define a function calculate_returns() to calculate daily returns from the closing prices of the stocks and apply this function to each stock's price series
calculate_returns <- function(hargasaham) {
returns <- diff(log(hargasaham)) # Perhitungan return menggunakan metode log
return(returns)
}
returnsaham <- lapply(HargaPenutupan, calculate_returns)
# c. Combine the returns of all stocks into a single data frame.
dfreturn <- do.call(cbind, returnsaham)
head(dfreturn)## BBCA ASII TLKM UNVR ICBP
## 2022-01-03 NA NA NA NA NA
## 2022-01-04 0.010186845 0.008695707 -0.002395211 0.004716990 0.017241806
## 2022-01-05 0.006734032 -0.035245939 -0.029199155 -0.009456335 0.005681833
## 2022-01-06 0.003350087 0.017778246 0.017136282 0.004739345 0.002828856
## 2022-01-07 0.023141529 0.004395611 0.012062872 -0.002366865 0.002820876
## 2022-01-10 -0.006557401 -0.008810630 -0.016929062 0.007083855 -0.002820876
Untuk perhitungan return menggunakan metode log, harga saham dilogkan lalu cari selisihnya waktu ke-n dengan ke-(n-1). Tabel diatas adalah return dari masing-masing saham.
# d. Calculate the correlation matrix of returns using cor().
korelasisaham = cor(dfreturn, use = "pairwise.complete.obs") # Korelasi dengan metode Pairwise
data.frame(korelasisaham)Untuk melakukan perhitungan korelasi antar saham, disini menggunakan metode pairwise dengan “pairwise.complete.obs”. Tabel diatas adalah nilai korelasi antar saham.
# e. Visualize the correlation matrix using corrplot().
colnames(korelasisaham) = rownames(korelasisaham) = sahamlabel # Penamaan pada data frame korelasi
mask = matrix(F, nrow=nrow(korelasisaham), ncol=ncol(korelasisaham))
mask[lower.tri(mask)] = T
heatmap = plot_ly(z=korelasisaham, x=sahamlabel, y=sahamlabel, type="heatmap")
heatmap = heatmap %>%
layout(title = "Correlation Heatmap of Indonesian Stocks Return Price",
xaxis = list(title=""),
yaxis=list(title=""),
colorscale= "Inferno",
margin = list(l=60, r=80, t=100, b=60))
heatmapUntuk memudahkan melihat korelasi atau hubungan antar saham maka dibuat visualisasi heatmap. Dari visualisasi diatas didapat bahwa korelasi antar saham tidak begitu kuat yang artinya karakteristik dari satu saham dengan saham yang lain tidak sama.
# f. Calculate the portfolio's returns and standard deviation based on equal weights for each stock.
n <- length(HargaPenutupan)
weights <- rep(1/n, n)
portreturn <- colSums(na.omit(dfreturn * weights)) # na.omit untuk mengabaikan nilai NA
portsd <- sqrt(var(portreturn))
print(paste("Portfolio Returns:", mean(portreturn)))## [1] "Portfolio Returns: -1.39994340181562e-06"
## [1] "Portfolio Standard Deviation: 0.000112515613133091"
Berdasarkan perhitungan rata-rata portofolio return dan standart deviasi didapatkan bahwa portofolio return sebesar - 0,001399% dengan standar deviasi sebesar 0,01%. Artinya portofolio investasi yang dihasilkan lebih stabil dikarenakan return yang rendah dengan standar deviasi yang rendah pula. Hal ini cocok bagi investor pemula agar modal investasi lebih terjaga karena risiko kerugiannya rendah.
return = na.omit(dfreturn)
colmean = apply(return, 2, mean, na.rm=T)
colsd <- apply(return, 2, sd, na.rm = TRUE)
print(colsd)## BBCA ASII TLKM UNVR ICBP
## 0.01261183 0.01634538 0.01416644 0.02009436 0.01606686
Tabel diatas adalah standar deviasai dari masing-masing saham.
# g. Calculate the diversification ratio, which measures the extent to which the portfolio's risk is reduced due to diversification.
calculate_diversification_ratio <- function(portsd, colsd) {
weight_persaham <- sum(colsd) / length(colsd)
# Calculate diversification ratio
diversification_ratio <- portsd / weight_persaham
return(diversification_ratio)
}
diversification_ratio <- calculate_diversification_ratio(portsd, colsd)
print(paste("Diversification Ratio:", diversification_ratio))## [1] "Diversification Ratio: 0.00709565504812256"
Dari hasil perhitungan rasio diversifikasi didapat 0,007 atau 0,7% yang artinya bahwa diversifikasi dalam portofolio mampu mengurangi risiko sebesar 0,7%.
# h. Define the objective function and constraints for portfolio optimization. Here, we aim to maximize the portfolio return subject to the constraint that the sum of portfolio weights equals 1.
library(quadprog)
ekpektasireturn <- c(0.1, 0.1, 0.1, 0.1, 0.1) # Return yang diinginkan dari masing-masing saham
cov_matrix <- matrix(korelasisaham, nrow=5) # Covariance matrix
library(Matrix)## Warning: package 'Matrix' was built under R version 4.1.3
pd_D_mat <- nearPD(cov_matrix)
D_mat <- as.matrix(pd_D_mat$mat)
d_vec <- rep(0, length(ekpektasireturn))
A_mat <- cbind(rep(1, length(ekpektasireturn)), diag(length(ekpektasireturn)))
b_vec <- c(1, d_vec)
# i. Find the optimal portfolio weights that maximize the portfolio return given the covariance matrix and constraints.
# Metode optimasi maksimum
library(quadprog)
output <- solve.QP(Dmat = D_mat, dvec = d_vec, Amat = A_mat, bvec = b_vec, meq = 1)
# Optimal portfolio weights
optimal_weights <- output$solution
print(optimal_weights)## [1] 0.1596782 0.2127760 0.2036109 0.2066979 0.2172369
Dengan mengharapkan return masing-masing saham sebesar 10% maka proporsi yang optimal untuk masing-masing saham yaitu 15,9% (BBCA), 21,2% (ASSI), 20,3% (TLKM), 20,7% (UNVR), 21,7% (ICBP).
# j. Visualize the optimal weights assigned to each stock in the portfolio.
library(plotly)
colors <- c("#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd")
plot_data <- data.frame(Symbol = saham, Weight = optimal_weights, Color = colors)
bar_plot <- plot_ly(plot_data, x = ~Symbol, y = ~Weight, type = 'bar',
marker = list(color = ~Color)) %>%
layout(title = "Optimal Weights of Stocks in Portfolio",
xaxis = list(title = "Stocks"),
yaxis = list(title = "Weight"))
bar_plotAtau untuk mempermudah dapat dilihat dari visualisasi diatas.
# k. Calculate the expected return and volatility of the optimized portfolio using the optimal weights and covariance matrix.
portekpektasireturn <- sum(optimal_weights * ekpektasireturn)
# Calculate portfolio volatility (standard deviation)
portvolatility <- sqrt(t(optimal_weights) %*% cov_matrix %*% optimal_weights)
# Print the results
print(paste("Expected Return of the Portfolio:", portekpektasireturn))## [1] "Expected Return of the Portfolio: 0.1"
## [1] "Portfolio Volatility (Standard Deviation): 6.08146141944616e-05"
Dengan return yang diharapkan sebesar 10% volatilitasnya sebesar 0,0608%.
Soal 2
Assume you are working as an Actuary at an Insurance Company. Your job is to define insurance claims data and analyze the risk associated with different scenarios. Consider explaining your answer in details as the following instructions:
# a. Generate insurance claims data for a hypothetical insurance company with 10000 policies over 17 years.
set.seed(863)
policies <- 10000
years <- 17
# Mean number of claims per policy per year (assuming Poisson distribution)
lambda <- 0.1
# Initialize empty data frame to store claims data
claims_data <- data.frame(
Policy_ID = integer(),
Year = integer(),
Claims = numeric(),
Claim_Amount = numeric()
)
# Generate claims data for each policy and year
for (policy_id in 1:policies) {
for (year in 1:years) {
# c. Simulate claim frequencies for each policy from a Poisson distribution with a mean of 0.1 (i.e., on average, each policy has 0.1 claims per year).
num_claims <- rpois(1, lambda)
if (num_claims > 0) {
# d. Simulate claim amounts for each policy and each year from a normal distribution with a mean of 5007 and a standard deviation of 2007.
claim_amounts <- round(rnorm(num_claims, 5007, 2007),2)
claims_data <- rbind(claims_data, data.frame(
Policy_ID = rep(policy_id, num_claims),
Year = rep(year, num_claims),
Claims = num_claims,
Claim_Amount = claim_amounts
))
}
}
}
claims_data# b. Generate random policy premiums from a normal distribution with a mean of 1007 and a standard deviation of 2007.
set.seed(863)
policy_premiums <- abs(round(rnorm((nrow(claims_data)), mean = 1007, sd = 2007), 2))
claims_data$Premiums = policy_premiums# e. Calculate total claim amounts per policy and then calculate loss ratios (total claims divided by premiums) to assess the risk associated with each policy.
total_claim_amounts <- tapply(claims_data$Claim_Amount, claims_data$Policy_ID, sum)
total_premiums <- tapply(claims_data$Premiums, claims_data$Policy_ID, sum)
loss_ratios <- total_claim_amounts / total_premiums
loss = data.frame(loss_ratios)
loss# f. Plot a histogram of the loss ratios to visualize the distribution of risk.
loss_ratio_histogram <- plot_ly(x = loss_ratios, type = "histogram",
name = "Loss Ratios",
xbins = list(size = 0.1),
marker = list(color = "yellow"))
loss_ratio_histogram <- loss_ratio_histogram %>%
layout(title = "Histogram of Loss Ratios",
xaxis = list(title = "Loss Ratio"),
yaxis = list(title = "Frequency"))
loss_ratio_histogramBerdasarkan hasil plot bahwa loss ratio berkumpul pada titik 0 tetapi frequensi klaim masih tinggi.
# g. Calculate summary statistics including the mean, median, and 95th percentile of the loss ratios.
mean_loss_ratio <- mean(loss_ratios)
median_loss_ratio <- median(loss_ratios)
p95_loss_ratio <- quantile(loss_ratios, probs = 0.95)
# Display summary statistics
cat("Mean Loss Ratio:", mean_loss_ratio, "\n")## Mean Loss Ratio: 6.868065
## Median Loss Ratio: 2.980516
## 95th Percentile of Loss Ratios: 16.02537