File size: 3,316 Bytes
f4505cc
 
 
 
 
 
b59b790
715f9f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1aabc74
 
715f9f2
 
 
 
 
 
 
 
1aabc74
715f9f2
 
 
 
 
 
b59b790
715f9f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b59b790
715f9f2
b59b790
a15fad3
 
 
 
 
615b087
 
715f9f2
 
b59b790
715f9f2
 
 
 
 
 
b59b790
a15fad3
715f9f2
b59b790
715f9f2
 
 
b59b790
715f9f2
 
a15fad3
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import streamlit as st
import yfinance as yf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.optimize as sco

def get_stock_data(tickers, start, end):
    data = yf.download(tickers, start=start, end=end)
    
    if data.empty:
        st.error("Data saham tidak ditemukan. Periksa ticker atau rentang tanggal.")
        return None
    
    if 'Adj Close' in data.columns:
        return data['Adj Close']
    elif 'Close' in data.columns:
        st.warning("Menggunakan 'Close' karena 'Adj Close' tidak tersedia.")
        return data['Close']
    else:
        st.error("Data harga penutupan tidak ditemukan.")
        return None

def calculate_returns(data):
    log_returns = np.log(data / data.shift(1))  
    return log_returns.mean() * 252, log_returns.cov() * 252

def optimize_portfolio(returns, cov_matrix):
    num_assets = len(returns)
    
    def sharpe_ratio(weights):
        portfolio_return = np.dot(weights, returns)
        portfolio_volatility = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
        return -portfolio_return / portfolio_volatility  
    
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    bounds = tuple((0, 1) for _ in range(num_assets))
    init_guess = num_assets * [1. / num_assets]
    
    result = sco.minimize(sharpe_ratio, init_guess, method='SLSQP', bounds=bounds, constraints=constraints)
    return result.x if result.success else None

def generate_efficient_frontier(returns, cov_matrix, num_portfolios=5000):
    num_assets = len(returns)
    results = np.zeros((3, num_portfolios))
    
    for i in range(num_portfolios):
        weights = np.random.dirichlet(np.ones(num_assets), size=1)[0]
        portfolio_return = np.dot(weights, returns)
        portfolio_volatility = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
        sharpe_ratio = portfolio_return / portfolio_volatility
        
        results[0, i] = portfolio_return
        results[1, i] = portfolio_volatility
        results[2, i] = sharpe_ratio
    
    return results

st.title("Analisis Portofolio Saham Optimal (Model Markowitz)")

st.markdown("""
### Teori Markowitz
Model Markowitz, atau Modern Portfolio Theory (MPT), digunakan untuk membangun portofolio investasi optimal dengan memaksimalkan return untuk tingkat risiko tertentu.

Portofolio yang optimal ditemukan dengan menghitung kombinasi terbaik dari aset yang tersedia untuk meminimalkan risiko dan memaksimalkan return.
""")

def get_recommended_stocks():
    return "KLBF.JK, SIDO.JK, KAEF.JK, TLKM.JK, UNVR.JK"

def validate_tickers(tickers):
    invalid_tickers = [t for t in tickers if yf.Ticker(t).history(period='1d').empty]
    if invalid_tickers:
        st.warning(f"Ticker tidak valid atau tidak memiliki data: {', '.join(invalid_tickers)}")
        return False
    return True

st.write("Rekomendasi Saham yang Bertahan Saat COVID-19:")
st.write(get_recommended_stocks())

tickers_list = st.text_input("Masukkan ticker saham", "KLBF.JK, SIDO.JK, KAEF.JK").split(", ")
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("2023-12-31"))

if st.button("Analisis Portofolio"):
    if validate_tickers(tickers_list):
        stock_data = get_stock