Bhanu Prasanna commited on
Commit
8c08ea9
1 Parent(s): 7db6bc2
main.py CHANGED
@@ -11,6 +11,7 @@ from utilities.py import summary_tables
11
  from pypfopt import EfficientFrontier
12
  from pypfopt import risk_models
13
  from pypfopt import expected_returns
 
14
 
15
  import plotly.express as px
16
  import plotly.graph_objects as go
@@ -35,16 +36,26 @@ streamlit_company_list_input = st.multiselect(
35
  "Select Multiple Companies", company_name, default=None
36
  )
37
 
38
- optimization_methods = st.selectbox(
39
- "Select an Optimsation Technique",
40
  (
41
- "Maximum Sharpe Ratio",
42
- "Efficient Risk",
43
- "Minimum Volatility",
44
- "Efficient Return",
45
  ),
46
  )
47
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  company_name_to_symbol = [name_to_symbol_dict[i] for i in streamlit_company_list_input]
49
 
50
  number_of_symbols = len(company_name_to_symbol)
@@ -90,23 +101,39 @@ if number_of_symbols > 1:
90
  if number_of_symbols > 1:
91
  company_stock_returns_data = company_data.pct_change().dropna()
92
 
93
- mu = expected_returns.mean_historical_return(company_data)
94
- S = risk_models.sample_cov(company_data)
 
 
95
 
96
- ef = EfficientFrontier(mu, S)
 
 
97
 
98
- if optimization_methods == "Maximum Sharpe Raio":
99
- ef.max_sharpe()
100
- elif optimization_methods == "Minimum Volatility":
101
- ef.min_volatility()
102
- elif optimization_methods == "Efficient Risk":
103
- ef.efficient_risk(0.5)
104
- else:
105
- ef.efficient_return(0.05)
106
 
107
- company_asset_weights = pd.DataFrame.from_dict(
108
- ef.clean_weights(), orient="index"
109
- ).reset_index()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
  company_asset_weights.columns = ["Ticker", "Allocation"]
112
 
@@ -139,7 +166,15 @@ if number_of_symbols > 1:
139
 
140
  st_portfolio_performance.columns = ["Metrics", "Summary"]
141
 
142
- st.write("Optimization Method - ", optimization_methods)
 
 
 
 
 
 
 
 
143
 
144
  st.dataframe(st_portfolio_performance, use_container_width=True)
145
 
@@ -155,12 +190,64 @@ if number_of_symbols > 1:
155
 
156
  cumulative_returns = (portfolio_returns + 1).cumprod() * initial_investment
157
 
158
- tab1, tab2 = st.tabs(["Plots", "Tables"])
159
 
160
  with tab1:
 
161
  plots.plot_annual_returns(annual_portfolio_returns)
162
  plots.plot_cummulative_returns(cumulative_returns)
163
 
164
  with tab2:
165
- summary_tables.annual_returns_dataframe(annual_portfolio_returns)
166
- summary_tables.cumulative_returns_dataframe(cumulative_returns)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  from pypfopt import EfficientFrontier
12
  from pypfopt import risk_models
13
  from pypfopt import expected_returns
14
+ from pypfopt import HRPOpt, hierarchical_portfolio
15
 
16
  import plotly.express as px
17
  import plotly.graph_objects as go
 
36
  "Select Multiple Companies", company_name, default=None
37
  )
38
 
39
+ optimisation_method = st.selectbox(
40
+ "Choose an optimization method accordingly",
41
  (
42
+ "Efficient Frontier",
43
+ "Hierarchical Risk Parity",
 
 
44
  ),
45
  )
46
 
47
+ parameter_for_optimisation = 0
48
+ if optimisation_method == "Efficient Frontier":
49
+ parameter_for_optimisation = st.selectbox(
50
+ "Choose an optimization parameter accordingly",
51
+ (
52
+ "Maximum Sharpe Ratio",
53
+ "Efficient Risk",
54
+ "Minimum Volatility",
55
+ "Efficient Return",
56
+ ),
57
+ )
58
+
59
  company_name_to_symbol = [name_to_symbol_dict[i] for i in streamlit_company_list_input]
