GarGerry commited on
Commit
a577e2a
·
verified ·
1 Parent(s): a493e84

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -100
app.py CHANGED
@@ -1,115 +1,54 @@
1
  import streamlit as st
2
- import yfinance as yf
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
- import plotly.express as px
9
- import plotly.graph_objects as go
10
- from fpdf import FPDF
11
 
12
- def get_stock_data(tickers, start, end):
13
- data = yf.download(tickers, start=start, end=end)
 
14
 
15
- if data.empty:
16
- st.error("Data saham tidak ditemukan. Periksa ticker atau rentang tanggal.")
17
- return None
18
 
19
- if 'Adj Close' in data.columns:
20
- return data['Adj Close']
21
- elif 'Close' in data.columns:
22
- st.warning("Menggunakan 'Close' karena 'Adj Close' tidak tersedia.")
23
- return data['Close']
24
- else:
25
- st.error("Data harga penutupan tidak ditemukan.")
26
- return None
27
-
28
- def calculate_returns(data):
29
- log_returns = np.log(data / data.shift(1))
30
- return log_returns.mean() * 252, log_returns.cov() * 252
31
-
32
- def optimize_portfolio(returns, cov_matrix):
33
- num_assets = len(returns)
34
 
35
- def sharpe_ratio(weights):
36
- portfolio_return = np.dot(weights, returns)
37
- portfolio_volatility = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
38
- return -portfolio_return / portfolio_volatility
39
 
40
- constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
41
- bounds = tuple((0, 1) for _ in range(num_assets))
42
- init_guess = num_assets * [1. / num_assets]
 
 
43
 
44
- result = sco.minimize(sharpe_ratio, init_guess, method='SLSQP', bounds=bounds, constraints=constraints)
45
- return result.x if result.success else None
46
-
47
- def simulate_monte_carlo(returns, cov_matrix, num_simulations=10000, time_horizon=252):
48
- num_assets = len(returns)
49
- simulated_returns = np.zeros(num_simulations)
50
- simulated_volatility = np.zeros(num_simulations)
51
 
52
- for i in range(num_simulations):
53
- weights = np.random.dirichlet(np.ones(num_assets), size=1)[0]
54
- simulated_returns[i] = np.dot(weights, returns)
55
- simulated_volatility[i] = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
 
56
 
57
- fig = px.scatter(x=simulated_volatility, y=simulated_returns, color=simulated_returns/simulated_volatility,
58
- labels={'x': 'Volatilitas', 'y': 'Return'},
59
- title='Simulasi Monte Carlo')
60
- st.plotly_chart(fig)
61
-
62
- def stock_screener():
63
- st.sidebar.header("Stock Screener")
64
- pe_ratio = st.sidebar.slider("Maksimum P/E Ratio", 0, 100, 20)
65
- market_cap = st.sidebar.selectbox("Market Cap", ["Small", "Mid", "Large"])
66
 
67
- # Simulasi data screener (contoh)
68
- screener_data = pd.DataFrame({
69
- 'Ticker': ['AAPL', 'MSFT', 'GOOGL', 'TSLA', 'AMZN'],
70
- 'P/E Ratio': [30, 25, 35, 40, 28],
71
- 'Market Cap': ['Large', 'Large', 'Large', 'Mid', 'Large']
72
- })
73
- filtered_stocks = screener_data[(screener_data['P/E Ratio'] <= pe_ratio) & (screener_data['Market Cap'] == market_cap)]
74
- st.sidebar.write("Saham yang memenuhi kriteria:")
75
- st.sidebar.write(filtered_stocks)
76
-
77
- def export_to_pdf(stock_data):
78
- pdf = FPDF()
79
- pdf.add_page()
80
- pdf.set_font("Arial", size=12)
81
- pdf.cell(200, 10, txt="Laporan Analisis Saham", ln=True, align='C')
82
- pdf.ln(10)
83
- for ticker in stock_data.columns:
84
- pdf.cell(200, 10, txt=f"{ticker}: {stock_data[ticker].iloc[-1]}", ln=True)
85
- pdf.output("stock_report.pdf")
86
- st.success("Laporan PDF telah dibuat!")
87
-
88
- st.title("Analisis Portofolio Saham Optimal (Model Markowitz)")
89
-
90
- st.write("Rekomendasi Saham yang Bertahan Saat COVID-19:")
91
- st.write("KLBF.JK, SIDO.JK, KAEF.JK, TLKM.JK, UNVR.JK")
92
-
93
- tickers_list = st.text_input("Masukkan ticker saham", "KLBF.JK, SIDO.JK, KAEF.JK").split(", ")
94
- start_date = st.date_input("Pilih tanggal mulai", pd.to_datetime("2020-01-01"))
95
- end_date = st.date_input("Pilih tanggal akhir", pd.to_datetime("2023-12-31"))
96
- stock_screener()
97
 
