portafolio / app.py
Skkinycalvs's picture
Update app.py
9135a63 verified
raw
history blame contribute delete
No virus
4.09 kB
import streamlit as st
import pandas as pd
import numpy as np
import optuna
import plotly.express as px
st.title("Portfolio weights calculator")
help_string = "NOTA: El formato utilizado aquí es llamando cada columna de GOOGLEFINANCE."
"Stocks - Tickets.csv"
check_box = st.checkbox("¿Deseas usar el archivo precargado?")
if check_box:
uploaded_file = "Stocks - Tickets.csv"
file_name = uploaded_file
else:
uploaded_file = st.file_uploader("Sube aquí tu archivo de excel", type=[".xls", ".xlsx", ".csv"], help=help_string)
file_name = uploaded_file.name if uploaded_file is not None else None
if uploaded_file is not None:
# Can be used wherever a "file-like" object is accepted:
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']).dt.date
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])
# Plotting with Plotly
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')
# Use Streamlit to render the plot
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}]")