bia12 commited on
Commit
4bf6580
1 Parent(s): 9d0fa17

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +98 -68
app.py CHANGED
@@ -1,76 +1,106 @@
1
  import streamlit as st
2
- import numpy as np
3
  import pandas as pd
4
- import matplotlib.pyplot as plt
5
- import random
6
-
7
- # Streamlit app layout
8
- st.title("Estimating statistics from two lists of historical values")
9
-
10
- with st.form("my_form"):
11
- N = st.number_input("How many elements do you want for each list?", step=1)
12
-
13
- # Button to generate the numbers
14
- if st.form_submit_button("Click to generate random numbers' lists"):
15
- # Generate two lists of 100 random numbers each
16
- x = [random.randint(0, 20) for _ in range(N)]
17
- y = [random.randint(0, 20) for _ in range(N)]
18
-
19
- # Display the lists in the app
20
- # st.write('List 1:', x)
21
- # st.write('List 2:', y)
22
-
23
- if "x" in globals():
24
- x_bar = np.mean(x)
25
- y_bar = np.mean(y)
26
-
27
- st.subheader("Expected values")
28
- st.write(f"E(x) = {x_bar:,.2f}")
29
- st.write(f"E(y) = {y_bar:,.2f}")
30
-
31
- var_x = np.var(x)
32
- var_y = np.var(y)
33
-
34
- st.subheader("Variances")
35
- st.write(f"var(x) = {var_x:,.2f}")
36
- st.write(f"var(y) = {var_y:,.2f}")
37
-
38
- cov_xy = np.corrcoef(x, y)[0, 1]
39
-
40
- st.subheader("Correlation")
41
- st.write(f"corr(x, y) = {cov_xy:,.2f}")
42
-
43
- plt.scatter(x, y)
44
- plt.title("Correlations")
45
- plt.xlabel("x")
46
- plt.ylabel("y")
47
-
48
- st.pyplot(plt)
49
-
50
- plt.close()
51
-
52
- plt.title("Plot of returns")
53
- plt.plot(np.arange(len(x)), x)
54
- plt.plot(np.arange(len(y)), y)
55
- plt.ylim(-10, 40)
56
- plt.xlabel('"time"')
57
- plt.ylabel('"returns"')
58
 
59
- st.pyplot(plt)
60
 
61
- w_x = (x_bar - y_bar + var_y - cov_xy * np.sqrt(var_x * var_y)) / (
62
- var_x + var_y - 2 * cov_xy * np.sqrt(var_x * var_y)
63
- )
64
- w_y = 1 - w_x
65
 
66
- var_r = (w_x**2)*var_x + (w_y**2)*var_y + 2*w_x*w_y*cov_xy*np.sqrt(var_x * var_y)
67
 
68
- st.subheader(f"Weights and portfolio returns (this is Plus, but you will need to explain how you obtained the answers)")
69
- st.write("Assuming x and y represent returns of portfolios")
70
- st.write(f"w_x = {w_x:,.2f}")
71
- st.write(f"w_y = {w_y:,.2f}")
72
- st.write(f"E(r) = {w_x*x_bar + w_y*y_bar:,.2f}")
73
- st.write(f"var(r) = {var_r:,.2f}")
74
 
 
 
 
75
  else:
76
- st.write(":red[Please, give the number of elements in each list]")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
 
2
  import pandas as pd
3
+ import numpy as np
4
+ import optuna
5
+ import plotly.express as px
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
+ st.title("Portfolio weights calculator")
8
 
9
+ help_string = "NOTA: El formato utilizado aquí es llamando cada columna de GOOGLEFINANCE."
 
 
 
10
 
11
+ "Stocks - Sheet1.csv"
12
 
13
+ check_box = st.checkbox("¿Deseas usar el archivo precargado?")
 
 
 
 
 
14
 
15
+ if check_box:
16
+ uploaded_file = "Stocks - Sheet1.csv"
17
+ file_name = uploaded_file
18
  else:
