GarGerry commited on
Commit
0cd95d3
·
verified ·
1 Parent(s): 345ac6c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -72
app.py CHANGED
@@ -3,6 +3,7 @@ import yfinance as yf
3
  import numpy as np
4
  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):
@@ -56,88 +57,84 @@ def generate_efficient_frontier(returns, cov_matrix, num_portfolios=5000):
56
 
57
  return results
58
 
59
- st.title("Analisis Portofolio Saham Optimal (Model Markowitz)")
60
-
61
- st.markdown("""
62
- ### Teori Markowitz
63
- Model Markowitz, atau Modern Portfolio Theory (MPT), digunakan untuk membangun portofolio investasi optimal dengan memaksimalkan return untuk tingkat risiko tertentu.
64
 
65
- Portofolio yang optimal ditemukan dengan menghitung kombinasi terbaik dari aset yang tersedia untuk meminimalkan risiko dan memaksimalkan return.
66
- """)
 
 
 
 
 
67
 
68
- def get_recommended_stocks():
69
- return "KLBF.JK, SIDO.JK, KAEF.JK, TLKM.JK, UNVR.JK"
 
 
 
 
 
70
 
71
- def validate_tickers(tickers):
72
- invalid_tickers = [t for t in tickers if yf.Ticker(t).history(period='1d').empty]
73
- if invalid_tickers:
74
- st.warning(f"Ticker tidak valid atau tidak memiliki data: {', '.join(invalid_tickers)}")
75
- return False
76
- return True
77
 
78
  st.write("Rekomendasi Saham yang Bertahan Saat COVID-19:")
79
- st.write(get_recommended_stocks())
80
 
81
  tickers_list = st.text_input("Masukkan ticker saham", "KLBF.JK, SIDO.JK, KAEF.JK").split(", ")
82
  start_date = st.date_input("Pilih tanggal mulai", pd.to_datetime("2020-01-01"))
83
  end_date = st.date_input("Pilih tanggal akhir", pd.to_datetime("2023-12-31"))
84
 
85
  if st.button("Analisis Portofolio"):
86
- if validate_tickers(tickers_list):
87
- stock_data = get_stock_data(tickers_list, start_date, end_date)
88
- if stock_data is not None:
89
- mean_returns, cov_matrix = calculate_returns(stock_data)
90
- optimal_weights = optimize_portfolio(mean_returns, cov_matrix)
91
 
92
- st.subheader("Statistik Saham")
93
- st.write(stock_data.describe())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
- if optimal_weights is not None:
96
- st.subheader("Bobot Portofolio Optimal")
97
- portfolio_weights = {stock: weight for stock, weight in zip(stock_data.columns, optimal_weights)}
98
- st.write(portfolio_weights)
99
-
100
- # Pie Chart dengan pengelompokan saham kecil ke "Others"
101
- threshold = 0.05 # Saham dengan bobot <5% digabung ke "Others"
102
- large_weights = {k: v for k, v in portfolio_weights.items() if v >= threshold}
103
- small_weights = {k: v for k, v in portfolio_weights.items() if v < threshold}
104
-
105
- if small_weights:
106
- large_weights["Others"] = sum(small_weights.values())
107
-
108
- fig, ax = plt.subplots()
109
- ax.pie(large_weights.values(), labels=large_weights.keys(), autopct='%1.1f%%', startangle=140)
110
- ax.axis('equal')
111
- st.pyplot(fig)
112
-
113
- st.markdown("""
114
- **Interpretasi Pie Chart:**
115
- - Pie chart ini menunjukkan distribusi bobot optimal dari setiap saham dalam portofolio.
116
- - Saham dengan bobot signifikan ditampilkan dengan persentase masing-masing.
117
- - Saham dengan bobot kecil (<5%) digabung ke dalam kategori "Others".
118
- - Portofolio optimal didasarkan pada perhitungan rasio Sharpe, yang mencari keseimbangan terbaik antara return dan risiko.
119
- """)
120
-
121
- # Efficient Frontier
122
- results = generate_efficient_frontier(mean_returns, cov_matrix)
123
-
124
- st.subheader("Efficient Frontier")
125
- fig, ax = plt.subplots()
126
- scatter = ax.scatter(results[1, :], results[0, :], c=results[2, :], cmap="viridis", marker='o')
127
- ax.set_xlabel("Risiko (Standar Deviasi)")
128
- ax.set_ylabel("Return Tahunan")
129
- ax.set_title("Efficient Frontier")
130
- fig.colorbar(scatter, label="Sharpe Ratio")
131
- st.pyplot(fig)
132
-
133
- st.markdown("""
134
- **Interpretasi:**
135
- - **Bobot Portofolio Optimal**: Menunjukkan alokasi dana ke setiap saham.
136
- - **Grafik Efficient Frontier**:
137
- - Sumbu **X**: Risiko (diukur dengan standar deviasi return portofolio).
138
- - Sumbu **Y**: Return tahunan dari berbagai kombinasi portofolio.
139
- - Warna titik menunjukkan **Sharpe Ratio** – semakin terang warna, semakin optimal kombinasi risiko dan return.
140
- - **Pemilihan Portofolio Terbaik**: Portofolio di frontier efisien memberikan return terbaik untuk tingkat risiko tertentu.
141
- """)
142
- else:
143
- st.error("Optimasi portofolio gagal. Coba dengan saham yang berbeda.")
 
