Bhanu Prasanna commited on
Commit
4db4bdc
·
1 Parent(s): e41e3ea

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +157 -156
main.py CHANGED
@@ -72,201 +72,202 @@ if num_tick > 1:
72
  com_data.dropna(inplace=True)
73
  num_tick = len(com_data.columns)
74
 
75
- com_sel_name_temp = []
76
- for i in com_data.columns:
77
- com_sel_name_temp.append(company_symbol_dict[i])
 
78
 
79
- com_sel = com_data.columns.to_list()
80
- com_sel_name.sort()
81
 
82
- st.dataframe(com_data, use_container_width=True)
83
 
84
- ## Log-Return of Company Dataset
85
- log_return = np.log(1 + com_data.pct_change())
86
 
87
- ## Generate Random Weights
88
- rand_weig = np.array(np.random.random(num_tick))
89
 
90
- ## Rebalancing Random Weights
91
- rebal_weig = rand_weig / np.sum(rand_weig)
92
 
93
- ## Calculate the Expected Returns, Annualize it by * 247.0
94
- exp_ret = np.sum((log_return.mean() * rebal_weig) * 247)
95
 
96
- ## Calculate the Expected Volatility, Annualize it by * 247.0
97
- exp_vol = np.sqrt(np.dot(rebal_weig.T, np.dot(log_return.cov() * 247, rebal_weig)))
98
 
99
- ## Calculate the Sharpe Ratio.
100
- sharpe_ratio = exp_ret / exp_vol
101
 
102
- # Put the weights into a data frame to see them better.
103
- weights_df = pd.DataFrame(
104
- data={
105
- "company_name": com_sel_name_temp,
106
- "random_weights": rand_weig,
107
- "rebalance_weights": rebal_weig,
108
- }
109
- )
110
 
111
- st.divider()
112
 