19
+ uploaded_file = st.file_uploader("Sube aquí tu archivo de excel", type=[".xls", ".xlsx", ".csv"], help=help_string)
20
+ file_name = uploaded_file.name
21
+
22
+ if uploaded_file is not None:
23
+ # Can be used wherever a "file-like" object is accepted:
24
+ if file_name[-3:] == "csv":
25
+ df = pd.read_csv(uploaded_file)
26
+ else:
27
+ df = pd.read_excel(uploaded_file)
28
+
29
+ df = df.drop(0, axis=0)
30
+ df = df.drop("Unnamed: 2", axis=1).drop("Unnamed: 4", axis=1).rename({"Unnamed: 0": "Date"}, axis=1)
31
+
32
+ df['Date'] = pd.to_datetime(df['Date']).dt.date
33
+
34
+ stocks = list(df.columns)[-3:]
35
+ stocks_rets = []
36
+
37
+ for i in stocks:
38
+ stocks_rets.append(i+"_ret")
39
+ df[i] = df[i].astype(float)
40
+ df[i+"_ret"] = (df[i] - df[i].shift(1)) / df[i].shift(1)
41
+
42
+ st.write(df[["Date"] + stocks_rets])
43
+
44
+ # Plotting with Plotly
45
+ fig = px.line(df, x=df.Date, y=stocks, labels={'value': 'Value', 'variable': 'Series'}, title='Time Series Plot')
46
+ fig.update_layout(xaxis_title='Date', yaxis_title='Value')
47
+
48
+ # Use Streamlit to render the plot
49
+ st.plotly_chart(fig)
50
+
51
+ ret_list = df[stocks_rets].mean().to_numpy().reshape(-1, 1)
52
+ cov_matrix = df[stocks_rets].cov().to_numpy()
53
+
54
+ optim_choice = st.selectbox("Elige la forma de optomizar :", ("max returns", "min variance", "max returns - variance"))
55
+
56
+ def portfolio_variance(weights, covariance_matrix):
57
+ return np.dot(weights.T, np.dot(covariance_matrix, weights))
58
+
59
+ def portfolio_returns(weights, expected_returns):
60
+ return np.dot(weights.T, expected_returns)
61
+
62
+ if optim_choice == "max returns":
63
+ def objective(trial):
64
+ w1 = trial.suggest_uniform('w1', 0, 1)
65
+ w2 = trial.suggest_uniform('w2', 0, 1)
66
+ w3 = 1 - w1 - w2
67
+ weights = np.array([w1, w2, w3]).reshape(-1, 1)
68
+ return np.dot(weights.T, ret_list)
69
+
70
+ study = optuna.create_study(direction="maximize")
71
+ study.optimize(objective, n_trials=100, show_progress_bar=True)
72
+
73
+ elif optim_choice == "min variance":
74
+ def objective(trial):
75
+ w1 = trial.suggest_uniform('w1', 0, 1)
76
+ w2 = trial.suggest_uniform('w2', 0, 1)
77
+ w3 = 1 - w1 - w2
78
+ weights = np.array([w1, w2, w3]).reshape(-1, 1)
79
+ return np.dot(weights.T, np.dot(cov_matrix, weights))
80
+
81
+ study = optuna.create_study(direction="minimize")
82
+ study.optimize(objective, n_trials=100, show_progress_bar=True)
83
+
84
+ else:
85
+ def objective(trial):
86
+ w1 = trial.suggest_uniform('w1', 0, 1)
87
+ w2 = trial.suggest_uniform('w2', 0, 1)
88
+ w3 = 1 - w1 - w2
89
+ weights = np.array([w1, w2, w3]).reshape(-1, 1)
90
+ return np.dot(weights.T, ret_list) - np.dot(weights.T, np.dot(cov_matrix, weights))
91
+
92
+ study = optuna.create_study(direction="maximize")
93
+ study.optimize(objective, n_trials=100, show_progress_bar=True)
94
+
95
+ w1 = study.best_params['w1']
96
+ w2 = study.best_params['w2']
97
+ w3 = 1- w1 - w2
98
+
99
+ weights = np.array([w1, w2, w3]).reshape(-1, 1)
100
+
101
+ yearly_returns = (1 + np.dot(weights.T, ret_list)[0, 0]) ** 252 - 1
102
+ yearly_variance = np.dot(weights.T, np.dot(cov_matrix, weights))[0, 0] * 252
103
+
104
+ st.write(f"Los pesos son: :green[{stocks[0]} -> {w1:,.4f}], :green[{stocks[1]} -> {w2:,.4f}], :green[{stocks[2]} -> {w3:,.4f}]")
105
+ st.write(f"El retorno anualizado del portafolio es: :green[{yearly_returns:,.4f}]")
106
+ st.write(f"La varianza anualizado del portafolio es: :green[{yearly_variance:,.4f}]")