60
 
61
  number_of_symbols = len(company_name_to_symbol)
 
101
  if number_of_symbols > 1:
102
  company_stock_returns_data = company_data.pct_change().dropna()
103
 
104
+ mu = 0
105
+ S = 0
106
+ ef = 0
107
+ company_asset_weights = 0
108
 
109
+ if optimisation_method == "Efficient Frontier":
110
+ mu = expected_returns.mean_historical_return(company_data)
111
+ S = risk_models.sample_cov(company_data)
112
 
113
+ ef = EfficientFrontier(mu, S)
 
 
 
 
 
 
 
114
 
115
+ if parameter_for_optimisation == "Maximum Sharpe Raio":
116
+ ef.max_sharpe()
117
+ elif parameter_for_optimisation == "Minimum Volatility":
118
+ ef.min_volatility()
119
+ elif parameter_for_optimisation == "Efficient Risk":
120
+ ef.efficient_risk(0.5)
121
+ else:
122
+ ef.efficient_return(0.05)
123
+
124
+ company_asset_weights = pd.DataFrame.from_dict(
125
+ ef.clean_weights(), orient="index"
126
+ ).reset_index()
127
+ elif optimisation_method == "Hierarchical Risk Parity":
128
+ mu = expected_returns.returns_from_prices(company_data)
129
+ S = risk_models.sample_cov(company_data)
130
+
131
+ ef = HRPOpt(mu, S)
132
+
133
+ company_asset_weights = ef.optimize()
134
+ company_asset_weights = pd.DataFrame.from_dict(
135
+ company_asset_weights, orient="index", columns=["Weight"]
136
+ ).reset_index()
137
 
138
  company_asset_weights.columns = ["Ticker", "Allocation"]
139
 
 
166
 
167
  st_portfolio_performance.columns = ["Metrics", "Summary"]
168
 
169
+ if optimisation_method == "Efficient Frontier":
170
+ st.write(
171
+ "Optimization Method - ",
172
+ optimisation_method,
173
+ "---- Parameter - ",
174
+ parameter_for_optimisation,
175
+ )
176
+ else:
177
+ st.write("Optimization Method - ", optimisation_method)
178
 
179
  st.dataframe(st_portfolio_performance, use_container_width=True)
180
 
 
190
 
191
  cumulative_returns = (portfolio_returns + 1).cumprod() * initial_investment
192
 
193
+ tab1, tab2, tab3 = st.tabs(["Plots", "Annual Returns", "Montly Returns"])
194
 
195
  with tab1:
196
+
197
  plots.plot_annual_returns(annual_portfolio_returns)
198
  plots.plot_cummulative_returns(cumulative_returns)
199
 
200
  with tab2:
