sankhyikii commited on
Commit
4637479
1 Parent(s): 7f81147

font update

Browse files
Files changed (2) hide show
  1. main.py +124 -93
  2. style/style.css +5 -0
main.py CHANGED
@@ -6,31 +6,66 @@ import plotly.graph_objects as go
6
 
7
  st.set_page_config(layout="wide")
8
 
9
- st.markdown("<h1 style='text-align: center;'><u>CapiPort</u></h1>", unsafe_allow_html=True)
10
- st.markdown("<h5 style='text-align: center; color: gray;'>Your Portfolio Optimisation Tool</h5>", unsafe_allow_html=True)
11
- st.divider()
12
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
 
15
  list_df = pd.read_csv("Data/Company List.csv")
16
 
17
  company_name = list_df["Name"].to_list()
18
- company_symbol = (list_df["Ticker"] + '.NS').to_list()
19
 
20
  company_dict = dict()
21
 
22
  for CSymbol, CName in zip(company_symbol, company_name):
23
  company_dict[CName] = CSymbol
24
 
25
- com_sel_name = st.multiselect('Select Multiple Companies', company_name, default = None)
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  com_sel = [company_dict[i] for i in com_sel_name]
27
 
28
  num_tick = len(com_sel)
29
 
30
  if num_tick > 1:
31
 
32
- com_data = yf.download(com_sel, start="1900-01-01", end="2024-03-08")['Adj Close']
33
- com_data.dropna(inplace = True)
34
 
35
  com_sel = com_data.columns.to_list()
36
  com_sel_name.sort()
@@ -50,40 +85,42 @@ if num_tick > 1:
50
  exp_ret = np.sum((log_return.mean() * rebal_weig) * 247)
51
 
52
  ## Calculate the Expected Volatility, Annualize it by * 247.0
53
- exp_vol = np.sqrt(
54
- np.dot(
55
- rebal_weig.T,
56
- np.dot(
57
- log_return.cov() * 247,
58
- rebal_weig
59
- )
60
- )
61
- )
62
 
63
  ## Calculate the Sharpe Ratio.
64
  sharpe_ratio = exp_ret / exp_vol
65
 
66
  # Put the weights into a data frame to see them better.
67
- weights_df = pd.DataFrame(data={
68
- 'company_name': com_sel_name,
69
- 'random_weights': rand_weig,
70
- 'rebalance_weights': rebal_weig
71
- })
 
 
72
 
73
  st.divider()
74
 
75
- st.markdown("<h5 style='text-align: center;'>Random Portfolio Weights</h5>", unsafe_allow_html=True)
 
 
 
76
  st.dataframe(weights_df, use_container_width=True)
77
 
78
-
79
  # Do the same with the other metrics.
80
- metrics_df = pd.DataFrame(data={
81
- 'Expected Portfolio Returns': exp_ret,
82
- 'Expected Portfolio Volatility': exp_vol,
83
- 'Portfolio Sharpe Ratio': sharpe_ratio
84
- }, index=[0])
 
 
 
85
 
86
- st.markdown("<h5 style='text-align: center;'>Random Weights Metrics</h5>", unsafe_allow_html=True)
 
 
 
87
  st.dataframe(metrics_df, use_container_width=True)
88
 
89
  st.divider()
@@ -119,9 +156,7 @@ if num_tick > 1:
119
  ret_arr[ind] = np.sum((log_return.mean() * weig) * 247)
120
 
121
  ## Calculate and Append the Volatility to the Volatitlity Array
122
- vol_arr[ind] = np.sqrt(
123
- np.dot(weig.T, np.dot(log_return.cov() * 247, weig))
124
- )
125
 
126
  ## Calculate and Append the Sharpe Ratio to Sharpe Ratio Array
127
  sharpe_arr[ind] = ret_arr[ind] / vol_arr[ind]
@@ -133,42 +168,50 @@ if num_tick > 1:
133
  sim_df = pd.DataFrame(data=sim_data).T
134
 
135
  ## Give the columns in Simulation Data Proper Names
136
- sim_df.columns = [
137
- 'Returns',
138
- 'Volatility',
139
- 'Sharpe Ratio',
140
- 'Portfolio Weights'
141
- ]
142
 
