Spaces:
Sleeping
Sleeping
Enes Berke Karaoğlan commited on
Commit ·
abf2ca2
1
Parent(s): a8b14d1
fix: Veri çekme hatası düzeltildi, hata kontrolleri geliştirildi
Browse files
app.py
CHANGED
|
@@ -2,133 +2,166 @@ import streamlit as st
|
|
| 2 |
import pandas as pd
|
| 3 |
import numpy as np
|
| 4 |
import yfinance as yf
|
|
|
|
| 5 |
import plotly.express as px
|
|
|
|
| 6 |
|
| 7 |
-
|
| 8 |
-
st.title('Portföy Yönetim Aracı')
|
| 9 |
|
| 10 |
-
#
|
| 11 |
-
st.sidebar.header("
|
| 12 |
-
|
| 13 |
-
symbols = [sym.strip().upper() for sym in
|
| 14 |
|
| 15 |
-
|
| 16 |
-
|
| 17 |
for sym in symbols:
|
| 18 |
-
amount = st.sidebar.number_input(f
|
| 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 |
-
if not df.empty and not df.isnull().all().all():
|
| 46 |
-
# Portföy performansını hesaplayın
|
| 47 |
-
total_investment = sum(amounts.values())
|
| 48 |
|
|
|
|
|
|
|
| 49 |
if not df.empty:
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
# Grafikler
|
| 59 |
-
st.subheader("📈 Hisse Senedi Fiyatları")
|
| 60 |
-
fig = px.line(df, title="Hisse Senedi Fiyatları")
|
| 61 |
-
st.plotly_chart(fig)
|
| 62 |
-
|
| 63 |
-
st.subheader("📊 Portföy Dağılım Grafiği")
|
| 64 |
-
fig = px.bar(x=amounts.keys(), y=portfolio_value, labels={"x": 'Yatırım Araçları', 'y': 'Portföy Değeri'})
|
| 65 |
-
st.plotly_chart(fig)
|
| 66 |
-
|
| 67 |
-
# Getiri hesaplamaları
|
| 68 |
-
st.subheader("📅 Günlük Getiriler")
|
| 69 |
-
daily_returns = df.pct_change().dropna()
|
| 70 |
-
st.dataframe(daily_returns)
|
| 71 |
-
|
| 72 |
-
st.subheader("📅 Aylık Getiriler")
|
| 73 |
-
monthly_returns = df.resample('M').ffill().pct_change().dropna()
|
| 74 |
-
st.dataframe(monthly_returns)
|
| 75 |
-
|
| 76 |
-
st.subheader("📅 Yıllık Getiriler")
|
| 77 |
-
annual_returns = df.resample('Y').ffill().pct_change().dropna()
|
| 78 |
-
st.dataframe(annual_returns)
|
| 79 |
-
|
| 80 |
-
# Risk Analizi
|
| 81 |
-
st.subheader("📊 Volatilite (Yıllık)")
|
| 82 |
-
volatility = daily_returns.std() * np.sqrt(252)
|
| 83 |
-
st.dataframe(volatility)
|
| 84 |
-
|
| 85 |
-
st.subheader("📉 Beta Değeri")
|
| 86 |
-
if not daily_returns.empty:
|
| 87 |
-
beta = daily_returns.cov() / daily_returns.var()
|
| 88 |
-
st.dataframe(beta)
|
| 89 |
-
|
| 90 |
-
# Hareketli Ortalama
|
| 91 |
-
st.subheader("📊 Hareketli Ortalama")
|
| 92 |
-
window_size = st.sidebar.slider("Hareketli Ortalama Penceresi (Gün)", 5, 100, 20)
|
| 93 |
-
moving_avg = df.rolling(window=window_size).mean()
|
| 94 |
-
st.line_chart(moving_avg)
|
| 95 |
-
|
| 96 |
-
# Tarih Aralığı Filtreleme
|
| 97 |
-
st.subheader("📅 Tarih Aralığına Göre Veri Filtreleme")
|
| 98 |
-
start_date = st.sidebar.date_input("📅 Başlangıç Tarihi", pd.to_datetime("2023-01-01"))
|
| 99 |
-
end_date = st.sidebar.date_input("📅 Bitiş Tarihi", pd.to_datetime("2024-01-01"))
|
| 100 |
-
|
| 101 |
-
if start_date < end_date:
|
| 102 |
-
filtered_data = df[(df.index >= start_date) & (df.index <= end_date)]
|
| 103 |
-
st.line_chart(filtered_data)
|
| 104 |
else:
|
| 105 |
-
st.
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
for symbol in symbols:
|
| 119 |
-
if symbol in df.columns:
|
| 120 |
-
price_series = [df[symbol].iloc[-1]]
|
| 121 |
-
for _ in range(365): # 1 yıl
|
| 122 |
-
price_series.append(price_series[-1] * (1 + np.random.normal(mean_returns[symbol], volatility[symbol])))
|
| 123 |
-
simulated_prices.append(price_series)
|
| 124 |
-
|
| 125 |
-
if simulated_prices:
|
| 126 |
-
simulation_df[x] = pd.Series([np.sum(sim) for sim in zip(*simulated_prices)])
|
| 127 |
-
|
| 128 |
-
st.line_chart(simulation_df)
|
| 129 |
else:
|
| 130 |
-
st.warning("
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
import pandas as pd
|
| 3 |
import numpy as np
|
| 4 |
import yfinance as yf
|
| 5 |
+
import plotly.graph_objects as go
|
| 6 |
import plotly.express as px
|
| 7 |
+
from datetime import datetime
|
| 8 |
|
| 9 |
+
st.title("Portföy Yönetim Aracı")
|
|
|
|
| 10 |
|
| 11 |
+
# Yan panel girdileri
|
| 12 |
+
st.sidebar.header("Kullanıcı Girdileri")
|
| 13 |
+
symbols_input = st.sidebar.text_input("Hisse Senedi Sembolleri (virgülle ayrılmış)", value="AAPL, MSFT, TSLA")
|
| 14 |
+
symbols = [sym.strip().upper() for sym in symbols_input.split(",") if sym.strip()]
|
| 15 |
|
| 16 |
+
investment_amounts = {}
|
| 17 |
+
st.sidebar.subheader("Yatırım Miktarları (Adet)")
|
| 18 |
for sym in symbols:
|
| 19 |
+
amount = st.sidebar.number_input(f"{sym} için adet", min_value=0.0, value=0.0, step=1.0)
|
| 20 |
+
investment_amounts[sym] = amount
|
| 21 |
+
|
| 22 |
+
st.sidebar.header("Tarih Aralığı")
|
| 23 |
+
start_date = st.sidebar.date_input("Başlangıç Tarihi", value=datetime(2022, 1, 3))
|
| 24 |
+
end_date = st.sidebar.date_input("Bitiş Tarihi", value=datetime(2024, 1, 1))
|
| 25 |
+
|
| 26 |
+
st.sidebar.header("Hareketli Ortalama")
|
| 27 |
+
ma_window = st.sidebar.number_input("Hareketli Ortalama Pencere Boyutu (gün)", min_value=1, value=20, step=1)
|
| 28 |
+
|
| 29 |
+
@st.cache_data # st.cache yerine st.cache_data kullanılması önerilir
|
| 30 |
+
def load_data(symbol, start_date, end_date):
|
| 31 |
+
try:
|
| 32 |
+
data = yf.download(symbol, start=start_date, end=end_date)
|
| 33 |
+
if data.empty:
|
| 34 |
+
st.warning(f"{symbol} için veri bulunamadı veya boş döndü.")
|
| 35 |
+
return data
|
| 36 |
+
except Exception as e:
|
| 37 |
+
st.error(f"{symbol} verisi çekilirken hata oluştu: {e}")
|
| 38 |
+
return None
|
| 39 |
+
|
| 40 |
+
data_dict = {}
|
| 41 |
+
for sym in symbols:
|
| 42 |
+
df = load_data(sym, start_date, end_date)
|
| 43 |
+
if df is not None:
|
| 44 |
+
data_dict[sym] = df
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
+
st.header("Hisse Senedi Fiyatları")
|
| 47 |
+
for sym, df in data_dict.items():
|
| 48 |
if not df.empty:
|
| 49 |
+
fig = go.Figure()
|
| 50 |
+
fig.add_trace(go.Scatter(x=df.index, y=df['Close'], mode='lines', name='Kapanış Fiyatı'))
|
| 51 |
+
fig.add_trace(go.Scatter(x=df.index,
|
| 52 |
+
y=df['Close'].rolling(window=int(ma_window)).mean(),
|
| 53 |
+
mode='lines',
|
| 54 |
+
name=f'{ma_window} Günlük MA'))
|
| 55 |
+
fig.update_layout(title=f"{sym} Fiyat Grafiği", xaxis_title="Tarih", yaxis_title="Fiyat (USD)")
|
| 56 |
+
st.plotly_chart(fig)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
else:
|
| 58 |
+
st.warning(f"{sym} için çizilecek veri yok.")
|
| 59 |
+
|
| 60 |
+
st.header("Portföy Performansı")
|
| 61 |
+
portfolio_value = 0
|
| 62 |
+
portfolio_values = {}
|
| 63 |
+
|
| 64 |
+
for sym, df in data_dict.items():
|
| 65 |
+
# Eğer df boş değilse hesaplamaları yap
|
| 66 |
+
if df is not None and not df.empty:
|
| 67 |
+
latest_price = df['Close'].iloc[-1]
|
| 68 |
+
value = latest_price * investment_amounts[sym]
|
| 69 |
+
portfolio_values[sym] = value
|
| 70 |
+
portfolio_value += value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
else:
|
| 72 |
+
st.warning(f"{sym} veri seti boş veya None, hesaplamalar atlanıyor.")
|
| 73 |
+
|
| 74 |
+
st.write("Güncel Portföy Değeri: $", round(portfolio_value, 2))
|
| 75 |
+
portfolio_df = pd.DataFrame({
|
| 76 |
+
"Sembol": list(portfolio_values.keys()),
|
| 77 |
+
"Değer": list(portfolio_values.values())
|
| 78 |
+
})
|
| 79 |
+
fig_bar = px.bar(portfolio_df, x="Sembol", y="Değer", title="Portföy Dağılım Grafiği", labels={"Değer": "Değer ($)"})
|
| 80 |
+
st.plotly_chart(fig_bar)
|
| 81 |
+
|
| 82 |
+
# Getiri Hesaplamaları
|
| 83 |
+
st.header("Getiri Hesaplamaları")
|
| 84 |
+
returns_data = {}
|
| 85 |
+
for sym, df in data_dict.items():
|
| 86 |
+
df = df.copy()
|
| 87 |
+
df['Daily Return'] = df['Close'].pct_change()
|
| 88 |
+
returns_data[sym] = df['Daily Return']
|
| 89 |
+
|
| 90 |
+
# Günlük Getiri Tablosu
|
| 91 |
+
st.subheader("Günlük Getiriler")
|
| 92 |
+
daily_returns_df = pd.DataFrame({sym: data['Daily Return'] for sym, data in data_dict.items()})
|
| 93 |
+
st.dataframe(daily_returns_df.tail())
|
| 94 |
+
|
| 95 |
+
# Aylık Getiri Hesaplaması
|
| 96 |
+
st.subheader("Aylık Getiriler")
|
| 97 |
+
monthly_returns = {}
|
| 98 |
+
for sym, df in data_dict.items():
|
| 99 |
+
df = df.copy()
|
| 100 |
+
df['Monthly Return'] = df['Close'].resample('M').ffill().pct_change()
|
| 101 |
+
monthly_returns[sym] = df['Monthly Return']
|
| 102 |
+
monthly_returns_df = pd.DataFrame(monthly_returns)
|
| 103 |
+
st.dataframe(monthly_returns_df.tail())
|
| 104 |
+
|
| 105 |
+
# Yıllık Getiri Hesaplaması
|
| 106 |
+
st.subheader("Yıllık Getiriler")
|
| 107 |
+
annual_returns = {}
|
| 108 |
+
for sym, df in data_dict.items():
|
| 109 |
+
df = df.copy()
|
| 110 |
+
df['Annual Return'] = df['Close'].resample('Y').ffill().pct_change()
|
| 111 |
+
annual_returns[sym] = df['Annual Return']
|
| 112 |
+
annual_returns_df = pd.DataFrame(annual_returns)
|
| 113 |
+
st.dataframe(annual_returns_df.tail())
|
| 114 |
+
|
| 115 |
+
# Risk Analizi
|
| 116 |
+
st.header("Risk Analizi")
|
| 117 |
+
risk_metrics = {}
|
| 118 |
+
for sym, df in data_dict.items():
|
| 119 |
+
df = df.copy()
|
| 120 |
+
daily_vol = df['Daily Return'].std()
|
| 121 |
+
annual_vol = daily_vol * np.sqrt(252)
|
| 122 |
+
risk_metrics[sym] = {"Günlük Volatilite": daily_vol, "Yıllık Volatilite": annual_vol}
|
| 123 |
+
|
| 124 |
+
risk_df = pd.DataFrame(risk_metrics).T
|
| 125 |
+
st.dataframe(risk_df)
|
| 126 |
+
|
| 127 |
+
# Portföyün Günlük Getirilerinin Hesaplanması (Yatırım miktarlarına göre ağırlıklandırma)
|
| 128 |
+
portfolio_daily_returns = pd.Series(0, index=list(data_dict.values())[0].index)
|
| 129 |
+
total_investment = sum(investment_amounts[sym] for sym in symbols if sym in investment_amounts and investment_amounts[sym] > 0)
|
| 130 |
+
for sym, df in data_dict.items():
|
| 131 |
+
weight = investment_amounts[sym] / total_investment if total_investment > 0 else 0
|
| 132 |
+
portfolio_daily_returns += df['Daily Return'] * weight
|
| 133 |
+
|
| 134 |
+
# Beta Hesaplaması: Her hisse için, portföy getirisine göre beta = cov(ha, portföy)/var(portföy)
|
| 135 |
+
beta_values = {}
|
| 136 |
+
for sym, df in data_dict.items():
|
| 137 |
+
covariance = np.cov(df['Daily Return'].dropna(), portfolio_daily_returns.dropna())[0, 1]
|
| 138 |
+
variance = np.var(portfolio_daily_returns.dropna())
|
| 139 |
+
beta = covariance / variance if variance != 0 else np.nan
|
| 140 |
+
beta_values[sym] = beta
|
| 141 |
+
|
| 142 |
+
beta_df = pd.DataFrame.from_dict(beta_values, orient='index', columns=["Beta"])
|
| 143 |
+
st.subheader("Beta Değerleri")
|
| 144 |
+
st.dataframe(beta_df)
|
| 145 |
+
|
| 146 |
+
# Monte Carlo Simülasyonu: Portföyün 1 yıl sonraki değeri için 1000 simülasyon
|
| 147 |
+
st.header("Monte Carlo Simülasyonu ile Gelecek Portföy Değeri Tahmini")
|
| 148 |
+
simulations = 1000
|
| 149 |
+
days = 365
|
| 150 |
+
last_portfolio_value = portfolio_value
|
| 151 |
+
|
| 152 |
+
# Portföy günlük getirilerinin ortalama ve standart sapması
|
| 153 |
+
portfolio_daily_mean = portfolio_daily_returns.mean()
|
| 154 |
+
portfolio_daily_std = portfolio_daily_returns.std()
|
| 155 |
+
|
| 156 |
+
simulation_results = []
|
| 157 |
+
for i in range(simulations):
|
| 158 |
+
simulated_value = last_portfolio_value
|
| 159 |
+
for d in range(days):
|
| 160 |
+
simulated_return = np.random.normal(portfolio_daily_mean, portfolio_daily_std)
|
| 161 |
+
simulated_value *= (1 + simulated_return)
|
| 162 |
+
simulation_results.append(simulated_value)
|
| 163 |
+
|
| 164 |
+
fig_hist = px.histogram(simulation_results, nbins=50,
|
| 165 |
+
title="Monte Carlo Simülasyonu Sonuçları (1 Yıl Sonra Portföy Değeri Dağılımı)",
|
| 166 |
+
labels={"value": "Portföy Değeri", "count": "Frekans"})
|
| 167 |
+
st.plotly_chart(fig_hist)
|