201
+
202
+ annual_portfolio_returns = summary_tables.annual_returns_dataframe(
203
+ annual_portfolio_returns
204
+ )
205
+ annual_cumulative_returns = (
206
+ summary_tables.annual_cumulative_returns_dataframe(cumulative_returns)
207
+ )
208
+ annual_stock_returns = summary_tables.company_wise_annual_return(
209
+ company_stock_returns_data, company_asset_weights
210
+ )
211
+
212
+ merged_annual_returns_data = pd.merge(
213
+ annual_portfolio_returns,
214
+ annual_cumulative_returns,
215
+ on="Year",
216
+ suffixes=("_portfolio", "_cumulative"),
217
+ )
218
+
219
+ merged_annual_returns_data = pd.merge(
220
+ merged_annual_returns_data, annual_stock_returns, on="Year"
221
+ )
222
+
223
+ st.write("Annual Returns")
224
+ st.dataframe(merged_annual_returns_data, use_container_width=True)
225
+
226
+ with tab3:
227
+
228
+ monthly_portfolio_return = summary_tables.monthly_returns_dataframe(
229
+ portfolio_returns
230
+ )
231
+ monthly_stock_return = summary_tables.company_wise_monthly_return(
232
+ company_stock_returns_data, company_asset_weights
233
+ )
234
+ monthly_cumulative_returns = (
235
+ summary_tables.monthly_cumulative_returns_dataframe(cumulative_returns)
236
+ )
237
+
238
+ merged_monthly_returns_data = pd.merge(
239
+ monthly_portfolio_return,
240
+ monthly_cumulative_returns,
241
+ on=["Year", "Month"],
242
+ how="inner",
243
+ )
244
+
245
+ merged_monthly_returns_data = pd.merge(
246
+ merged_monthly_returns_data,
247
+ monthly_stock_return,
248
+ on=["Year", "Month"],
249
+ how="inner",
250
+ )
251
+
252
+ st.write("Montly Return")
253
+ st.dataframe(merged_monthly_returns_data)
utilities/py/__pycache__/summary_tables.cpython-310.pyc CHANGED
Binary files a/utilities/py/__pycache__/summary_tables.cpython-310.pyc and b/utilities/py/__pycache__/summary_tables.cpython-310.pyc differ
 
utilities/py/sharpe.py DELETED
@@ -1 +0,0 @@
1
- import numpy as np
 
 
utilities/py/summary_tables.py CHANGED
@@ -13,10 +13,10 @@ def annual_returns_dataframe(annual_portfolio_returns):
13
 
14
  annual_portfolio_returns["Year"] = annual_portfolio_returns.Year.dt.year.astype(str)
15
 
16
- st.dataframe(annual_portfolio_returns, use_container_width=True)
17
 
18
 
19
- def cumulative_returns_dataframe(cumulative_returns):
20
 
21
  cumulative_returns = cumulative_returns.to_frame().reset_index()
22
 
@@ -28,4 +28,115 @@ def cumulative_returns_dataframe(cumulative_returns):
28
  cumulative_returns.groupby("Year").tail(1).reset_index().drop("index", axis=1)
29
  )
30
 
31
- st.dataframe(cumulative_returns, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  annual_portfolio_returns["Year"] = annual_portfolio_returns.Year.dt.year.astype(str)
15
 
16
+ return annual_portfolio_returns
17
 
18
 
19
+ def annual_cumulative_returns_dataframe(cumulative_returns):
20
 
21
  cumulative_returns = cumulative_returns.to_frame().reset_index()
22
 
 
28
  cumulative_returns.groupby("Year").tail(1).reset_index().drop("index", axis=1)
29
  )
30
 
