UAS OPTIMASI STATISTIKA

OPTIMASI STATISTIKA


Kontak : \(\downarrow\)
Email
Instagram https://www.instagram.com/claraevania/
RPubs https://rpubs.com/claradellaevania/

**

Program Linear

Buatlah contoh kasus Optimisasi Program Linear dalam Industri atau bisnis!

CONTOH KASUS

Dalam suatu bisnis mainan akan memproduksi 2 jenis produk mainan yaitu mainan mobil-mobilan dan truk mainan. Untuk memproduksi 2 produk mainan tersebut di butuhkan 2 kegiatan yaitu proses perakitan dan pengecatan. Saat memproduksi, dibutuhkan waktu 56 jam untuk proses perakitan dan 60 jam untuk proses pengecatan. Untuk produksi 1 unit mobil-mobilan diperlukan waktu 8 jam perakitan dan 5 jam pengecatan. Untuk produksi 1 unit truk mainan diperlukan 7 jam perakitan dan 12 jam pengecatan. Jika biaya masing masing produk adalah Rp. 125 ribu untuk mobil-mobilan dan 95 ribu untuk truk mainan. Tentukan solusi optimal agar mendapatkan untung yang maksimal.

\[ \begin{align} x = Mobil-Mobilan \\ y = Truk \space mainan \end{align} \]

Fungsi Tujuan

\[ \begin{align} Z = 125x + 95y \end{align} \]

Fungsi Kendala

\[ \begin{align} x≥0 \\ y≥0 \\ 8x + 7y ≤ 56 \\ 5x + 12y ≤ 60 \\ \end{align} \]

R

library(lpSolve)

maxim <- c(125,95)
LHS <- matrix(c(8,7,
                5,12)
              ,ncol=2, byrow=TRUE)
arah_kendala <- c("<=","<=")
RHS <- c(56,60)


# Penyelesaian
model <- lp ("max",
            maxim,
            LHS,
            arah_kendala,
            RHS,
            compute.sens = TRUE)

print(model)
## Success: the objective function is 875
model$solution
## [1] 7 0

Sehingga untung yang didapat adalah 875 dengan Nilai X sebesar 7 dan y sebesar 0.

Python

## (0.0, 25.0)
## (0.0, 11.0)

from scipy.optimize import linprog
obj = [-125,-95]

lhs_ineq = [[8,7],
           [5,12]]

rhs_ineq = [56,
           60]
bnd = [(0, float("inf")), 
       (0, float("inf"))]
model_2 = linprog(c=obj,
                 A_ub = lhs_ineq,
                 b_ub = rhs_ineq,
                 method = "revised simplex")
## <string>:1: DeprecationWarning: `method='revised simplex'` is deprecated and will be removed in SciPy 1.11.0. Please use one of the HiGHS solvers (e.g. `method='highs'`) in new code.
print(model_2)
##      con: array([], dtype=float64)
##      fun: -875.0
##  message: 'Optimization terminated successfully.'
##      nit: 1
##    slack: array([ 0., 25.])
##   status: 0
##  success: True
##        x: array([7., 0.])
print("nilai x dan y adalah = {}".format(model_2.x))
## nilai x dan y adalah = [7. 0.]
print("Untung Maksimumnya adalah = {}".format(model_2.fun*-1))
## Untung Maksimumnya adalah = 875.0

Sehingga untung yang didapat adalah 875 dengan Nilai X sebesar 7 dan y sebesar 0.

Program Non Linear

Buatlah contoh kasus Optimisasi Program Non-Linear dalam Industri atau bisnis!

SOAL

Sebuah perusahaan pembuat computer mendapat kontrak untuk menyediakan 50 unit computer pada akhir bulan pertama, 50 unit computer pada akhir bulan kedua, dan 50 unit computer pada akhir bulan ketiga. Biaya produksi x computer setiap bulannya adalah x 2 perusahaan ini dapatmemproduksi computer lebih dari yang dipesan dan menyimpannya di gudan untuk diserahkan pada bulan berikutnya. Biaya gudang adalah sebesar 40 satuan harga untuk seluruh computer yangdisimpan dari bulan yang lalu ke bulan berikutnya. Diandaikan bahwa pada permulaan pesanandi gudang tidak terdapat persediaan computer. Tentukan jumlah produksi computer tiap bulannya agar biaya pembuatan nya minimum.

