markowitz / app.py
GarGerry's picture
Update app.py
6811b7e verified
raw
history blame
2.28 kB
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.")