Sofi1606's picture
Update app.py
af5cbb1 verified
raw
history blame contribute delete
No virus
5.06 kB
import streamlit as st
import pandas as pd
import numpy as np
import optuna
import plotly.express as px
import requests
import io
st.title("Portfolio weights calculator")
help_string = "NOTA: Para su informaci贸n los datos utilizados se extrajeron de GOOGLEFINANCE."
api_url = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&apikey=QVQGE7YPO68S403J&datatype=csv"
symbols = ['AMZN', 'MELI', 'ETSY']
option = st.selectbox("Selecciona la fuente de datos:", ("API Alpha Vantage", "Subir archivo propio", "Usar archivo predeterminado"))
if option == "API Alpha Vantage":
for symbol in symbols:
st.subheader(symbol)
response = requests.get(f"{api_url}&symbol={symbol}")
if response.status_code == 200:
data = pd.read_csv(io.BytesIO(response.content))
st.write(f"Datos de la acci贸n {symbol}:")
st.write(data.head())
else:
st.write(f"Error al obtener los datos de la acci贸n {symbol}. C贸digo de estado:", response.status_code)
elif option == "Subir archivo propio":
uploaded_file = st.file_uploader("Sube aqu铆 tu archivo de excel", type=[".xls", ".xlsx", ".csv"], help=help_string)
if uploaded_file is not None:
# Cargar y procesar el archivo subido
if file_name[-3:] == "csv":
df = pd.read_csv(uploaded_file)
else:
df = pd.read_excel(uploaded_file)
# Resto del procesamiento del archivo ...
elif option == "Usar archivo predeterminado":
uploaded_file = "STOCKS - Hoja 1.csv" # Opcional: proporciona la ruta al archivo predeterminado
# Cargar y procesar el archivo predeterminado
# Resto del procesamiento del archivo ...
if uploaded_file is not None:
if file_name[-3:] == "csv":
df = pd.read_csv(uploaded_file)
else:
df = pd.read_excel(uploaded_file)
df = df.drop(0, axis=0)
df = df.drop("Unnamed: 2", axis=1).drop("Unnamed: 4", axis=1).rename({"Unnamed: 0": "Date"}, axis=1)
df['Date'] = pd.to_datetime(df['Date'], format="%d/%m/%Y %H:%M:%S")
stocks = list(df.columns)[-3:]
stocks_rets = []
for i in stocks:
stocks_rets.append(i+"_ret")
df[i] = df[i].astype(float)
df[i+"_ret"] = (df[i] - df[i].shift(1)) / df[i].shift(1)
st.write(df[["Date"] + stocks_rets])
fig = px.line(df, x=df.Date, y=stocks, labels={'value': 'Value', 'variable': 'Series'}, title='Time Series Plot')
fig.update_layout(xaxis_title='Date', yaxis_title='Value')
st.plotly_chart(fig)
ret_list = df[stocks_rets].mean().to_numpy().reshape(-1, 1)
cov_matrix = df[stocks_rets].cov().to_numpy()
optim_choice = st.selectbox("Elige la forma de optomizar :", ("max returns", "min variance", "max returns - variance"))
def portfolio_variance(weights, covariance_matrix):
return np.dot(weights.T, np.dot(covariance_matrix, weights))
def portfolio_returns(weights, expected_returns):
return np.dot(weights.T, expected_returns)
if optim_choice == "max returns":
def objective(trial):
w1 = trial.suggest_uniform('w1', 0, 1)
w2 = trial.suggest_uniform('w2', 0, 1)
w3 = 1 - w1 - w2
weights = np.array([w1, w2, w3]).reshape(-1, 1)
return np.dot(weights.T, ret_list)
study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=100, show_progress_bar=True)
elif optim_choice == "min variance":
def objective(trial):
w1 = trial.suggest_uniform('w1', 0, 1)
w2 = trial.suggest_uniform('w2', 0, 1)
w3 = 1 - w1 - w2
weights = np.array([w1, w2, w3]).reshape(-1, 1)
return np.dot(weights.T, np.dot(cov_matrix, weights))
study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials=100, show_progress_bar=True)
else:
def objective(trial):
w1 = trial.suggest_uniform('w1', 0, 1)
w2 = trial.suggest_uniform('w2', 0, 1)
w3 = 1 - w1 - w2
weights = np.array([w1, w2, w3]).reshape(-1, 1)
return np.dot(weights.T, ret_list) - np.dot(weights.T, np.dot(cov_matrix, weights))
study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=100, show_progress_bar=True)
w1 = study.best_params['w1']
w2 = study.best_params['w2']
w3 = 1- w1 - w2
weights = np.array([w1, w2, w3]).reshape(-1, 1)
yearly_returns = (1 + np.dot(weights.T, ret_list)[0, 0]) ** 252 - 1
yearly_variance = np.dot(weights.T, np.dot(cov_matrix, weights))[0, 0] * 252
st.write(f"Los pesos son: :green[{stocks[0]} -> {w1:,.4f}], :green[{stocks[1]} -> {w2:,.4f}], :green[{stocks[2]} -> {w3:,.4f}]")
st.write(f"El retorno anualizado del portafolio es: :green[{yearly_returns:,.4f}]")
st.write(f"La varianza anualizado del portafolio es: :green[{yearly_variance:,.4f}]")