\[ \begin{align} x[1] = Produksi\space Computer \space Bulan\spacePertama \\ x[2] = Produksi\space Computer\space Bulan\space Pertama \\ x[3] = Produksi \space Computer\space Bulan \space Pertama \\ x[4] = Produksi \space Computer\space Bulan \space Keempat \\ \end{align} \]

Fungsi Tujuan

Meminimumkan biaya total produksi selama 4 bulan secara berurutan

\[ \begin{align} x[1]*x[4](x[1]+x[2]+x[3])+x[3]\\ \end{align} \]

Batas

\[ \begin{align} x[1],x[2],x[3],x[4] ≥& 25\\ x[1]^2 + x[2]^2 +x[3]^2 + x[4]^2 ≥& 40\\ 1 ≤ x[1],x[2],x[3],x[4] &≤ 5 \end{align} \]

R

library(nloptr)
eval_f <- function( x ) {
return( list( "objective" = x[1]*x[4]*(x[1] + x[2] + x[3]) + x[3],
"gradient" = c( x[1] * x[4] + x[4] * (x[1] + x[2] + x[3]),
x[1] * x[4],
x[1] * x[4] + 1.0,
x[1] * (x[1] + x[2] + x[3]) ) ) )}

# Inequality constraints.
eval_g_ineq <- function( x ) {
constr <- c( 25 - x[1] * x[2] * x[3] * x[4] )
grad <- c( -x[2]*x[3]*x[4],
-x[1]*x[3]*x[4],
-x[1]*x[2]*x[4],
-x[1]*x[2]*x[3] )
return( list( "constraints"=constr, "jacobian"=grad ) )}

# Equality constraints.
eval_g_eq <- function( x ) {
constr <- c( x[1]^2 + x[2]^2 + x[3]^2 + x[4]^2 - 40 )
grad <- c( 2.0*x[1],
2.0*x[2],
2.0*x[3],
2.0*x[4] )
return( list( "constraints"=constr, "jacobian"=grad ) )}

# Initial values.
x0 <- c( 1, 5, 5, 1 )
# Lower and upper bounds of control.
lb <- c( 1, 1, 1, 1 )
ub <- c( 5, 5, 5, 5 )
# Optimal solution.
solution.opt <- c(1.00000000, 4.74299963, 3.82114998, 1.37940829)

# Set optimization options.
local_opts <- list( "algorithm" = "NLOPT_LD_MMA",
"xtol_rel" = 1.0e-7 )
opts <- list( "algorithm" = "NLOPT_LD_AUGLAG",
"xtol_rel" = 1.0e-7,
"maxeval" = 1000,
"local_opts" = local_opts,
"print_level" = 0 )

# Do optimization.
res <- nloptr( x0 = x0,
eval_f = eval_f,
lb = lb,
ub = ub,
eval_g_ineq = eval_g_ineq,
eval_g_eq = eval_g_eq,
opts = opts )
print(res)
## 
## Call:
## 
## nloptr(x0 = x0, eval_f = eval_f, lb = lb, ub = ub, eval_g_ineq = eval_g_ineq, 
##     eval_g_eq = eval_g_eq, opts = opts)
## 
## 
## Minimization using NLopt version 2.7.1 
## 
## NLopt solver status: 4 ( NLOPT_XTOL_REACHED: Optimization stopped because 
## xtol_rel or xtol_abs (above) was reached. )
## 
## Number of Iterations....: 476 
## Termination conditions:  xtol_rel: 1e-07 maxeval: 1000 
## Number of inequality constraints:  1 
## Number of equality constraints:    1 
## Optimal value of objective function:  17.0140172892472 
## Optimal value of controls: 1 4.742999 3.821151 1.379408
res <- nloptr(
x0 = x0,
eval_f = eval_f,
lb = lb,
ub = ub,
eval_g_ineq = eval_g_ineq,
opts = opts )
print(res)
## 
## Call:
## 
## nloptr(x0 = x0, eval_f = eval_f, lb = lb, ub = ub, eval_g_ineq = eval_g_ineq, 
##     opts = opts)
## 
## 
## Minimization using NLopt version 2.7.1 
## 
## NLopt solver status: 3 ( NLOPT_FTOL_REACHED: Optimization stopped because 
## ftol_rel or ftol_abs (above) was reached. )
## 
## Number of Iterations....: 55 
## Termination conditions:  xtol_rel: 1e-07 maxeval: 1000 
## Number of inequality constraints:  1 
## Number of equality constraints:    0 
## Optimal value of objective function:  16 
## Optimal value of controls: 1 5 5 1