98
- if st.button("Analisis Portofolio"):
99
- stock_data = get_stock_data(tickers_list, start_date, end_date)
100
- if stock_data is not None:
101
- mean_returns, cov_matrix = calculate_returns(stock_data)
102
- optimal_weights = optimize_portfolio(mean_returns, cov_matrix)
103
 
104
- st.subheader("Simulasi Monte Carlo")
105
- simulate_monte_carlo(mean_returns, cov_matrix)
106
 
107
- if st.button("Export to PDF"):
108
- export_to_pdf(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
- else:
115
- st.error("Optimasi portofolio gagal. Coba dengan saham yang berbeda.")
 
1
  import streamlit as st
 
 
2
  import pandas as pd
3
  import matplotlib.pyplot as plt
 
 
 
 
 
4
 
5
+ def main():
6
+ st.title("Financial Budget Planner 💰")
7
+ st.write("Kelola keuanganmu dengan lebih baik!")
8
 
9
+ # Input pemasukan
10
+ income = st.number_input("Masukkan total pemasukan bulanan (Rp)", min_value=0, step=100000)
 
11
 
12
+ # Input pengeluaran
13
+ st.subheader("Pengeluaran Bulanan")
14
+ categories = ["Makanan", "Transportasi", "Hiburan", "Tagihan", "Tabungan", "Lainnya"]
15
+ expenses = {}
16
+ total_expense = 0
 
 
 
 
 
 
 
 
 
 
17
 
18
+ for category in categories:
19
+ expenses[category] = st.number_input(f"{category} (Rp)", min_value=0, step=50000)
20
+ total_expense += expenses[category]
 
21
 
22
+ # Sisa saldo
23
+ remaining_balance = income - total_expense
24
+ st.subheader("Ringkasan Keuangan")
25
+ st.write(f"Total Pengeluaran: Rp {total_expense:,}")
26
+ st.write(f"Sisa Saldo: Rp {remaining_balance:,}")
27
 
28
+ # Visualisasi data
29
+ if total_expense > 0:
30
+ df = pd.DataFrame(expenses.items(), columns=["Kategori", "Jumlah"])
31
+ fig, ax = plt.subplots()
32
+ ax.pie(df["Jumlah"], labels=df["Kategori"], autopct='%1.1f%%', startangle=90, colors=["#ff9999", "#66b3ff", "#99ff99", "#ffcc99", "#c2c2f0", "#ffb3e6"])
33
+ ax.axis('equal')
34
+ st.pyplot(fig)
35
 
36
+ # Rekomendasi tabungan
37
+ if income > 0:
38
+ save_percentage = 20 if income > 5000000 else 10
39
+ recommended_savings = income * save_percentage / 100
40
+ st.write(f"💡 Rekomendasi: Sisihkan sekitar **{save_percentage}%** dari pemasukan untuk tabungan: Rp {recommended_savings:,}")
41
 
42
+ # Notifikasi jika over budget
43
+ if remaining_balance < 0:
44
+ st.warning("⚠️ Pengeluaran lebih besar dari pemasukan! Pertimbangkan untuk mengurangi pengeluaran.")
 
 
 
 
 
 
45
 
46
+ if __name__ == "__main__":
47
+ main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
+ # Requirements:
50
+ # streamlit
51
+ # pandas
52
+ # matplotlib
 
53
 
 
 
54