143
  ## Make sure the Data Types are correct in the Data Frame
144
  sim_df = sim_df.infer_objects()
145
 
146
  # Print out the results.
147
  st.write("\n\n")
148
- st.markdown("<h4 style='text-align: center;'>Simulation Results</h4>", unsafe_allow_html=True)
 
 
 
149
  st.dataframe(sim_df.head(), use_container_width=True)
150
 
151
  # Return the Max Sharpe Ratio from the run.
152
- max_sharpe_ratio = sim_df.loc[sim_df['Sharpe Ratio'].idxmax()]
153
 
154
  # Return the Min Volatility from the run.
155
- min_volatility = sim_df.loc[sim_df['Volatility'].idxmin()]
156
 
157
- max_sharpe_weights_df = pd.DataFrame(data={
158
- 'company_name': com_sel_name,
159
- 'random_weights': max_sharpe_ratio["Portfolio Weights"],
160
- })
 
 
161
 
162
- st.markdown("<h5 style='text-align: center;'>Portfolio with Max Sharpe Ratio</h5>", unsafe_allow_html=True)
 
 
 
163
  st.dataframe(max_sharpe_ratio, use_container_width=True)
164
  st.dataframe(max_sharpe_weights_df, use_container_width=True)
165
 
166
- min_volatility_weights_df = pd.DataFrame(data={
167
- 'company_name': com_sel_name,
168
- 'random_weights': min_volatility["Portfolio Weights"],
169
- })
 
 
170
 
171
- st.markdown("<h5 style='text-align: center;'>Portfolio with Min Volatility</h5>", unsafe_allow_html=True)
 
 
 
172
  st.dataframe(min_volatility, use_container_width=True)
173
  st.dataframe(min_volatility_weights_df, use_container_width=True)
174
 
@@ -176,57 +219,45 @@ if num_tick > 1:
176
 
177
  st.markdown("<h1 style='text-align: center;'>Plotting</h1>", unsafe_allow_html=True)
178
 
179
- fig = go.Figure(data=go.Scatter(
180
- x=sim_df['Volatility'],
181
- y=sim_df['Returns'],
182
- mode='markers',
183
- marker=dict(
184
- color=sim_df['Sharpe Ratio'],
185
- colorscale='RdYlBu',
186
- size=10
187
  )
188
- ))
189
 
190
  # Add color bar
191
- fig.update_layout(
192
- coloraxis_colorbar=dict(
193
- title='Sharpe Ratio'
194
- )
195
- )
196
 
197
  # Add title and axis labels
198
  fig.update_layout(
199
- title='Portfolio Returns Vs. Risk',
200
- xaxis=dict(title='Standard Deviation / Volatility'),
201
- yaxis=dict(title='Returns')
202
  )
203
 
204
  # Plot the Max Sharpe Ratio, using a `Red Star`.
205
- fig.add_trace(go.Scatter(
206
- x=[max_sharpe_ratio[1]],
207
- y=[max_sharpe_ratio[0]],
208
- mode='markers',
209
- marker=dict(
210
- color='red',
211
- symbol='star',
212
- size=20
213
- ),
214
- name='Max Sharpe Ratio'
215
- ))
216
 
217
  # Plot the Min Volatility, using a `Blue Star`.
218
- fig.add_trace(go.Scatter(
219
- x=[min_volatility[1]],
220
- y=[min_volatility[0]],
221
- mode='markers',
222
- marker=dict(
223
- color='blue',
224
- symbol='star',
225
- size=20
226
- ),
227
- name='Min Volatility'
228
- ))
229
 
230
  st.plotly_chart(fig, use_container_width=True)
231
-
232
-
 
6
 
7
  st.set_page_config(layout="wide")
8
 