Python

import numpy as np
import matplotlib.pyplot as plt
def f(x):
    return x1*x4*(x1 + x2 + x3) + x3
def obj_fun(x):
    return (x[0] - 0.5) ** 2 + 0.7 * x[0] * x[1] \
        + 1.2 * (x[1] + 0.7) ** 2

def gradient_fun(x):
    return np.array([2 * (x[0] - 0.5) + 0.7 * x[1], \
        0.7 * x[0] + 2 * 1.2 * (x[1] + 0.7)])
import numpy as np
from scipy.optimize import minimize, line_search, BFGS, SR1
from numdifftools import Gradient

class DescentAlgorithm:
    
    def __init__(self, fun, gradient=None, hess=None, nd={},
                 wolfe_c1=1e-4, wolfe_c2=0.1, x_tol=1e-6,
                 f_tol=1e-6, max_iter=50, save_history=False):
        
        self.fun = fun
        
        if gradient is None:
            self.gradient = Gradient(fun, **nd)
        else:
            self.gradient = gradient
        
        self.hess = hess
        self.wolfe_coefs = wolfe_c1, wolfe_c2
        self.x_tol = x_tol
        self.f_tol = f_tol
        self.max_iter = max_iter
        self.save_history = save_history
        self.history = []
    
    def optimize(self, x0, *args, **kwargs):
        
        x0 = np.atleast_1d(x0).astype(float)
        self.history = []
        xk = x0.copy()
        fk = self.fun(x0, *args, **kwargs)
        gradk = self.gradient(x0, *args, **kwargs)
        
        fc, gc = 1, 1
        
        pk = self.prepare_initial_step(xk, fk, gradk, *args,
                                       **kwargs)
        
        advance_x, advance_f, advance_max = True, True, True
        k = 0
        
        if self.save_history:
            self.history.append({"x":xk, "f":fk, "grad":gradk})
        
        while (advance_x or advance_f) and (k <= self.max_iter):
            
            alpha, fc_, gc_, fnew, fk, gradnew \
                = line_search(self.fun, self.gradient,
                              xk, sk, gradk, fk, args=args,
                              c1=self.wolfe_coefs[0],
                              c2=self.wolfe_coefs[1],
                              maxiter=15)
            
            if alpha is None:
                alpha = 1
                fnew = self.fun(xk + alpha * sk, *args, **kwargs)
                gradnew = self.gradient(xk + alpha * sk, *args,
                                        **kwargs)
            
            xnew = xk + alpha * pk
            fc = fc + fc_
            gc = gc + gc_
            
            if gradnew is None:
                gradnew = self.gradient(xnew, *args, **kwargs)
            
            advance_f = abs(fnew - fk) > self.f_tol
            advance_x = np.linalg.norm(xnew - xk) > self.x_tol
            
            xk, fk, gradk, pk = \
                self.prepare_next_step(xk, fk, gradk, pk,
                                       xnew, fnew, gradnew,
                                       *args, **kwargs)
            k = k + 1
            
            if self.save_history:
                self.history.append({"x":xk, "f":fk, "grad":gradk})
            
            if np.linalg.norm(pk) < np.sqrt(np.finfo(float).eps):
                self.message = 'Negligible step'
                self.success = True
                break
        
        if not (advance_x or advance_f):
            self.success = True
            self.message = 'Tolerance reached'
            
        elif k > self.max_iter:
            self.success = False
            self.message = 'Max iterations reached'
        
        self.x = xk
        self.f = fk
        self.grad = gradk
        self.fc = fc
        self.gc = gc
        self.result = {"x":xk, "f":fk, "grad":gradk, "iter":k,
                       "message":self.message,
                       "success":self.success}
    
    def prepare_next_step(self, xk, fk, gradk, pk, xnew, fnew, 
                          gradnew, *args, **kwargs):
        pass
    
    def prepare_initial_step(self, xk, fk, gradk, *args, **kwargs):
        pass
class SteepestDescent(DescentAlgorithm):

    def prepare_next_step(self, xk, fk, gradk, pk, xnew, fnew,
                          gradnew, *args, **kwargs):
        return xnew, fnew, gradnew, -gradnew

    def prepare_initial_step(self, xk, fk, gradk, *args, **kwargs):
        return -gradk
