Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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
|
| 13 |
-
|
|
|
|
| 14 |
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
return None
|
| 18 |
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 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 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
return -portfolio_return / portfolio_volatility
|
| 39 |
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
|
|
|
|
|
|
| 43 |
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
|
|
|
| 56 |
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 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 |
-
|
| 68 |
-
|
| 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 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|