9
+ with open(r"style/style.css") as css:
10
+ st.markdown(f"<style>{css.read()}</style>", unsafe_allow_html=True)
11
+
12
+ st.markdown(
13
+ "<h1 style='text-align: center;'><u>CapiPort</u></h1>", unsafe_allow_html=True
14
+ )
15
+
16
+ st.markdown(
17
+ "<h5 style='text-align: center; color: gray;'>Your Portfolio Optimisation Tool</h5>",
18
+ unsafe_allow_html=True,
19
+ )
20
+ st.header(
21
+ "",
22
+ divider="rainbow",
23
+ )
24
+
25
+ color = "Quest"
26
+ st.markdown(
27
+ "<h1 style='text-align: center;'>🔍 Quest for financial excellence begins with meticulous portfolio optimization</u></h1>",
28
+ unsafe_allow_html=True,
29
+ )
30
+
31
+ st.header(
32
+ "",
33
+ divider="rainbow",
34
+ )
35
 
36
 
37
  list_df = pd.read_csv("Data/Company List.csv")
38
 
39
  company_name = list_df["Name"].to_list()
40
+ company_symbol = (list_df["Ticker"] + ".NS").to_list()
41
 
42
  company_dict = dict()
43
 
44
  for CSymbol, CName in zip(company_symbol, company_name):
45
  company_dict[CName] = CSymbol
46
 
47
+ st.markdown(
48
+ """
49
+ <style>
50
+ .big-font {
51
+ font-size:20px;
52
+ }
53
+ </style>""",
54
+ unsafe_allow_html=True,
55
+ )
56
+
57
+ st.markdown('<p class="big-font">Select Multiple Companies</p>', unsafe_allow_html=True)
58
+
59
+ com_sel_name = st.multiselect("", company_name, default=None)
60
+
61
  com_sel = [company_dict[i] for i in com_sel_name]
62
 
63
  num_tick = len(com_sel)
64
 
65
  if num_tick > 1:
66
 
67
+ com_data = yf.download(com_sel, start="1900-01-01", end="2024-03-08")["Adj Close"]
68
+ com_data.dropna(inplace=True)
69
 
70
  com_sel = com_data.columns.to_list()
71
  com_sel_name.sort()
 
85
  exp_ret = np.sum((log_return.mean() * rebal_weig) * 247)
86
 
87
  ## Calculate the Expected Volatility, Annualize it by * 247.0
88
+ exp_vol = np.sqrt(np.dot(rebal_weig.T, np.dot(log_return.cov() * 247, rebal_weig)))
 
 
 
 
 
 
 
 
89
 
90
  ## Calculate the Sharpe Ratio.
91
  sharpe_ratio = exp_ret / exp_vol
92
 
93
  # Put the weights into a data frame to see them better.
94
+ weights_df = pd.DataFrame(
95
+ data={
96
+ "company_name": com_sel_name,
97
+ "random_weights": rand_weig,
98
+ "rebalance_weights": rebal_weig,
99
+ }
100
+ )
101
 
102
  st.divider()
103
 
104
+ st.markdown(
105
+ "<h5 style='text-align: center;'>Random Portfolio Weights</h5>",
106
+ unsafe_allow_html=True,
107
+ )
108
  st.dataframe(weights_df, use_container_width=True)
109
 
 
110
  # Do the same with the other metrics.
111
+ metrics_df = pd.DataFrame(
112
+ data={
113
+ "Expected Portfolio Returns": exp_ret,
114
+ "Expected Portfolio Volatility": exp_vol,
115
+ "Portfolio Sharpe Ratio": sharpe_ratio,
116
+ },
117
+ index=[0],
118
+ )
119
 
120
+ st.markdown(
121
+ "<h5 style='text-align: center;'>Random Weights Metrics</h5>",
122
+ unsafe_allow_html=True,
123
+ )
124
  st.dataframe(metrics_df, use_container_width=True)
125
 
126
  st.divider()
 
156
  ret_arr[ind] = np.sum((log_return.mean() * weig) * 247)
157
 
158
  ## Calculate and Append the Volatility to the Volatitlity Array
159
+ vol_arr[ind] = np.sqrt(np.dot(weig.T, np.dot(log_return.cov() * 247, weig)))
 
 
160
 
161
  ## Calculate and Append the Sharpe Ratio to Sharpe Ratio Array
162
  sharpe_arr[ind] = ret_arr[ind] / vol_arr[ind]
 
168
  sim_df = pd.DataFrame(data=sim_data).T
169
 
