FlavioRubensOttaviani's picture
Update app.py
2eae80b verified
import gradio as gr
import yfinance as yf
import pandas as pd
import numpy as np
import plotly.express as px
class ottimizzazioneLagrange:
def __init__(self, tickers_string, period):
# Pulizia stringa input
self.tickers = [t.strip().upper() for t in tickers_string.split(',')]
self.period = period
self.dati_prezzi = None
self.matrice_covarianza = None
self.pesi_ottimali = None
def run_optimization(self):
# 1. Download dati (senza progress bar per evitare log sporchi)
dati = yf.download(self.tickers, period=self.period, progress=False)
if dati.empty:
return "Error: No data found / Errore: Dati non trovati.", None
if isinstance(dati.columns, pd.MultiIndex):
self.dati_prezzi = dati['Close']
else:
self.dati_prezzi = pd.DataFrame(dati['Close'])
self.dati_prezzi.columns = self.tickers
# 2. Calcolo Rendimenti e Matrice Covarianza
rendimenti = self.dati_prezzi.pct_change().dropna()
self.matrice_covarianza = rendimenti.cov() * 252
# 3. Ottimizzazione Lagrange (Minima Varianza)
n_asset = len(self.tickers)
vettore1 = np.ones(n_asset)
cov_inversa = np.linalg.inv(self.matrice_covarianza.values)
num = cov_inversa @ vettore1
den = vettore1.T @ num
self.pesi_ottimali = num / den
# 4. Risultati Testuali
res = "GLOBAL MINIMUM VARIANCE PORTFOLIO\n" + "-"*35 + "\n"
for i, ticker in enumerate(self.tickers):
res += f"Asset: {ticker} | Weight: {self.pesi_ottimali[i]*100:.2f}%\n"
# 5. Creazione Grafico Plotly
df_plot = pd.DataFrame({
'Asset': self.tickers,
'Weight': self.pesi_ottimali * 100
})
fig = px.pie(df_plot, values='Weight', names='Asset',
title="Portfolio Allocation (Markowitz Optimization)",
hole=0.3)
return res, fig
def inference(tickers, period):
try:
model = ottimizzazioneLagrange(tickers, period)
return model.run_optimization()
except Exception as e:
return f"System Error: {str(e)}", None
# UI Gradio
with gr.Blocks(theme=gr.themes.Default()) as demo:
gr.Markdown("# 📈 Portfolio Optimization via Lagrange Multipliers")
gr.Markdown("### Author: Dr. Ottaviani Flavio Rubens")
with gr.Row():
with gr.Column():
in_tickers = gr.Textbox(label="Tickers (comma separated / separati da virgola)", value="AAPL, MSFT, GOOGL")
in_period = gr.Dropdown(label="Analysis Period / Periodo", choices=["1y", "2y", "5y", "max"], value="1y")
btn = gr.Button("Calculate / Calcola", variant="primary")
with gr.Column():
out_text = gr.Textbox(label="Results / Risultati", lines=8)
out_plot = gr.Plot(label="Allocation Chart / Grafico Allocazione")
btn.click(inference, inputs=[in_tickers, in_period], outputs=[out_text, out_plot])
if __name__ == "__main__":
demo.launch()