Carsten Stahl commited on
Commit
b7cd1b1
1 Parent(s): 774135c

drastically reduced the complexity of main.py

Browse files
Files changed (1) hide show
  1. main.py +6 -260
main.py CHANGED
@@ -1,272 +1,18 @@
1
- import yfinance as yf
2
- import numpy as np
3
  import pandas as pd
4
 
5
- import streamlit as st
6
-
7
  from utilities.py.styling import streamlit_style
8
- from utilities.py import plots
9
- from utilities.py import summary_tables
10
- # from utilities.py import mongodb
11
-
12
- from pypfopt import EfficientFrontier
13
- from pypfopt import risk_models
14
- from pypfopt import expected_returns
15
- from pypfopt import HRPOpt, hierarchical_portfolio
16
 
17
- import plotly.express as px
18
- import plotly.graph_objects as go
19
 
20
  streamlit_style()
21
  # data import
22
  company_list_df = pd.read_csv("utilities/data/Company List.csv")
23
 
 
24
 
25
- # company selction -------------------------------------------------------------------
26
- company_name = company_list_df["Name"].to_list()
27
- company_symbol = (company_list_df["Ticker"] + ".NS").to_list()
28
-
29
- name_to_symbol_dict = dict()
30
- symbol_to_name_dict = dict()
31
-
32
- for CSymbol, CName in zip(company_symbol, company_name):
33
- name_to_symbol_dict[CName] = CSymbol
34
-
35
- for CSymbol, CName in zip(company_symbol, company_name):
36
- symbol_to_name_dict[CSymbol] = CName
37
-
38
- streamlit_company_list_input = st.multiselect(
39
- "Select Multiple Companies", company_name, default=None
40
- )
41
-
42
- # method selection ---------------------------------------------------------------------
43
-
44
- optimisation_method = st.selectbox(
45
- "Choose an optimization method accordingly",
46
- (
47
- "Efficient Frontier",
48
- "Hierarchical Risk Parity",
49
- ),
50
- )
51
-
52
- parameter_for_optimisation = 0
53
- if optimisation_method == "Efficient Frontier":
54
- parameter_for_optimisation = st.selectbox(
55
- "Choose an optimization parameter accordingly",
56
- (
57
- "Maximum Sharpe Ratio",
58
- "Efficient Risk",
59
- "Minimum Volatility",
60
- "Efficient Return",
61
- ),
62
- )
63
-
64
- # selection of starting date and amount to invest --------------------------------------
65
-
66
- company_name_to_symbol = [name_to_symbol_dict[i] for i in streamlit_company_list_input]
67
-
68
- number_of_symbols = len(company_name_to_symbol)
69
-
70
- start_date = st.date_input(
71
- "Start Date",
72
- format="YYYY-MM-DD",
73
- value=pd.Timestamp("1947-08-15"),
74
- max_value=pd.Timestamp.now(),
75
- )
76
-
77
- initial_investment = st.number_input("How much would you want to invest?", value=45000)
78
-
79
- # Optimization and summary of results
80
- if number_of_symbols > 1:
81
- company_data = pd.DataFrame()
82
-
83
- # get the stock data for the companies
84
- for cname in company_name_to_symbol:
85
- stock_data_temp = yf.download(
86
- cname, start=start_date, end=pd.Timestamp.now().strftime("%Y-%m-%d")
87
- )["Adj Close"]
88
- stock_data_temp.name = cname
89
- company_data = pd.merge(
90
- company_data,
91
- stock_data_temp,
92
- how="outer",
93
- right_index=True,
94
- left_index=True,
95
- )
96
-
97
- # cleaning the data
98
- company_data.dropna(axis=1, how="all", inplace=True)
99
-
100
- company_data.dropna(inplace=True)
101
-
102
- for i in company_data.columns:
103
- company_data[i] = company_data[i].abs()
104
-
105
- st.write(
106
- f"Note: Due to unavailability of full data, this Analysis uses data from the date: {company_data.index[0]}"
107
- )
108
-
109
- number_of_symbols = len(company_data.columns)
110
-
111
- # showing the stock data in the UI
112
- st.dataframe(company_data, use_container_width=True)
113
-
114
- # only continue with sim, if more than one company was fetched
115
- if number_of_symbols > 1:
116
- company_stock_returns_data = company_data.pct_change().dropna()
117
-
118
- # Config for the simulation
119
- mu = 0
120
- S = 0
121
- ef = 0
122
- company_asset_weights = 0
123
-
124
- # Do the portfolio optimization
125
- if optimisation_method == "Efficient Frontier":
126
- mu = expected_returns.mean_historical_return(company_data)
127
- S = risk_models.sample_cov(company_data)
128
-
129
- ef = EfficientFrontier(mu, S)
130
-
131
- if parameter_for_optimisation == "Maximum Sharpe Raio":
132
- ef.max_sharpe()
133
- elif parameter_for_optimisation == "Minimum Volatility":
134
- ef.min_volatility()
135
- elif parameter_for_optimisation == "Efficient Risk":
136
- ef.efficient_risk(0.5)
137
- else:
138
- ef.efficient_return(0.05)
139
-
140
- company_asset_weights = pd.DataFrame.from_dict(
141
- ef.clean_weights(), orient="index"
142
- ).reset_index()
143
- elif optimisation_method == "Hierarchical Risk Parity":
144
- mu = expected_returns.returns_from_prices(company_data)
145
- S = risk_models.sample_cov(company_data)
146
-
147
- ef = HRPOpt(mu, S)
148
-
149
- company_asset_weights = ef.optimize()
150
- company_asset_weights = pd.DataFrame.from_dict(
151
- company_asset_weights, orient="index", columns=["Weight"]
152
- ).reset_index()
153
-
154
- # cleaning the returned data from the optimization and outputing results
155
- company_asset_weights.columns = ["Ticker", "Allocation"]
156
-
157
- company_asset_weights["Name"] = [
158
- symbol_to_name_dict[i] for i in company_asset_weights["Ticker"]
159
- ]
160
-
161
- company_asset_weights = company_asset_weights[["Name", "Ticker", "Allocation"]]
162
-
163
- st.dataframe(company_asset_weights, use_container_width=True)
164
-
165
-
166
- # get portfolio performance and refactor the data
167
- (
168
- expected_annual_return,
169
- annual_volatility,
170
- sharpe_ratio,
171
- ) = ef.portfolio_performance()
172
-
173
- st_portfolio_performance = pd.DataFrame.from_dict(
174
- {
175
- "Expected annual return": (expected_annual_return * 100).round(2),
176
- "Annual volatility": (annual_volatility * 100).round(2),
177
- "Sharpe ratio": sharpe_ratio.round(2),
178
- },
179
- orient="index",
180
- ).reset_index()
181
-
182
- st_portfolio_performance.columns = ["Metrics", "Summary"]
183
-
184
- # output the method used above the results
185
- if optimisation_method == "Efficient Frontier":
186
- st.write(
187
- "Optimization Method - ",
188
- optimisation_method,
189
- "---- Parameter - ",
190
- parameter_for_optimisation,
191
- )
192
- else:
193
- st.write("Optimization Method - ", optimisation_method)
194
-
195
- st.dataframe(st_portfolio_performance, use_container_width=True)
196
-
197
- # plot the pie chart with the asset weights
198
- plots.pie_chart_company_asset_weights(company_asset_weights)
199
-
200
- # summarizing the asset returns with optimized portfolio
201
- portfolio_returns = (
202
- company_stock_returns_data * list(ef.clean_weights().values())
203
- ).sum(axis=1)
204
-
205
- annual_portfolio_returns = portfolio_returns.resample("Y").apply(
206
- lambda x: (x + 1).prod() - 1
207
- )
208
-
209
- cumulative_returns = (portfolio_returns + 1).cumprod() * initial_investment
210
-
211
- # Output the results in the tab
212
-
213
- tab1, tab2, tab3 = st.tabs(["Plots", "Annual Returns", "Montly Returns"])
214
-
215
- with tab1:
216
- plots.plot_annual_returns(annual_portfolio_returns)
217
- plots.plot_cummulative_returns(cumulative_returns)
218
-
219
- with tab2:
220
- annual_portfolio_returns = summary_tables.annual_returns_dataframe(
221
- annual_portfolio_returns
222
- )
223
- annual_cumulative_returns = (
224
- summary_tables.annual_cumulative_returns_dataframe(cumulative_returns)
225
- )
226
- annual_stock_returns = summary_tables.company_wise_annual_return(
227
- company_stock_returns_data, company_asset_weights
228
- )
229
-
230
- merged_annual_returns_data = pd.merge(
231
- annual_portfolio_returns,
232
- annual_cumulative_returns,
233
- on="Year",
234
- suffixes=("_portfolio", "_cumulative"),
235
- )
236
-
237
- merged_annual_returns_data = pd.merge(
238
- merged_annual_returns_data, annual_stock_returns, on="Year"
239
- )
240
-
241
- st.write("Annual Returns")
242
- st.dataframe(merged_annual_returns_data, use_container_width=True)
243
-
244
- with tab3:
245
- monthly_portfolio_return = summary_tables.monthly_returns_dataframe(
246
- portfolio_returns
247
- )
248
- monthly_stock_return = summary_tables.company_wise_monthly_return(
249
- company_stock_returns_data, company_asset_weights
250
- )
251
- monthly_cumulative_returns = (
252
- summary_tables.monthly_cumulative_returns_dataframe(cumulative_returns)
253
- )
254
-
255
- merged_monthly_returns_data = pd.merge(
256
- monthly_portfolio_return,
257
- monthly_cumulative_returns,
258
- on=["Year", "Month"],
259
- how="inner",
260
- )
261
-
262
- merged_monthly_returns_data = pd.merge(
263
- merged_monthly_returns_data,
264
- monthly_stock_return,
265
- on=["Year", "Month"],
266
- how="inner",
267
- )
268
 
269
- st.write("Montly Return")
270
- st.dataframe(merged_monthly_returns_data, use_container_width=True)
271
 
272
- # mongodb.mongodb_push_data(company_name_to_symbol, number_of_symbols)
 
 
 
 
1
  import pandas as pd
2
 
 
 
3
  from utilities.py.styling import streamlit_style
4
+ from utilities.py.composer import Composer
 
 
 
 
 
 
 
5
 
 
 
6
 
7
  streamlit_style()
8
  # data import
9
  company_list_df = pd.read_csv("utilities/data/Company List.csv")
10
 
11
+ composer = Composer(company_list_df)
12
 
13
+ composer.render_user_input()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ ready_to_render_results = len(composer.user_input.get_selected_comp_ids()) > 1
 
16
 
17
+ if ready_to_render_results:
18
+ composer.render_results()