steepest = SteepestDescent(obj_fun, gradient=gradient_fun,
                           save_history=True)

Portofolio Saham

Buatlah contoh kasus Optimisasi Portofolio dengan memilih 5 saham terbaik di Indonesia dengan cara melakukan analisis data keuangan terlebih dahulu pada saham LQ45!

Sebelum lanjut dalam melihat iptimasi portofolio saham, akan dilakukan analisis data keuangan terlebih dahulu. Dengan bertujuan untuk mengukur kinerja perusahaan berdasarkan data perbandingan dalam laporan neraca atau laporan laba rugi.

Selain untuk menjadi alat ukur, analisis rasio keuangan digunakan untuk melihat tren kinerja perusahaan dalam suatu periode tertentu serta sebagai acuan investor dalam memilih perusahaan. Biasanya dalam mengukur analisis keuangan dapat menggunakan Rasio Likuiditas, Rasio Profitabilitas, Rasio Solvabolitas, Rasio Investasidan Rasio Aktivitas.

Namun untuk data saham LQ45 digunakan dalam perbandingan harga saham perusahaan yang diperdagangkan secara publik dengan ukuran keuangan lainnya. dimana dapat membantu mencari tau nilai pasar saham saai ini dan masa depan. Salah satunya Laba persaham dapat diukur jumlah laba bersih perusahaan yang diperoleh per lembar saham yang beredar, selain itu juga ada Price Earning Ratio dengan membandingkan harga pasar per saham suatu perusahaan dengan laba per sahamnya. Selanjutnya yaitu Rasio Pembayaran Dividen dengan mengukur presentase laba bersih yang didistribusikan kepada pemegang saham. Untuk analisis lebih lanjut dapat dilihat analisis berikut.

Untuk Data yang digunakan, saya memakai data 5 saham untuk membangun portofolio yaitu

  • BCA = Bank Central Asia Tbk PT = bbca.jk = BBCA.JK
  • Telkom = Telkom Indonesia (Persero) Tbk PT = TLKM.JK
  • BRI = Bank Rakyat Indonesia (Persero) Tbk PT = BBRI.JK
  • Astra = Astra International Tbk PT = ASII.JK
  • Unilever = Unilever Indonesia Tbk PT = UNVR.JK

R

library(tidyquant) 
library(plotly) 
library(timetk)
tick = c('BBCA.JK','TLKM.JK','BBRI.JK','ASII.JK','UNVR.JK')

pricedata = tq_get(tick,
                   from = '2020-01-01',
                   to   = '2022-12-09',              
                   get  = 'stock.prices')
pricedata

Pengembalian

Setelah menginput 5 data saham, kita dapat menghitung pengembalian harian untuk beberapa saham ini dengan menggunakan pengembalian logaritmik yang bertujuan untuk memastikan data stasioner.

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

#log_ret_tidy$ret<-round(log_ret_tidy$ret,4)

library(DT)  # print data dalam tabel
datatable(log_ret_tidy)

Kita dapat menggunakan fungsi spread() untuk mengubah datatable menjadi format lebar dan menggunakan xts() untuk mengubahnya menjadi objek time series.

library(tidyr)

log_ret_xts = log_ret_tidy %>%
  spread(symbol, value = ret) %>%
  tk_xts()

datatable(log_ret_xts)

Rata-rata Pengembalian

mean_ret <- colMeans(log_ret_xts)
print ( round (mean_ret, 4))
## ASII.JK BBCA.JK BBRI.JK TLKM.JK UNVR.JK 
##  -1e-04   4e-04   3e-04   1e-04  -7e-04

Matriks Kovariansi

cov_mat <- cov(log_ret_xts) * 252
print(round(cov_mat,4))
##         ASII.JK BBCA.JK BBRI.JK TLKM.JK UNVR.JK
## ASII.JK  0.1397  0.0531  0.0696  0.0516  0.0409
## BBCA.JK  0.0531  0.0831  0.0640  0.0446  0.0346
## BBRI.JK  0.0696  0.0640  0.1460  0.0539  0.0372
## TLKM.JK  0.0516  0.0446  0.0539  0.1087  0.0325
## UNVR.JK  0.0409  0.0346  0.0372  0.0325  0.1300