31
+ return cumulative_returns
32
+
33
+
34
+ def company_wise_annual_return(company_stock_returns_data, company_asset_weights):
35
+ # Create an empty DataFrame to store annual returns for each stock
36
+ annual_stock_returns = pd.DataFrame(
37
+ index=company_stock_returns_data.index.year.unique(),
38
+ columns=company_asset_weights["Ticker"],
39
+ )
40
+
41
+ # Iterate over each year
42
+ for year in annual_stock_returns.index:
43
+ # Filter returns data for the current year
44
+ year_returns = company_stock_returns_data.loc[
45
+ company_stock_returns_data.index.year == year
46
+ ]
47
+ # Iterate over each stock
48
+ for ticker, weight in zip(
49
+ company_asset_weights["Ticker"], company_asset_weights["Allocation"]
50
+ ):
51
+ # Calculate the weighted sum of returns for the current stock in the current year
52
+ weighted_sum_returns = (year_returns[ticker] * weight).sum() * 100
53
+ # Store the weighted average return for the current stock in the current year
54
+ annual_stock_returns.loc[year, ticker] = weighted_sum_returns
55
+
56
+ # Display annual returns for each stock
57
+ annual_stock_returns.reset_index(inplace=True)
58
+ annual_stock_returns["Date"] = annual_stock_returns["Date"].astype(str)
59
+ annual_stock_returns.rename(columns={"Date": "Year"}, inplace=True)
60
+
61
+ return annual_stock_returns
62
+
63
+
64
+ def company_wise_monthly_return(company_stock_returns_data, company_asset_weights):
65
+ # Resample daily returns to monthly returns for each stock
66
+ monthly_stock_returns = company_stock_returns_data.resample("M").mean()
67
+
68
+ # Iterate over each stock
69
+ for ticker, weight in zip(
70
+ company_asset_weights["Ticker"], company_asset_weights["Allocation"]
71
+ ):
72
+ # Calculate the weighted monthly returns for the current stock
73
+ weighted_monthly_returns = monthly_stock_returns[ticker] * weight
74
+ # Fill missing values with 0
75
+ weighted_monthly_returns.fillna(0, inplace=True)
76
+ # Store the weighted monthly returns in the DataFrame
77
+ monthly_stock_returns[ticker] = weighted_monthly_returns
78
+
79
+ # Reset the index and add new columns for year and month
80
+ monthly_stock_returns.reset_index(inplace=True)
81
+ monthly_stock_returns["Year"] = monthly_stock_returns["Date"].dt.year.astype(str)
82
+ monthly_stock_returns["Month"] = monthly_stock_returns["Date"].dt.month.astype(str)
83
+
84
+ # Rearrange the columns
85
+ columns_order = ["Year", "Month"] + [
86
+ col for col in monthly_stock_returns.columns if col not in ["Year", "Month"]
87
+ ]
88
+ monthly_stock_returns = monthly_stock_returns[columns_order]
89
+
90
+ # Drop the original date index column
91
+ monthly_stock_returns.drop(columns=["Date"], inplace=True)
92
+
93
+ # Display monthly returns for each stock
94
+ # st.write("Monthly Returns for Individual Stocks:")
95
+ # st.dataframe(monthly_stock_returns, use_container_width=True)
96
+
97
+ return monthly_stock_returns
98
+
99
+
100
+ def monthly_returns_dataframe(portfolio_returns):
101
+ monthly_portfolio_returns = (
102
+ (portfolio_returns.resample("M").mean() * 100).to_frame().reset_index()
103
+ )
104
+
105
+ monthly_portfolio_returns.columns = ["Date", "Return"]
106
+
107
+ monthly_portfolio_returns["Year"] = monthly_portfolio_returns.Date.dt.year.astype(
108
+ str
109
+ )
110
+ monthly_portfolio_returns["Month"] = monthly_portfolio_returns.Date.dt.month.astype(
111
+ str
112
+ )
113
+
114
+ monthly_portfolio_returns.drop(columns=["Date"], inplace=True)
115
+
116
+ monthly_portfolio_returns = monthly_portfolio_returns[["Year", "Month", "Return"]]
117
+
118
+ return monthly_portfolio_returns
119
+
120
+
121
+ def monthly_cumulative_returns_dataframe(cumulative_returns):
122
+
123
+ monthly_cumulative_returns = (
124
+ cumulative_returns.resample("M").last().to_frame().reset_index()
125
+ )
126
+
127
+ monthly_cumulative_returns.columns = ["Date", "Balance"]
128
+
129
+ monthly_cumulative_returns["Year"] = monthly_cumulative_returns.Date.dt.year.astype(
130
+ str
131
+ )
132
+ monthly_cumulative_returns["Month"] = (
133
+ monthly_cumulative_returns.Date.dt.month.astype(str)
134
+ )
135
+
136
+ monthly_cumulative_returns.drop(columns=["Date"], inplace=True)
137
+
138
+ monthly_cumulative_returns = monthly_cumulative_returns[
139
+ ["Year", "Month", "Balance"]
140
+ ]
141
+
142
+ return monthly_cumulative_returns