170
  ## Give the columns in Simulation Data Proper Names
171
+ sim_df.columns = ["Returns", "Volatility", "Sharpe Ratio", "Portfolio Weights"]
 
 
 
 
 
172
 
173
  ## Make sure the Data Types are correct in the Data Frame
174
  sim_df = sim_df.infer_objects()
175
 
176
  # Print out the results.
177
  st.write("\n\n")
178
+ st.markdown(
179
+ "<h4 style='text-align: center;'>Simulation Results</h4>",
180
+ unsafe_allow_html=True,
181
+ )
182
  st.dataframe(sim_df.head(), use_container_width=True)
183
 
184
  # Return the Max Sharpe Ratio from the run.
185
+ max_sharpe_ratio = sim_df.loc[sim_df["Sharpe Ratio"].idxmax()]
186
 
187
  # Return the Min Volatility from the run.
188
+ min_volatility = sim_df.loc[sim_df["Volatility"].idxmin()]
189
 
190
+ max_sharpe_weights_df = pd.DataFrame(
191
+ data={
192
+ "company_name": com_sel_name,
193
+ "random_weights": max_sharpe_ratio["Portfolio Weights"],
194
+ }
195
+ )
196
 
197
+ st.markdown(
198
+ "<h5 style='text-align: center;'>Portfolio with Max Sharpe Ratio</h5>",
199
+ unsafe_allow_html=True,
200
+ )
201
  st.dataframe(max_sharpe_ratio, use_container_width=True)
202
  st.dataframe(max_sharpe_weights_df, use_container_width=True)
203
 
204
+ min_volatility_weights_df = pd.DataFrame(
205
+ data={
206
+ "company_name": com_sel_name,
207
+ "random_weights": min_volatility["Portfolio Weights"],
208
+ }
209
+ )
210
 
211
+ st.markdown(
212
+ "<h5 style='text-align: center;'>Portfolio with Min Volatility</h5>",
213
+ unsafe_allow_html=True,
214
+ )
215
  st.dataframe(min_volatility, use_container_width=True)
216
  st.dataframe(min_volatility_weights_df, use_container_width=True)
217
 
 
219
 
220
  st.markdown("<h1 style='text-align: center;'>Plotting</h1>", unsafe_allow_html=True)
221
 
222
+ fig = go.Figure(
223
+ data=go.Scatter(
224
+ x=sim_df["Volatility"],
225
+ y=sim_df["Returns"],
226
+ mode="markers",
227
+ marker=dict(color=sim_df["Sharpe Ratio"], colorscale="RdYlBu", size=10),
 
 
228
  )
229
+ )
230
 
231
  # Add color bar
232
+ fig.update_layout(coloraxis_colorbar=dict(title="Sharpe Ratio"))
 
 
 
 
233
 
234
  # Add title and axis labels
235
  fig.update_layout(
236
+ title="Portfolio Returns Vs. Risk",
237
+ xaxis=dict(title="Standard Deviation / Volatility"),
238
+ yaxis=dict(title="Returns"),
239
  )
240
 
241
  # Plot the Max Sharpe Ratio, using a `Red Star`.
242
+ fig.add_trace(
243
+ go.Scatter(
244
+ x=[max_sharpe_ratio[1]],
245
+ y=[max_sharpe_ratio[0]],
246
+ mode="markers",
247
+ marker=dict(color="red", symbol="star", size=20),
248
+ name="Max Sharpe Ratio",
249
+ )
250
+ )
 
 
251
 
252
  # Plot the Min Volatility, using a `Blue Star`.
253
+ fig.add_trace(
254
+ go.Scatter(
255
+ x=[min_volatility[1]],
256
+ y=[min_volatility[0]],
257
+ mode="markers",
258
+ marker=dict(color="blue", symbol="star", size=20),
259
+ name="Min Volatility",
260
+ )
261
+ )
 
 
262
 
263
  st.plotly_chart(fig, use_container_width=True)
 
 
style/style.css ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ @import url('https://fonts.googleapis.com/css2?family=League+Spartan:wght@100..900&display=swap');
2
+
3
+ body * {
4
+ font-family: "League Spartan";
5
+ }