File size: 2,275 Bytes
23e99b2
 
 
 
 
6811b7e
1c7d42a
6811b7e
 
 
 
1c7d42a
6811b7e
 
 
1c7d42a
6811b7e
 
 
1c7d42a
 
 
6811b7e
 
 
 
1c7d42a
6811b7e
 
 
 
 
1c7d42a
6811b7e
 
1c7d42a
6811b7e
 
 
 
1c7d42a
6811b7e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import streamlit as st
import pandas as pd
import numpy as np
import yfinance as yf
import matplotlib.pyplot as plt
from scipy.optimize import minimize

# Fungsi untuk mengunduh data saham
def get_stock_data(tickers, start, end):
    data = yf.download(tickers, start=start, end=end)['Adj Close']
    return data

# Fungsi untuk menghitung return harian
def calculate_daily_returns(data):
    return data.pct_change().dropna()

# Fungsi untuk menghitung portofolio optimal dengan Model Markowitz
def optimize_portfolio(returns):
    num_assets = len(returns.columns)
    weights = np.random.random(num_assets)
    weights /= np.sum(weights)

    def portfolio_performance(weights):
        port_return = np.sum(returns.mean() * weights) * 252
        port_volatility = np.sqrt(np.dot(weights.T, np.dot(returns.cov() * 252, weights)))
        return port_volatility

    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    bounds = tuple((0, 1) for _ in range(num_assets))
    result = minimize(portfolio_performance, weights, method='SLSQP', bounds=bounds, constraints=constraints)
    
    return result.x

# Streamlit UI
st.title("Analisis Portofolio Saham Model Markowitz")

# Input pengguna untuk daftar saham
tickers = st.text_input("Masukkan kode saham (pisahkan dengan koma)", "BBCA.JK,TLKM.JK,UNVR.JK")
start_date = st.date_input("Pilih tanggal mulai", pd.to_datetime("2020-01-01"))
end_date = st.date_input("Pilih tanggal akhir", pd.to_datetime("2020-12-31"))

if st.button("Analisis"):
    tickers_list = [t.strip() for t in tickers.split(',')]
    data = get_stock_data(tickers_list, start_date, end_date)
    
    if not data.empty:
        st.write("Data Harga Saham")
        st.line_chart(data)

        returns = calculate_daily_returns(data)
        optimal_weights = optimize_portfolio(returns)

        st.write("Bobot Optimal Portofolio:")
        for ticker, weight in zip(tickers_list, optimal_weights):
            st.write(f"{ticker}: {weight:.2%}")

        # Visualisasi Portofolio
        fig, ax = plt.subplots()
        ax.pie(optimal_weights, labels=tickers_list, autopct='%1.1f%%', startangle=90)
        ax.axis("equal")
        st.pyplot(fig)
    else:
        st.error("Gagal mengambil data saham. Pastikan kode saham benar.")