113
- st.markdown(
114
- "<h5 style='text-align: center;'>Random Portfolio Weights</h5>",
115
- unsafe_allow_html=True,
116
- )
117
- st.dataframe(weights_df, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
118
 
119
- # Do the same with the other metrics.
120
- metrics_df = pd.DataFrame(
121
- data={
122
- "Expected Portfolio Returns": exp_ret,
123
- "Expected Portfolio Volatility": exp_vol,
124
- "Portfolio Sharpe Ratio": sharpe_ratio,
125
- },
126
- index=[0],
127
- )
128
 
129
- st.markdown(
130
- "<h5 style='text-align: center;'>Random Weights Metrics</h5>",
131
- unsafe_allow_html=True,
132
- )
133
- st.dataframe(metrics_df, use_container_width=True)
134
 
135
- st.divider()
136
 
137
- ## Let's get started with Monte Carlo Simulations
 
138
 
139
- ## How many times should we run Monte Carlo
140
- num_of_port = 8000
141
 
142
- ## Create an Array to store the weights as they are generated
143
- all_weights = np.zeros((num_of_port, num_tick))
144
 
145
- ## Create an Array to store the returns as they are generated
146
- ret_arr = np.zeros(num_of_port)
147
 
148
- ## Create an Array to store the volatilities as they are generated
149
- vol_arr = np.zeros(num_of_port)
150
 
151
- ## Create an Array to store the Sharpe Ratios as they are generated
152
- sharpe_arr = np.zeros(num_of_port)
153
 
154
- ## Let's start the Monte Carlo Simulation
 
 
 
155
 
156
- for ind in range(num_of_port):
157
- ## Let's first Calculate the Weights
158
- weig = np.array(np.random.random(num_tick))
159
- weig = weig / np.sum(weig)
160
 
161
- ## Append the Weights to Weigths array
162
- all_weights[ind, :] = weig
163
 
164
- ## Calculate and Append the Expected Log Returns to Returns Array
165
- ret_arr[ind] = np.sum((log_return.mean() * weig) * 247)
166
 
167
- ## Calculate and Append the Volatility to the Volatitlity Array
168
- vol_arr[ind] = np.sqrt(np.dot(weig.T, np.dot(log_return.cov() * 247, weig)))
169
 
170
- ## Calculate and Append the Sharpe Ratio to Sharpe Ratio Array
171
- sharpe_arr[ind] = ret_arr[ind] / vol_arr[ind]
172
 
173
- ## Let's create a Data Frame with Weights, Returns, Volatitlity, and the Sharpe Ratio
174
- sim_data = [ret_arr, vol_arr, sharpe_arr, all_weights]
175
 
176
- ## Create a Data Frame using above, then Transpose it
177
- sim_df = pd.DataFrame(data=sim_data).T
178
 
179
- ## Give the columns in Simulation Data Proper Names
180
- sim_df.columns = ["Returns", "Volatility", "Sharpe Ratio", "Portfolio Weights"]
181
 
182
- ## Make sure the Data Types are correct in the Data Frame
183
- sim_df = sim_df.infer_objects()
 
 
 
 
 
184
 
185
- # Print out the results.
186
- st.write("\n\n")
187
- st.markdown(
188
- "<h4 style='text-align: center;'>Simulation Results</h4>",
189
- unsafe_allow_html=True,
190
- )
191
- st.dataframe(sim_df.head(), use_container_width=True)
192
 
193
- # Return the Max Sharpe Ratio from the run.
194
- max_sharpe_ratio = sim_df.loc[sim_df["Sharpe Ratio"].idxmax()]
195
 
196
- # Return the Min Volatility from the run.
197
- min_volatility = sim_df.loc[sim_df["Volatility"].idxmin()]
 
 
 
 
198
 
199
- max_sharpe_weights_df = pd.DataFrame(
200
- data={
201
- "company_name": com_sel_name_temp,
202
- "random_weights": max_sharpe_ratio["Portfolio Weights"],
203
- }
204
- )
205
-
206
- st.markdown(
207
- "<h5 style='text-align: center;'>Portfolio with Max Sharpe Ratio</h5>",
208
- unsafe_allow_html=True,
209
- )
210
- st.dataframe(max_sharpe_ratio, use_container_width=True)
211
- st.dataframe(max_sharpe_weights_df, use_container_width=True)
212
-
213
- min_volatility_weights_df = pd.DataFrame(
214
- data={
215
- "company_name": com_sel_name_temp,
216
- "random_weights": min_volatility["Portfolio Weights"],
217
- }
218
- )
219
 
220
- st.markdown(
221
- "<h5 style='text-align: center;'>Portfolio with Min Volatility</h5>",
222
- unsafe_allow_html=True,
223
- )
224
- st.dataframe(min_volatility, use_container_width=True)
225
- st.dataframe(min_volatility_weights_df, use_container_width=True)
226
 
227
- st.divider()
228
 
229
- st.markdown("<h1 style='text-align: center;'>Plotting</h1>", unsafe_allow_html=True)
230
 
231
- fig = go.Figure(
232
- data=go.Scatter(
233
- x=sim_df["Volatility"],
234
- y=sim_df["Returns"],
235
- mode="markers",
236
- marker=dict(color=sim_df["Sharpe Ratio"], colorscale="RdYlBu", size=10),
 
237
  )
238
- )
239
-
240
- # Add color bar
241
- fig.update_layout(coloraxis_colorbar=dict(title="Sharpe Ratio"))
242
-
243
- # Add title and axis labels
244
- fig.update_layout(
245
- title="Portfolio Returns Vs. Risk",
246
- xaxis=dict(title="Standard Deviation / Volatility"),
247
- yaxis=dict(title="Returns"),
248
- )
249
-
250
- # Plot the Max Sharpe Ratio, using a `Red Star`.
251
- fig.add_trace(
252
- go.Scatter(
253
- x=[max_sharpe_ratio[1]],
254
- y=[max_sharpe_ratio[0]],
255
- mode="markers",
256
- marker=dict(color="red", symbol="star", size=20),
257
- name="Max Sharpe Ratio",
258
  )
259
- )
260
-
261
- # Plot the Min Volatility, using a `Blue Star`.
262
- fig.add_trace(
263
- go.Scatter(
264
- x=[min_volatility[1]],
265
- y=[min_volatility[0]],
266
- mode="markers",
267
- marker=dict(color="blue", symbol="star", size=20),
268
- name="Min Volatility",
269
  )
270
- )
271
 
272
- st.plotly_chart(fig, use_container_width=True)
 
72
  com_data.dropna(inplace=True)
73
  num_tick = len(com_data.columns)
74
 
75
+ if num_tick > 1:
76
+ com_sel_name_temp = []
77
+ for i in com_data.columns:
78
+ com_sel_name_temp.append(company_symbol_dict[i])
79
 
80
+ com_sel = com_data.columns.to_list()
81
+ com_sel_name.sort()
82
 
83
+ st.dataframe(com_data, use_container_width=True)
84
 
85
+ ## Log-Return of Company Dataset
86
+ log_return = np.log(1 + com_data.pct_change())
87
 
88
+ ## Generate Random Weights
89
+ rand_weig = np.array(np.random.random(num_tick))
90
 
91
+ ## Rebalancing Random Weights
92
+ rebal_weig = rand_weig / np.sum(rand_weig)
93
 
94
+ ## Calculate the Expected Returns, Annualize it by * 247.0
95
+ exp_ret = np.sum((log_return.mean() * rebal_weig) * 247)
96
 
97
+ ## Calculate the Expected Volatility, Annualize it by * 247.0
98
+ exp_vol = np.sqrt(np.dot(rebal_weig.T, np.dot(log_return.cov() * 247, rebal_weig)))
99
 
100
+ ## Calculate the Sharpe Ratio.
101
+ sharpe_ratio = exp_ret / exp_vol
102
 
103
+ # Put the weights into a data frame to see them better.
104
+ weights_df = pd.DataFrame(
105
+ data={
106
+ "company_name": com_sel_name_temp,
107
+ "random_weights": rand_weig,
108
+ "rebalance_weights": rebal_weig,
109
+ }
110
+ )
111
 
112
+ st.divider()
113
 
114
+ st.markdown(
115
+ "<h5 style='text-align: center;'>Random Portfolio Weights</h5>",
116
+ unsafe_allow_html=True,
117
+ )
118
+ st.dataframe(weights_df, use_container_width=True)
119
+
120
+ # Do the same with the other metrics.
121
+ metrics_df = pd.DataFrame(
122
+ data={
123
+ "Expected Portfolio Returns": exp_ret,
124
+ "Expected Portfolio Volatility": exp_vol,
125
+ "Portfolio Sharpe Ratio": sharpe_ratio,
126
+ },
127
+ index=[0],
128
+ )
129
 
130
+ st.markdown(
131
+ "<h5 style='text-align: center;'>Random Weights Metrics</h5>",
132
+ unsafe_allow_html=True,
133
+ )
134
+ st.dataframe(metrics_df, use_container_width=True)
 
 
 
 
135
 
136
+ st.divider()
 
 
 
 
137
 
138
+ ## Let's get started with Monte Carlo Simulations
139
 
140
+ ## How many times should we run Monte Carlo
141
+ num_of_port = 8000
142
 
143
+ ## Create an Array to store the weights as they are generated
144
+ all_weights = np.zeros((num_of_port, num_tick))
145
 
146
+ ## Create an Array to store the returns as they are generated
147
+ ret_arr = np.zeros(num_of_port)
148
 
149
+ ## Create an Array to store the volatilities as they are generated
150
+ vol_arr = np.zeros(num_of_port)
151
 
152
+ ## Create an Array to store the Sharpe Ratios as they are generated
153
+ sharpe_arr = np.zeros(num_of_port)
154
 
155
+ ## Let's start the Monte Carlo Simulation
 
156
 
157
+ for ind in range(num_of_port):
158
+ ## Let's first Calculate the Weights
159
+ weig = np.array(np.random.random(num_tick))
160
+ weig = weig / np.sum(weig)
161
 
162
+ ## Append the Weights to Weigths array
163
+ all_weights[ind, :] = weig
 
 
164
 
165
+ ## Calculate and Append the Expected Log Returns to Returns Array
166
+ ret_arr[ind] = np.sum((log_return.mean() * weig) * 247)
167
 
168
+ ## Calculate and Append the Volatility to the Volatitlity Array
169
+ vol_arr[ind] = np.sqrt(np.dot(weig.T, np.dot(log_return.cov() * 247, weig)))
170
 
171
+ ## Calculate and Append the Sharpe Ratio to Sharpe Ratio Array
172
+ sharpe_arr[ind] = ret_arr[ind] / vol_arr[ind]
173
 
174
+ ## Let's create a Data Frame with Weights, Returns, Volatitlity, and the Sharpe Ratio
175
+ sim_data = [ret_arr, vol_arr, sharpe_arr, all_weights]
176
 
177
+ ## Create a Data Frame using above, then Transpose it
178
+ sim_df = pd.DataFrame(data=sim_data).T
179
 
180
+ ## Give the columns in Simulation Data Proper Names
181
+ sim_df.columns = ["Returns", "Volatility", "Sharpe Ratio", "Portfolio Weights"]
182
 
183
+ ## Make sure the Data Types are correct in the Data Frame
184
+ sim_df = sim_df.infer_objects()
185
 
186
+ # Print out the results.
187
+ st.write("\n\n")
188
+ st.markdown(
189
+ "<h4 style='text-align: center;'>Simulation Results</h4>",
190
+ unsafe_allow_html=True,
191
+ )
192
+ st.dataframe(sim_df.head(), use_container_width=True)
193
 
194
+ # Return the Max Sharpe Ratio from the run.
195
+ max_sharpe_ratio = sim_df.loc[sim_df["Sharpe Ratio"].idxmax()]
 
 
 
 
 
196
 
197
+ # Return the Min Volatility from the run.
198
+ min_volatility = sim_df.loc[sim_df["Volatility"].idxmin()]
199
 
200
+ max_sharpe_weights_df = pd.DataFrame(
201
+ data={
202
+ "company_name": com_sel_name_temp,
203
+ "random_weights": max_sharpe_ratio["Portfolio Weights"],
204
+ }
205
+ )
206
 
207
+ st.markdown(
208
+ "<h5 style='text-align: center;'>Portfolio with Max Sharpe Ratio</h5>",
209
+ unsafe_allow_html=True,
210
+ )
211
+ st.dataframe(max_sharpe_ratio, use_container_width=True)
212
+ st.dataframe(max_sharpe_weights_df, use_container_width=True)
213
+
214
+ min_volatility_weights_df = pd.DataFrame(
215
+ data={
216
+ "company_name": com_sel_name_temp,
217
+ "random_weights": min_volatility["Portfolio Weights"],
218
+ }
219
+ )
 
 
 
 
 
 
 
220
 
221
+ st.markdown(
222
+ "<h5 style='text-align: center;'>Portfolio with Min Volatility</h5>",
223
+ unsafe_allow_html=True,
224
+ )
225
+ st.dataframe(min_volatility, use_container_width=True)
226
+ st.dataframe(min_volatility_weights_df, use_container_width=True)
227
 
228
+ st.divider()
229
 
230
+ st.markdown("<h1 style='text-align: center;'>Plotting</h1>", unsafe_allow_html=True)
231
 
232
+ fig = go.Figure(
233
+ data=go.Scatter(
234
+ x=sim_df["Volatility"],
235
+ y=sim_df["Returns"],
236
+ mode="markers",
237
+ marker=dict(color=sim_df["Sharpe Ratio"], colorscale="RdYlBu", size=10),
238
+ )
239
  )
240
+
241
+ # Add color bar
242
+ fig.update_layout(coloraxis_colorbar=dict(title="Sharpe Ratio"))
243
+
244
+ # Add title and axis labels
245
+ fig.update_layout(
246
+ title="Portfolio Returns Vs. Risk",
247
+ xaxis=dict(title="Standard Deviation / Volatility"),
248
+ yaxis=dict(title="Returns"),
249
+ )
250
+
251
+ # Plot the Max Sharpe Ratio, using a `Red Star`.
252
+ fig.add_trace(
253
+ go.Scatter(
254
+ x=[max_sharpe_ratio[1]],
255
+ y=[max_sharpe_ratio[0]],
256
+ mode="markers",
257
+ marker=dict(color="red", symbol="star", size=20),
258
+ name="Max Sharpe Ratio",
259
+ )
260
  )
261
+
262
+ # Plot the Min Volatility, using a `Blue Star`.
263
+ fig.add_trace(
264
+ go.Scatter(
265
+ x=[min_volatility[1]],
266
+ y=[min_volatility[0]],
267
+ mode="markers",
268
+ marker=dict(color="blue", symbol="star", size=20),
269
+ name="Min Volatility",
270
+ )
271
  )
 
272
 
273
+ st.plotly_chart(fig, use_container_width=True)