3
  import numpy as np
4
  import pandas as pd
5
  import matplotlib.pyplot as plt
6
+ import seaborn as sns
7
  import scipy.optimize as sco
8
 
9
  def get_stock_data(tickers, start, end):
 
57
 
58
  return results
59
 
60
+ def plot_correlation_heatmap(data):
61
+ correlation_matrix = data.corr()
62
+ fig, ax = plt.subplots()
63
+ sns.heatmap(correlation_matrix, annot=True, cmap="coolwarm", ax=ax)
64
+ st.pyplot(fig)
65
 
66
+ def plot_moving_averages(data, stock):
67
+ fig, ax = plt.subplots()
68
+ data[stock].plot(label='Harga', ax=ax)
69
+ data[stock].rolling(window=50).mean().plot(label='SMA 50', ax=ax)
70
+ data[stock].rolling(window=200).mean().plot(label='SMA 200', ax=ax)
71
+ ax.legend()
72
+ st.pyplot(fig)
73
 
74
+ def simulate_dca(data, investment_amount=100):
75
+ investment_dates = data.index[::30]
76
+ dca_values = data.loc[investment_dates].mean(axis=1) * investment_amount
77
+ total_value = dca_values.cumsum()
78
+ fig, ax = plt.subplots()
79
+ total_value.plot(ax=ax, title='Simulasi Investasi DCA')
80
+ st.pyplot(fig)
81
 
82
+ st.title("Analisis Portofolio Saham Optimal (Model Markowitz)")
 
 
 
 
 
83
 
84
  st.write("Rekomendasi Saham yang Bertahan Saat COVID-19:")
85
+ st.write("KLBF.JK, SIDO.JK, KAEF.JK, TLKM.JK, UNVR.JK")
86
 
87
  tickers_list = st.text_input("Masukkan ticker saham", "KLBF.JK, SIDO.JK, KAEF.JK").split(", ")
88
  start_date = st.date_input("Pilih tanggal mulai", pd.to_datetime("2020-01-01"))
89
  end_date = st.date_input("Pilih tanggal akhir", pd.to_datetime("2023-12-31"))
90
 
91
  if st.button("Analisis Portofolio"):
92
+ stock_data = get_stock_data(tickers_list, start_date, end_date)
93
+ if stock_data is not None:
94
+ mean_returns, cov_matrix = calculate_returns(stock_data)
95
+ optimal_weights = optimize_portfolio(mean_returns, cov_matrix)
 
96
 
97
+ st.subheader("Statistik Saham")
98
+ st.write(stock_data.describe())
99
+
100
+ st.subheader("Heatmap Korelasi Saham")
101
+ plot_correlation_heatmap(stock_data)
102
+
103
+ st.subheader("Moving Average untuk Prediksi Tren")
104
+ selected_stock = st.selectbox("Pilih saham untuk analisis MA", stock_data.columns)
105
+ plot_moving_averages(stock_data, selected_stock)
106
+
107
+ st.subheader("Simulasi Investasi Dollar Cost Averaging (DCA)")
108
+ simulate_dca(stock_data)
109
+
110
+ if optimal_weights is not None:
111
+ st.subheader("Bobot Portofolio Optimal")
112
+ portfolio_weights = {stock: weight for stock, weight in zip(stock_data.columns, optimal_weights)}
113
+ st.write(portfolio_weights)
114
+
115
+ # Pie Chart dengan pengelompokan saham kecil ke "Others"
116
+ threshold = 0.05
117
+ large_weights = {k: v for k, v in portfolio_weights.items() if v >= threshold}
118
+ small_weights = {k: v for k, v in portfolio_weights.items() if v < threshold}
119
+
120
+ if small_weights:
121
+ large_weights["Others"] = sum(small_weights.values())
122
+
123
+ fig, ax = plt.subplots()
124
+ ax.pie(large_weights.values(), labels=large_weights.keys(), autopct='%1.1f%%', startangle=140)
125
+ ax.axis('equal')
126
+ st.pyplot(fig)
127
+
128
+ # Efficient Frontier
129
+ results = generate_efficient_frontier(mean_returns, cov_matrix)
130
 
131
+ st.subheader("Efficient Frontier")
132
+ fig, ax = plt.subplots()
133
+ scatter = ax.scatter(results[1, :], results[0, :], c=results[2, :], cmap="viridis", marker='o')
134
+ ax.set_xlabel("Risiko (Standar Deviasi)")
135
+ ax.set_ylabel("Return Tahunan")
136
+ ax.set_title("Efficient Frontier")
137
+ fig.colorbar(scatter, label="Sharpe Ratio")
138
+ st.pyplot(fig)
139
+ else:
140
+ st.error("Optimasi portofolio gagal. Coba dengan saham yang berbeda.")