Penerapan Metode Portofolio

Dalam menerapkan metode portofolio,langkah-langkah yang hrtus dilakukan untuk membentuk suatu portofolio adalah dengan

  • Bobot Acak
  • Rata-Rata Pengembalian Aset
  • Risiko Portofolio
  • Bobot Portofolio
wts <- runif(n = length(tick))
wts <- wts/sum(wts)

port_returns <- (sum(wts * mean_ret) + 1)^252 - 1
port_risk <- sqrt(t(wts) %*% (cov_mat %*% wts))
sharpe_ratio <- port_returns/port_risk
num_port <- 5000

all_wts <- matrix(nrow = num_port, ncol = length(tick))
port_returns <- vector('numeric', length = num_port)
port_risk <- vector('numeric', length = num_port)
sharpe_ratio <- vector('numeric', length = num_port)
for (i in seq_along(port_returns)) {
  
  wts <- runif(length(tick))
  wts <- wts/sum(wts)
  
  all_wts[i,] <- wts
  
  
  port_ret <- sum(wts * mean_ret)
  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
}
portfolio_values <- tibble(Return = port_returns,
                             Risk = port_risk,
                      SharpeRatio = sharpe_ratio)
all_wts <- tk_tbl(all_wts)

colnames(all_wts) <- colnames(log_ret_xts)

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

datatable(portfolio_values)

Variansi Minimum

library(forcats)

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

p <- min_var %>%
  gather(ASII.JK:UNVR.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)

Berdasarkan dengan data bahwa didapatkan Mayoritas Portofolio diinvestasikan pada saham TELKOM dan Bank Central Asia.

Portofolio Tangensi

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

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

Portofolio dengan Ratio Sharpe tertinggi hanya memiliki sedikit investasi pada saham Unilever dan Astra International Bank Republik Indonesia dan Bank Central Asia

Batas Efisien Portofolio

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') +
  annotate('text', x = 0.25, y = 0.05, label = "Portofolio Tangensi") +
  annotate('text', x = 0.274, y = 0.15, label = "Portofolio Varians minimum") +
  annotate(geom = 'segment', x = 0.273, xend = 0.273,  y = 0.09, 
           yend = 0.14, color = 'red', arrow = arrow(type = "open")) +
  annotate(geom = 'segment', x = 0.2417, xend = 0.2417,  y = 0.002, 
           yend = 0.04, color = 'red', arrow = arrow(type = "open"))
  
ggplotly(p)

Python

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import pandas
from pandas_datareader import data as pdr
import yfinance as yfin
yfin.pdr_override()
import datetime
tick1 = ['BBCA.JK','TLKM.JK','BBRI.JK','ASII.JK','UNVR.JK']
price_data=pdr.get_data_yahoo(tick1,
                              start='2020-01-01',
                              end= datetime.date.today())['Adj Close']
