Spaces:
Sleeping
Sleeping
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: Para su información los datos utilizados se extrajeron de GOOGLEFINANCE." | |
"STOCKS - Hoja 1.csv" | |
check_box = st.checkbox("¿Quieres usar el archivo que tenemos para ti?") | |
if check_box: | |
uploaded_file = "STOCKS - Hoja 1.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'], 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]) | |
# 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}]") |