import streamlit as st
import pandas as pd
import numpy as np
import yfinance as yf
import plotly.graph_objects as go
import plotly.express as px
from datetime import datetime

st.title("Portföy Yönetim Aracı")

# Yan panel girdileri
st.sidebar.header("Kullanıcı Girdileri")
symbols_input = st.sidebar.text_input("Hisse Senedi Sembolleri (virgülle ayrılmış)", value="AAPL, MSFT, TSLA")
symbols = [sym.strip().upper() for sym in symbols_input.split(",") if sym.strip()]

investment_amounts = {}
st.sidebar.subheader("Yatırım Miktarları (Adet)")
for sym in symbols:
    amount = st.sidebar.number_input(f"{sym} için adet", min_value=0.0, value=0.0, step=1.0)
    investment_amounts[sym] = amount

st.sidebar.header("Tarih Aralığı")
start_date = st.sidebar.date_input("Başlangıç Tarihi", value=datetime(2022, 1, 3))
end_date = st.sidebar.date_input("Bitiş Tarihi", value=datetime(2024, 1, 1))

st.sidebar.header("Hareketli Ortalama")
ma_window = st.sidebar.number_input("Hareketli Ortalama Pencere Boyutu (gün)", min_value=1, value=20, step=1)

@st.cache_data  # st.cache yerine st.cache_data kullanılması önerilir
def load_data(symbol, start_date, end_date):
    try:
        data = yf.download(symbol, start=start_date, end=end_date)
        if data.empty:
            st.warning(f"{symbol} için veri bulunamadı veya boş döndü.")
        return data
    except Exception as e:
        st.error(f"{symbol} verisi çekilirken hata oluştu: {e}")
        return None

data_dict = {}
for sym in symbols:
    df = load_data(sym, start_date, end_date)
    if df is not None:
        data_dict[sym] = df

st.header("Hisse Senedi Fiyatları")
for sym, df in data_dict.items():
    if not df.empty:
        fig = go.Figure()
        fig.add_trace(go.Scatter(x=df.index, y=df['Close'], mode='lines', name='Kapanış Fiyatı'))
        fig.add_trace(go.Scatter(x=df.index, 
                                 y=df['Close'].rolling(window=int(ma_window)).mean(), 
                                 mode='lines', 
                                 name=f'{ma_window} Günlük MA'))
        fig.update_layout(title=f"{sym} Fiyat Grafiği", xaxis_title="Tarih", yaxis_title="Fiyat (USD)")
        st.plotly_chart(fig)
    else:
        st.warning(f"{sym} için çizilecek veri yok.")

st.header("Portföy Performansı")
portfolio_value = 0
portfolio_values = {}

for sym, df in data_dict.items():
    # Eğer df boş değilse hesaplamaları yap
    if df is not None and not df.empty:
        latest_price = df['Close'].iloc[-1]
        value = latest_price * investment_amounts[sym]
        portfolio_values[sym] = value
        portfolio_value += value
    else:
        st.warning(f"{sym} veri seti boş veya None, hesaplamalar atlanıyor.")

st.write("Güncel Portföy Değeri: $", round(portfolio_value, 2))
portfolio_df = pd.DataFrame({
    "Sembol": list(portfolio_values.keys()),
    "Değer": list(portfolio_values.values())
})
fig_bar = px.bar(portfolio_df, x="Sembol", y="Değer", title="Portföy Dağılım Grafiği", labels={"Değer": "Değer ($)"})
st.plotly_chart(fig_bar)

# Getiri Hesaplamaları
st.header("Getiri Hesaplamaları")
returns_data = {}
for sym, df in data_dict.items():
    df = df.copy()
    df['Daily Return'] = df['Close'].pct_change()
    returns_data[sym] = df['Daily Return']

# Günlük Getiri Tablosu
st.subheader("Günlük Getiriler")
daily_returns_df = pd.DataFrame({sym: data['Daily Return'] for sym, data in data_dict.items()})
st.dataframe(daily_returns_df.tail())

# Aylık Getiri Hesaplaması
st.subheader("Aylık Getiriler")
monthly_returns = {}
for sym, df in data_dict.items():
    df = df.copy()
    df['Monthly Return'] = df['Close'].resample('M').ffill().pct_change()
    monthly_returns[sym] = df['Monthly Return']
monthly_returns_df = pd.DataFrame(monthly_returns)
st.dataframe(monthly_returns_df.tail())

# Yıllık Getiri Hesaplaması
st.subheader("Yıllık Getiriler")
annual_returns = {}
for sym, df in data_dict.items():
    df = df.copy()
    df['Annual Return'] = df['Close'].resample('Y').ffill().pct_change()
    annual_returns[sym] = df['Annual Return']
annual_returns_df = pd.DataFrame(annual_returns)
st.dataframe(annual_returns_df.tail())

# Risk Analizi
st.header("Risk Analizi")
risk_metrics = {}
for sym, df in data_dict.items():
    df = df.copy()
    daily_vol = df['Daily Return'].std()
    annual_vol = daily_vol * np.sqrt(252)
    risk_metrics[sym] = {"Günlük Volatilite": daily_vol, "Yıllık Volatilite": annual_vol}

risk_df = pd.DataFrame(risk_metrics).T
st.dataframe(risk_df)

# Portföyün Günlük Getirilerinin Hesaplanması (Yatırım miktarlarına göre ağırlıklandırma)
portfolio_daily_returns = pd.Series(0, index=list(data_dict.values())[0].index)
total_investment = sum(investment_amounts[sym] for sym in symbols if sym in investment_amounts and investment_amounts[sym] > 0)
for sym, df in data_dict.items():
    weight = investment_amounts[sym] / total_investment if total_investment > 0 else 0
    portfolio_daily_returns += df['Daily Return'] * weight

# Beta Hesaplaması: Her hisse için, portföy getirisine göre beta = cov(ha, portföy)/var(portföy)
beta_values = {}
for sym, df in data_dict.items():
    covariance = np.cov(df['Daily Return'].dropna(), portfolio_daily_returns.dropna())[0, 1]
    variance = np.var(portfolio_daily_returns.dropna())
    beta = covariance / variance if variance != 0 else np.nan
    beta_values[sym] = beta

beta_df = pd.DataFrame.from_dict(beta_values, orient='index', columns=["Beta"])
st.subheader("Beta Değerleri")
st.dataframe(beta_df)

# Monte Carlo Simülasyonu: Portföyün 1 yıl sonraki değeri için 1000 simülasyon
st.header("Monte Carlo Simülasyonu ile Gelecek Portföy Değeri Tahmini")
simulations = 1000
days = 365
last_portfolio_value = portfolio_value

# Portföy günlük getirilerinin ortalama ve standart sapması
portfolio_daily_mean = portfolio_daily_returns.mean()
portfolio_daily_std = portfolio_daily_returns.std()

simulation_results = []
for i in range(simulations):
    simulated_value = last_portfolio_value
    for d in range(days):
        simulated_return = np.random.normal(portfolio_daily_mean, portfolio_daily_std)
        simulated_value *= (1 + simulated_return)
    simulation_results.append(simulated_value)

fig_hist = px.histogram(simulation_results, nbins=50,
                        title="Monte Carlo Simülasyonu Sonuçları (1 Yıl Sonra Portföy Değeri Dağılımı)",
                        labels={"value": "Portföy Değeri", "count": "Frekans"})
st.plotly_chart(fig_hist)