## 
[                       0%                       ]
[*******************   40%                       ]  2 of 5 completed
[**********************60%****                   ]  3 of 5 completed
[**********************80%*************          ]  4 of 5 completed
[*********************100%***********************]  5 of 5 completed
price_data
##                 ASII.JK      BBCA.JK      BBRI.JK      TLKM.JK      UNVR.JK
## Date                                                                       
## 2020-01-02  6213.557129  6322.238770  4009.359863  3416.984375  7825.170410
## 2020-01-03  6281.340820  6426.191895  4018.451172  3478.158203  7848.051270
## 2020-01-06  6100.583008  6364.764160  3972.993652  3460.679932  7756.527832
## 2020-01-07  6123.178223  6369.489258  4000.268066  3443.201660  7733.646973
## 2020-01-08  6123.178223  6312.788086  3982.085449  3408.245605  7619.243652
## ...                 ...          ...          ...          ...          ...
## 2022-12-16  5775.000000  8600.000000  4980.000000  3680.000000  4870.000000
## 2022-12-19  5700.000000  8650.000000  4970.000000  3720.000000  4730.000000
## 2022-12-20  5700.000000  8575.000000  4910.000000  3720.000000  4770.000000
## 2022-12-21  5700.000000  8675.000000  4890.000000  3790.000000  4780.000000
## 2022-12-22  5775.000000  8575.000000  4960.000000  3750.000000  4840.000000
## 
## [729 rows x 5 columns]
from numpy import log 
log_ret = np.log(price_data/price_data.shift(1))
log_ret
##              ASII.JK   BBCA.JK   BBRI.JK   TLKM.JK   UNVR.JK
## Date                                                        
## 2020-01-02       NaN       NaN       NaN       NaN       NaN
## 2020-01-03  0.010850  0.016309  0.002265  0.017745  0.002920
## 2020-01-06 -0.029199 -0.009605 -0.011377 -0.005038 -0.011730
## 2020-01-07  0.003697  0.000742  0.006841 -0.005063 -0.002954
## 2020-01-08  0.000000 -0.008942 -0.004556 -0.010204 -0.014903
## ...              ...       ...       ...       ...       ...
## 2022-12-16 -0.004320  0.011696  0.014156  0.002721  0.035531
## 2022-12-19 -0.013072  0.005797 -0.002010  0.010811 -0.029169
## 2022-12-20  0.000000 -0.008708 -0.012146  0.000000  0.008421
## 2022-12-21  0.000000  0.011594 -0.004082  0.018642  0.002094
## 2022-12-22  0.013072 -0.011594  0.014213 -0.010610  0.012474
## 
## [729 rows x 5 columns]
cov_mat = log_ret.cov() * 252
print(cov_mat)
##           ASII.JK   BBCA.JK   BBRI.JK   TLKM.JK   UNVR.JK
## ASII.JK  0.138332  0.052342  0.069019  0.051048  0.040647
## BBCA.JK  0.052342  0.082466  0.063327  0.044269  0.034255
## BBRI.JK  0.069019  0.063327  0.144706  0.053536  0.037064
## TLKM.JK  0.051048  0.044269  0.053536  0.108063  0.032225
## UNVR.JK  0.040647  0.034255  0.037064  0.032225  0.129337

Penerapan Metode Portofolio


# Simulating 5000 portfolios
num_port = 5000
# Creating an empty array to store portfolio weights
all_wts = np.zeros((num_port, len(price_data.columns)))
# Creating an empty array to store portfolio returns
port_returns = np.zeros((num_port))
# Creating an empty array to store portfolio risks
port_risk = np.zeros((num_port))
# Creating an empty array to store portfolio sharpe ratio
sharpe_ratio = np.zeros((num_port))
for i in range(num_port):
  wts = np.random.uniform(size = len(price_data.columns))
  wts = wts/np.sum(wts)
  
  # saving weights in the array
  
  all_wts[i,:] = wts
  
  # Portfolio Returns
  
  port_ret = np.sum(log_ret.mean() * wts)
  port_ret = (port_ret + 1) ** 252 - 1
  
  # Saving Portfolio returns
  
  port_returns[i] = port_ret
  
  
  # Portfolio Risk
  
  port_sd = np.sqrt(np.dot(wts.T, np.dot(cov_mat, wts)))
  
  port_risk[i] = port_sd
  
  # Portfolio Sharpe Ratio
  # Assuming 0% Risk Free Rate
  
  sr = port_ret / port_sd
  sharpe_ratio[i] = sr
names = price_data.columns
min_var = all_wts[port_risk.argmin()]
print(min_var)
## [0.08733541 0.41535771 0.01818298 0.25703398 0.22208992]
max_sr = all_wts[sharpe_ratio.argmax()]
print(max_sr)
## [0.04220915 0.58961592 0.21823167 0.14101188 0.00893138]
print(port_risk.min())
## 0.24071130172591315
print(sharpe_ratio.max())
## 0.3157704106004899
import plotly.express as px

# Variansi minimum
min_var = pd.Series(min_var, index=names)
min_var = min_var.sort_values()

fig = px.bar(min_var, color=min_var.index, title="Portofolio dengan Variansi minimum")
fig.show()

Portofolio Tangensi

import plotly.express as px

# Maksimum Sharpe Ratio
max_sr = pd.Series(max_sr, index=names)
max_sr = max_sr.sort_values()

fig = px.bar(max_sr, color=max_sr.index, title="Portofolio dengan Tangensi")
fig.show()

**Batas Efisien Portofolio

fig = plt.figure()
ax1 = fig.add_axes([0.1,0.1,0.8,0.8])
ax1.set_xlabel('Risk')
ax1.set_ylabel("Returns")
ax1.set_title("Portfolio optimization and Efficient Frontier")
plt.scatter(port_risk, port_returns)
plt.show()