GarGerry commited on
Commit
f0a10e4
·
verified ·
1 Parent(s): 35ba371

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -24
app.py CHANGED
@@ -5,58 +5,75 @@ import pandas as pd
5
  import matplotlib.pyplot as plt
6
  import scipy.optimize as sco
7
 
 
8
  def get_stock_data(tickers, start, end):
9
  data = yf.download(tickers, start=start, end=end)
10
- if 'Adj Close' in data.columns:
11
- return data['Adj Close']
12
- else:
 
 
 
 
13
  return None
14
 
 
 
 
15
  def calculate_returns(data):
16
  log_returns = np.log(data / data.shift(1))
17
  return log_returns.mean() * 252, log_returns.cov() * 252
18
 
 
19
  def optimize_portfolio(returns, cov_matrix):
20
  num_assets = len(returns)
21
-
22
  def sharpe_ratio(weights):
23
  portfolio_return = np.dot(weights, returns)
24
  portfolio_volatility = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
25
- return -portfolio_return / portfolio_volatility
26
 
27
  constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
28
  bounds = tuple((0, 1) for _ in range(num_assets))
29
  init_guess = num_assets * [1. / num_assets]
30
-
31
  result = sco.minimize(sharpe_ratio, init_guess, method='SLSQP', bounds=bounds, constraints=constraints)
32
- return result.x
33
 
 
34
  st.title("Analisis Portofolio Saham Optimal (Model Markowitz)")
35
 
 
36
  tickers_list = st.text_input("Masukkan ticker saham (contoh: BBCA.JK, TLKM.JK, BBRI.JK)", "BBCA.JK, TLKM.JK, BBRI.JK").split(", ")
37
  start_date = st.date_input("Pilih tanggal mulai", pd.to_datetime("2020-01-01"))
38
  end_date = st.date_input("Pilih tanggal akhir", pd.to_datetime("2020-12-31"))
39
 
40
  if st.button("Analisis Portofolio"):
41
  try:
 
42
  stock_data = get_stock_data(tickers_list, start_date, end_date)
43
-
44
- if stock_data is None or stock_data.isnull().values.any():
45
- st.error("Data tidak ditemukan atau tidak lengkap. Periksa ticker atau tanggal yang dipilih.")
46
- else:
47
  mean_returns, cov_matrix = calculate_returns(stock_data)
 
 
48
  optimal_weights = optimize_portfolio(mean_returns, cov_matrix)
49
-
50
- st.subheader("Bobot Portofolio Optimal:")
51
- for i, stock in enumerate(tickers_list):
52
- st.write(f"{stock}: {optimal_weights[i]:.2%}")
53
-
54
- st.subheader("Efficient Frontier")
55
- fig, ax = plt.subplots()
56
- ax.scatter(np.sqrt(np.diag(cov_matrix)), mean_returns, c=mean_returns / np.sqrt(np.diag(cov_matrix)), marker='o')
57
- ax.set_xlabel("Risiko (Standar Deviasi)")
58
- ax.set_ylabel("Return Tahunan")
59
- ax.set_title("Efficient Frontier")
60
- st.pyplot(fig)
 
 
 
 
 
61
  except Exception as e:
62
- st.error(f"Terjadi kesalahan: {e}")
 
5
  import matplotlib.pyplot as plt
6
  import scipy.optimize as sco
7
 
8
+ # Fungsi untuk mengunduh data saham
9
  def get_stock_data(tickers, start, end):
10
  data = yf.download(tickers, start=start, end=end)
11
+
12
+ if data.empty:
13
+ st.error("Data saham tidak ditemukan. Periksa ticker atau rentang tanggal.")
14
+ return None
15
+
16
+ if 'Adj Close' not in data.columns:
17
+ st.error("Kolom 'Adj Close' tidak ditemukan dalam data yang diunduh.")
18
  return None
19
 
20
+ return data['Adj Close']
21
+
22
+ # Fungsi untuk menghitung return tahunan dan matriks kovarians
23
  def calculate_returns(data):
24
  log_returns = np.log(data / data.shift(1))
25
  return log_returns.mean() * 252, log_returns.cov() * 252
26
 
27
+ # Fungsi untuk menghitung portofolio optimal
28
  def optimize_portfolio(returns, cov_matrix):
29
  num_assets = len(returns)
30
+
31
  def sharpe_ratio(weights):
32
  portfolio_return = np.dot(weights, returns)
33
  portfolio_volatility = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
34
+ return -portfolio_return / portfolio_volatility # Negatif untuk minimisasi
35
 
36
  constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
37
  bounds = tuple((0, 1) for _ in range(num_assets))
38
  init_guess = num_assets * [1. / num_assets]
39
+
40
  result = sco.minimize(sharpe_ratio, init_guess, method='SLSQP', bounds=bounds, constraints=constraints)
41
+ return result.x if result.success else None
42
 
43
+ # Streamlit UI
44
  st.title("Analisis Portofolio Saham Optimal (Model Markowitz)")
45
 
46
+ # Input Saham & Tanggal
47
  tickers_list = st.text_input("Masukkan ticker saham (contoh: BBCA.JK, TLKM.JK, BBRI.JK)", "BBCA.JK, TLKM.JK, BBRI.JK").split(", ")
48
  start_date = st.date_input("Pilih tanggal mulai", pd.to_datetime("2020-01-01"))
49
  end_date = st.date_input("Pilih tanggal akhir", pd.to_datetime("2020-12-31"))
50
 
51
  if st.button("Analisis Portofolio"):
52
  try:
53
+ # Ambil data saham
54
  stock_data = get_stock_data(tickers_list, start_date, end_date)
55
+
56
+ if stock_data is not None:
 
 
57
  mean_returns, cov_matrix = calculate_returns(stock_data)
58
+
59
+ # Optimasi portofolio
60
  optimal_weights = optimize_portfolio(mean_returns, cov_matrix)
61
+
62
+ if optimal_weights is not None:
63
+ st.subheader("Bobot Portofolio Optimal:")
64
+ for i, stock in enumerate(tickers_list):
65
+ st.write(f"{stock}: {optimal_weights[i]:.2%}")
66
+
67
+ # Plot Efficient Frontier
68
+ st.subheader("Efficient Frontier")
69
+ fig, ax = plt.subplots()
70
+ ax.scatter(np.sqrt(np.diag(cov_matrix)), mean_returns, c=mean_returns / np.sqrt(np.diag(cov_matrix)), marker='o')
71
+ ax.set_xlabel("Risiko (Standar Deviasi)")
72
+ ax.set_ylabel("Return Tahunan")
73
+ ax.set_title("Efficient Frontier")
74
+ st.pyplot(fig)
75
+ else:
76
+ st.error("Optimasi portofolio gagal. Coba dengan saham yang berbeda.")
77
+
78
  except Exception as e:
79
+ st.error(f"Terjadi kesalahan: {e}")