sankhyikii commited on
Commit
d6536da
1 Parent(s): 4e1670a

moving averages and pct returns

Browse files
Files changed (3) hide show
  1. Notebooks/MAexp.py +181 -0
  2. Notebooks/movingaveragesexp.ipynb +607 -0
  3. main.py +34 -5
Notebooks/MAexp.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ import yfinance as yf
4
+ import streamlit as st
5
+ import plotly.graph_objects as go
6
+ import time
7
+ import datetime
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
+ list_df = pd.read_csv("../Data/Company List.csv")
37
+
38
+ company_name = list_df["Name"].to_list()
39
+ company_symbol = (list_df["Ticker"] + ".NS").to_list()
40
+
41
+ company_dict = dict()
42
+ company_symbol_dict = dict()
43
+
44
+ for CSymbol, CName in zip(company_symbol, company_name):
45
+ company_dict[CName] = CSymbol
46
+
47
+ for CSymbol, CName in zip(company_symbol, company_name):
48
+ company_symbol_dict[CSymbol] = CName
49
+
50
+ st.markdown(
51
+ """
52
+ <style>
53
+ .big-font {
54
+ font-size:20px;
55
+ }
56
+ </style>""",
57
+ unsafe_allow_html=True,
58
+ )
59
+
60
+ st.markdown('<p class="big-font">Select Multiple Companies</p>', unsafe_allow_html=True)
61
+
62
+ com_sel_name = st.multiselect("", company_name, default=None)
63
+ com_sel_date = []
64
+
65
+ for i in com_sel_name:
66
+ d = st.date_input(
67
+ f"On which date did you invested in - {i}",
68
+ value= pd.Timestamp('2021-01-01'),
69
+ format="YYYY-MM-DD",
70
+ )
71
+ d = d - datetime.timedelta(days=3)
72
+ com_sel_date.append(d)
73
+
74
+ com_sel = [company_dict[i] for i in com_sel_name]
75
+
76
+ num_tick = len(com_sel)
77
+
78
+ if num_tick > 1:
79
+ com_data = pd.DataFrame()
80
+ for cname, cdate in zip(com_sel, com_sel_date):
81
+ stock_data_temp = yf.download(cname, start=cdate, end=pd.Timestamp.now().strftime('%Y-%m-%d'))['Low']
82
+ stock_data_temp.name = cname
83
+ com_data = pd.merge(com_data, stock_data_temp, how="outer", right_index=True, left_index=True)
84
+ for i in com_data.columns:
85
+ com_data.dropna(axis=1, how='all', inplace=True)
86
+ # com_data.dropna(inplace=True)
87
+ num_tick = len(com_data.columns)
88
+
89
+ # Dataframe of the selected companies
90
+ st.dataframe(com_data, use_container_width=True)
91
+
92
+ # make a function to calculate moving averages from the dataframe com_data, store those moving averages in dictionary for respective company
93
+ def moving_average(data, window):
94
+ ma = {}
95
+ for i in data.columns:
96
+ ma[i] = data[i].rolling(window=window).mean().values[2]
97
+ return ma
98
+
99
+ moving_avg = moving_average(com_data, 3)
100
+ MA_df = pd.DataFrame(moving_avg.items(), columns=['Company', 'Purchase Rate (MA)'])
101
+
102
+ # calculate percentage return till present date from the moving average price of the stock
103
+ def percentage_return(data, moving_avg):
104
+ pr = {}
105
+ for i in data.columns:
106
+ pr[i] = f'{round(((data[i].values[-1] - moving_avg[i]) / moving_avg[i]) * 100,2) }%'
107
+ return pr
108
+
109
+ # make percentage return a dataframe from dictionary
110
+ percentage_return = pd.DataFrame(percentage_return(com_data, moving_avg).items(), columns=['Company', 'Percentage Return'])
111
+
112
+ #merge MA_df and percentage_return on "Company" columns
113
+ MA_df = pd.merge(MA_df, percentage_return, on='Company')
114
+
115
+ st.markdown(
116
+ "<h5 style='text-align: center;'>Percent Returns & MA price</h5>",
117
+ unsafe_allow_html=True,
118
+ )
119
+
120
+ st.write("<p style='text-align: center;'>**rate of purchase is moving average(MA) of 3 (t+2) days</p>", unsafe_allow_html=True)
121
+ st.dataframe(MA_df,use_container_width=True)
122
+
123
+ if num_tick > 1:
124
+ com_sel_name_temp = []
125
+ for i in com_data.columns:
126
+ com_sel_name_temp.append(company_symbol_dict[i])
127
+ com_sel = com_data.columns.to_list()
128
+
129
+
130
+ ## Log-Return of Company Dataset
131
+ log_return = np.log(1 + com_data.pct_change())
132
+
133
+ ## Generate Random Weights
134
+ rand_weig = np.array(np.random.random(num_tick))
135
+
136
+ ## Rebalancing Random Weights
137
+ rebal_weig = rand_weig / np.sum(rand_weig)
138
+
139
+ ## Calculate the Expected Returns, Annualize it by * 252.0
140
+ exp_ret = np.sum((log_return.mean() * rebal_weig) * 252)
141
+
142
+ ## Calculate the Expected Volatility, Annualize it by * 252.0
143
+ exp_vol = np.sqrt(np.dot(rebal_weig.T, np.dot(log_return.cov() * 252, rebal_weig)))
144
+
145
+ ## Calculate the Sharpe Ratio.
146
+ sharpe_ratio = exp_ret / exp_vol
147
+
148
+ # Put the weights into a data frame to see them better.
149
+ weights_df = pd.DataFrame(
150
+ data={
151
+ "company_name": com_sel_name_temp,
152
+ "random_weights": rand_weig,
153
+ "rebalance_weights": rebal_weig,
154
+ }
155
+ )
156
+
157
+ st.divider()
158
+
159
+ st.markdown(
160
+ "<h5 style='text-align: center;'>Random Portfolio Weights</h5>",
161
+ unsafe_allow_html=True,
162
+ )
163
+ st.dataframe(weights_df, use_container_width=True)
164
+
165
+ # Do the same with the other metrics.
166
+ metrics_df = pd.DataFrame(
167
+ data={
168
+ "Expected Portfolio Returns": exp_ret,
169
+ "Expected Portfolio Volatility": exp_vol,
170
+ "Portfolio Sharpe Ratio": sharpe_ratio,
171
+ },
172
+ index=[0],
173
+ )
174
+
175
+ st.markdown(
176
+ "<h5 style='text-align: center;'>Random Weights Metrics</h5>",
177
+ unsafe_allow_html=True,
178
+ )
179
+ st.dataframe(metrics_df, use_container_width=True)
180
+
181
+ st.divider()
Notebooks/movingaveragesexp.ipynb ADDED
@@ -0,0 +1,607 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "11ae7d38-5af8-4b51-91d4-a3fcde0eb00b",
6
+ "metadata": {},
7
+ "source": [
8
+ "# Trial 1"
9
+ ]
10
+ },
11
+ {
12
+ "cell_type": "code",
13
+ "execution_count": 3,
14
+ "id": "9e628f09-b78e-4737-8b97-227901cf61c7",
15
+ "metadata": {},
16
+ "outputs": [
17
+ {
18
+ "name": "stderr",
19
+ "output_type": "stream",
20
+ "text": [
21
+ "2024-03-11 19:43:50.457 `label` got an empty value. This is discouraged for accessibility reasons and may be disallowed in the future by raising an exception. Please provide a non-empty label and hide it with label_visibility if needed.\n"
22
+ ]
23
+ }
24
+ ],
25
+ "source": [
26
+ "import pandas as pd\n",
27
+ "import numpy as np\n",
28
+ "import yfinance as yf\n",
29
+ "import streamlit as st\n",
30
+ "import plotly.graph_objects as go\n",
31
+ "import time\n",
32
+ "import datetime\n",
33
+ "\n",
34
+ "with open(r\"../style/style.css\") as css:\n",
35
+ " st.markdown(f\"<style>{css.read()}</style>\", unsafe_allow_html=True)\n",
36
+ "\n",
37
+ "st.markdown(\n",
38
+ " \"<h1 style='text-align: center;'><u>CapiPort</u></h1>\", unsafe_allow_html=True\n",
39
+ ")\n",
40
+ "\n",
41
+ "st.markdown(\n",
42
+ " \"<h5 style='text-align: center; color: gray;'>Your Portfolio Optimisation Tool</h5>\",\n",
43
+ " unsafe_allow_html=True,\n",
44
+ ")\n",
45
+ "st.header(\n",
46
+ " \"\",\n",
47
+ " divider=\"rainbow\",\n",
48
+ ")\n",
49
+ "\n",
50
+ "color = \"Quest\"\n",
51
+ "st.markdown(\n",
52
+ " \"<h1 style='text-align: center;'>🔍 Quest for financial excellence begins with meticulous portfolio optimization</u></h1>\",\n",
53
+ " unsafe_allow_html=True,\n",
54
+ ")\n",
55
+ "\n",
56
+ "st.header(\n",
57
+ " \"\",\n",
58
+ " divider=\"rainbow\",\n",
59
+ ")\n",
60
+ "\n",
61
+ "list_df = pd.read_csv(\"../Data/Company List.csv\")\n",
62
+ "\n",
63
+ "company_name = list_df[\"Name\"].to_list()\n",
64
+ "company_symbol = (list_df[\"Ticker\"] + \".NS\").to_list()\n",
65
+ "\n",
66
+ "company_dict = dict()\n",
67
+ "company_symbol_dict = dict()\n",
68
+ "\n",
69
+ "for CSymbol, CName in zip(company_symbol, company_name):\n",
70
+ " company_dict[CName] = CSymbol\n",
71
+ "\n",
72
+ "for CSymbol, CName in zip(company_symbol, company_name):\n",
73
+ " company_symbol_dict[CSymbol] = CName\n",
74
+ "\n",
75
+ "st.markdown(\n",
76
+ " \"\"\" \n",
77
+ " <style>\n",
78
+ " .big-font {\n",
79
+ " font-size:20px;\n",
80
+ " }\n",
81
+ " </style>\"\"\",\n",
82
+ " unsafe_allow_html=True,\n",
83
+ ")\n",
84
+ "\n",
85
+ "st.markdown('<p class=\"big-font\">Select Multiple Companies</p>', unsafe_allow_html=True)\n",
86
+ "\n",
87
+ "com_sel_name = st.multiselect(\"\", company_name, default=None)\n",
88
+ "com_sel_date = []\n",
89
+ "\n",
90
+ "for i in com_sel_name:\n",
91
+ " d = st.date_input(\n",
92
+ " f\"On which date did you invested in - {i}\",\n",
93
+ " value= pd.Timestamp('2021-01-01'),\n",
94
+ " format=\"YYYY-MM-DD\",\n",
95
+ " )\n",
96
+ " d = d - datetime.timedelta(days=3)\n",
97
+ " com_sel_date.append(d)\n",
98
+ "\n",
99
+ "com_sel = [company_dict[i] for i in com_sel_name]\n",
100
+ "\n",
101
+ "num_tick = len(com_sel)\n",
102
+ "\n",
103
+ "if num_tick > 1:\n",
104
+ " com_data = pd.DataFrame()\n",
105
+ " for cname, cdate in zip(com_sel, com_sel_date):\n",
106
+ " stock_data_temp = yf.download(cname, start=cdate, end=pd.Timestamp.now().strftime('%Y-%m-%d'))['Low']\n",
107
+ " stock_data_temp.name = cname\n",
108
+ " com_data = pd.merge(com_data, stock_data_temp, how=\"outer\", right_index=True, left_index=True)\n",
109
+ " for i in com_data.columns:\n",
110
+ " com_data.dropna(axis=1, how='all', inplace=True)\n",
111
+ " # com_data.dropna(inplace=True)\n",
112
+ " num_tick = len(com_data.columns)\n",
113
+ "\n",
114
+ " # make a function to calculate moving averages from the dataframe com_data, store those moving averages in dictionary for respective company\n",
115
+ " def moving_average(data, window):\n",
116
+ " ma = {}\n",
117
+ " for i in data.columns:\n",
118
+ " ma[i] = data[i].rolling(window=window).mean().values[2]\n",
119
+ " return ma\n",
120
+ "\n",
121
+ " st.write('your average rate of purchase for stock with a moving average of 3 days is:') \n",
122
+ " moving_avg = moving_average(com_data, 3)\n",
123
+ " st.write(moving_avg)\n",
124
+ "\n",
125
+ "\n",
126
+ "\n",
127
+ " if num_tick > 1:\n",
128
+ " com_sel_name_temp = []\n",
129
+ " for i in com_data.columns:\n",
130
+ " com_sel_name_temp.append(company_symbol_dict[i])\n",
131
+ " print(com_sel_name_temp)\n",
132
+ " print(com_data)\n",
133
+ " \n",
134
+ " com_sel = com_data.columns.to_list()\n",
135
+ " print(com_sel)\n",
136
+ " \n",
137
+ " st.dataframe(com_data, use_container_width=True)\n",
138
+ "\n",
139
+ " ## Log-Return of Company Dataset\n",
140
+ " log_return = np.log(1 + com_data.pct_change())\n",
141
+ "\n",
142
+ " ## Generate Random Weights\n",
143
+ " rand_weig = np.array(np.random.random(num_tick))\n",
144
+ "\n",
145
+ " ## Rebalancing Random Weights\n",
146
+ " rebal_weig = rand_weig / np.sum(rand_weig)\n",
147
+ "\n",
148
+ " ## Calculate the Expected Returns, Annualize it by * 252.0\n",
149
+ " exp_ret = np.sum((log_return.mean() * rebal_weig) * 252)\n",
150
+ "\n",
151
+ " ## Calculate the Expected Volatility, Annualize it by * 252.0\n",
152
+ " exp_vol = np.sqrt(np.dot(rebal_weig.T, np.dot(log_return.cov() * 252, rebal_weig)))\n",
153
+ "\n",
154
+ " ## Calculate the Sharpe Ratio.\n",
155
+ " sharpe_ratio = exp_ret / exp_vol\n",
156
+ "\n",
157
+ " # Put the weights into a data frame to see them better.\n",
158
+ " weights_df = pd.DataFrame(\n",
159
+ " data={\n",
160
+ " \"company_name\": com_sel_name_temp,\n",
161
+ " \"random_weights\": rand_weig,\n",
162
+ " \"rebalance_weights\": rebal_weig,\n",
163
+ " }\n",
164
+ " )\n",
165
+ "\n",
166
+ " st.divider()\n",
167
+ "\n",
168
+ " st.markdown(\n",
169
+ " \"<h5 style='text-align: center;'>Random Portfolio Weights</h5>\",\n",
170
+ " unsafe_allow_html=True,\n",
171
+ " )\n",
172
+ " st.dataframe(weights_df, use_container_width=True)\n",
173
+ "\n",
174
+ " # Do the same with the other metrics.\n",
175
+ " metrics_df = pd.DataFrame(\n",
176
+ " data={\n",
177
+ " \"Expected Portfolio Returns\": exp_ret,\n",
178
+ " \"Expected Portfolio Volatility\": exp_vol,\n",
179
+ " \"Portfolio Sharpe Ratio\": sharpe_ratio,\n",
180
+ " },\n",
181
+ " index=[0],\n",
182
+ " )\n",
183
+ "\n",
184
+ " st.markdown(\n",
185
+ " \"<h5 style='text-align: center;'>Random Weights Metrics</h5>\",\n",
186
+ " unsafe_allow_html=True,\n",
187
+ " )\n",
188
+ " st.dataframe(metrics_df, use_container_width=True)\n",
189
+ "\n",
190
+ " st.divider()\n"
191
+ ]
192
+ },
193
+ {
194
+ "cell_type": "markdown",
195
+ "id": "eed54a79-e2b6-4bba-b4fc-9c16f9c225d2",
196
+ "metadata": {},
197
+ "source": [
198
+ "# Trial 2"
199
+ ]
200
+ },
201
+ {
202
+ "cell_type": "code",
203
+ "execution_count": null,
204
+ "id": "8b936aa3-324e-4695-9059-a7d25efe2754",
205
+ "metadata": {},
206
+ "outputs": [],
207
+ "source": [
208
+ "import pandas as pd\n",
209
+ "import numpy as np\n",
210
+ "import yfinance as yf\n",
211
+ "import streamlit as st\n",
212
+ "import plotly.graph_objects as go\n",
213
+ "import time\n",
214
+ "import datetime\n",
215
+ "\n",
216
+ "with open(r\"../style/style.css\") as css:\n",
217
+ " st.markdown(f\"<style>{css.read()}</style>\", unsafe_allow_html=True)\n",
218
+ "\n",
219
+ "st.markdown(\n",
220
+ " \"<h1 style='text-align: center;'><u>CapiPort</u></h1>\", unsafe_allow_html=True\n",
221
+ ")\n",
222
+ "\n",
223
+ "st.markdown(\n",
224
+ " \"<h5 style='text-align: center; color: gray;'>Your Portfolio Optimisation Tool</h5>\",\n",
225
+ " unsafe_allow_html=True,\n",
226
+ ")\n",
227
+ "st.header(\n",
228
+ " \"\",\n",
229
+ " divider=\"rainbow\",\n",
230
+ ")\n",
231
+ "\n",
232
+ "color = \"Quest\"\n",
233
+ "st.markdown(\n",
234
+ " \"<h1 style='text-align: center;'>🔍 Quest for financial excellence begins with meticulous portfolio optimization</u></h1>\",\n",
235
+ " unsafe_allow_html=True,\n",
236
+ ")\n",
237
+ "\n",
238
+ "st.header(\n",
239
+ " \"\",\n",
240
+ " divider=\"rainbow\",\n",
241
+ ")\n",
242
+ "\n",
243
+ "list_df = pd.read_csv(\"../Data/Company List.csv\")\n",
244
+ "\n",
245
+ "company_name = list_df[\"Name\"].to_list()\n",
246
+ "company_symbol = (list_df[\"Ticker\"] + \".NS\").to_list()\n",
247
+ "\n",
248
+ "company_dict = dict()\n",
249
+ "company_symbol_dict = dict()\n",
250
+ "\n",
251
+ "for CSymbol, CName in zip(company_symbol, company_name):\n",
252
+ " company_dict[CName] = CSymbol\n",
253
+ "\n",
254
+ "for CSymbol, CName in zip(company_symbol, company_name):\n",
255
+ " company_symbol_dict[CSymbol] = CName\n",
256
+ "\n",
257
+ "st.markdown(\n",
258
+ " \"\"\" \n",
259
+ " <style>\n",
260
+ " .big-font {\n",
261
+ " font-size:20px;\n",
262
+ " }\n",
263
+ " </style>\"\"\",\n",
264
+ " unsafe_allow_html=True,\n",
265
+ ")\n",
266
+ "\n",
267
+ "st.markdown('<p class=\"big-font\">Select Multiple Companies</p>', unsafe_allow_html=True)\n",
268
+ "\n",
269
+ "com_sel_name = st.multiselect(\"\", company_name, default=None)\n",
270
+ "com_sel_date = []\n",
271
+ "\n",
272
+ "for i in com_sel_name:\n",
273
+ " d = st.date_input(\n",
274
+ " f\"On which date did you invested in - {i}\",\n",
275
+ " value= pd.Timestamp('2021-01-01'),\n",
276
+ " format=\"YYYY-MM-DD\",\n",
277
+ " )\n",
278
+ " d = d - datetime.timedelta(days=3)\n",
279
+ " com_sel_date.append(d)\n",
280
+ "\n",
281
+ "com_sel = [company_dict[i] for i in com_sel_name]\n",
282
+ "\n",
283
+ "num_tick = len(com_sel)\n",
284
+ "\n",
285
+ "if num_tick > 1:\n",
286
+ " com_data = pd.DataFrame()\n",
287
+ " for cname, cdate in zip(com_sel, com_sel_date):\n",
288
+ " stock_data_temp = yf.download(cname, start=cdate, end=pd.Timestamp.now().strftime('%Y-%m-%d'))['Low']\n",
289
+ " stock_data_temp.name = cname\n",
290
+ " com_data = pd.merge(com_data, stock_data_temp, how=\"outer\", right_index=True, left_index=True)\n",
291
+ " for i in com_data.columns:\n",
292
+ " com_data.dropna(axis=1, how='all', inplace=True)\n",
293
+ " # com_data.dropna(inplace=True)\n",
294
+ " num_tick = len(com_data.columns)\n",
295
+ "\n",
296
+ " # Dataframe of the selected companies\n",
297
+ " st.dataframe(com_data, use_container_width=True)\n",
298
+ "\n",
299
+ " # make a function to calculate moving averages from the dataframe com_data, store those moving averages in dictionary for respective company\n",
300
+ " def moving_average(data, window):\n",
301
+ " ma = {}\n",
302
+ " for i in data.columns:\n",
303
+ " ma[i] = data[i].rolling(window=window).mean().values[2]\n",
304
+ " return ma\n",
305
+ "\n",
306
+ " st.write('your average rate of purchase for stock with a moving average of 3 (t+2) days is:') \n",
307
+ " moving_avg = moving_average(com_data, 3)\n",
308
+ " st.write(moving_avg)\n",
309
+ "\n",
310
+ " # calculate percentage return till present date from the moving average price of the stock\n",
311
+ " def percentage_return(data, moving_avg):\n",
312
+ " pr = {}\n",
313
+ " for i in data.columns:\n",
314
+ " pr[i] = f'{round(((data[i].values[-1] - moving_avg[i]) / moving_avg[i]) * 100,2) }%'\n",
315
+ " return pr\n",
316
+ " \n",
317
+ " # make percentage return a dataframe from dictionary\n",
318
+ " percentage_return = pd.DataFrame(percentage_return(com_data, moving_avg).items(), columns=['Company', 'Percentage Return'])\n",
319
+ " st.write('your percentage return till present date from the moving average price of the stock is:')\n",
320
+ " st.write(percentage_return)\n",
321
+ "\n",
322
+ "\n",
323
+ "\n",
324
+ "\n",
325
+ "\n",
326
+ " if num_tick > 1:\n",
327
+ " com_sel_name_temp = []\n",
328
+ " for i in com_data.columns:\n",
329
+ " com_sel_name_temp.append(company_symbol_dict[i])\n",
330
+ " com_sel = com_data.columns.to_list()\n",
331
+ " \n",
332
+ "\n",
333
+ " ## Log-Return of Company Dataset\n",
334
+ " log_return = np.log(1 + com_data.pct_change())\n",
335
+ "\n",
336
+ " ## Generate Random Weights\n",
337
+ " rand_weig = np.array(np.random.random(num_tick))\n",
338
+ "\n",
339
+ " ## Rebalancing Random Weights\n",
340
+ " rebal_weig = rand_weig / np.sum(rand_weig)\n",
341
+ "\n",
342
+ " ## Calculate the Expected Returns, Annualize it by * 252.0\n",
343
+ " exp_ret = np.sum((log_return.mean() * rebal_weig) * 252)\n",
344
+ "\n",
345
+ " ## Calculate the Expected Volatility, Annualize it by * 252.0\n",
346
+ " exp_vol = np.sqrt(np.dot(rebal_weig.T, np.dot(log_return.cov() * 252, rebal_weig)))\n",
347
+ "\n",
348
+ " ## Calculate the Sharpe Ratio.\n",
349
+ " sharpe_ratio = exp_ret / exp_vol\n",
350
+ "\n",
351
+ " # Put the weights into a data frame to see them better.\n",
352
+ " weights_df = pd.DataFrame(\n",
353
+ " data={\n",
354
+ " \"company_name\": com_sel_name_temp,\n",
355
+ " \"random_weights\": rand_weig,\n",
356
+ " \"rebalance_weights\": rebal_weig,\n",
357
+ " }\n",
358
+ " )\n",
359
+ "\n",
360
+ " st.divider()\n",
361
+ "\n",
362
+ " st.markdown(\n",
363
+ " \"<h5 style='text-align: center;'>Random Portfolio Weights</h5>\",\n",
364
+ " unsafe_allow_html=True,\n",
365
+ " )\n",
366
+ " st.dataframe(weights_df, use_container_width=True)\n",
367
+ "\n",
368
+ " # Do the same with the other metrics.\n",
369
+ " metrics_df = pd.DataFrame(\n",
370
+ " data={\n",
371
+ " \"Expected Portfolio Returns\": exp_ret,\n",
372
+ " \"Expected Portfolio Volatility\": exp_vol,\n",
373
+ " \"Portfolio Sharpe Ratio\": sharpe_ratio,\n",
374
+ " },\n",
375
+ " index=[0],\n",
376
+ " )\n",
377
+ "\n",
378
+ " st.markdown(\n",
379
+ " \"<h5 style='text-align: center;'>Random Weights Metrics</h5>\",\n",
380
+ " unsafe_allow_html=True,\n",
381
+ " )\n",
382
+ " st.dataframe(metrics_df, use_container_width=True)\n",
383
+ "\n",
384
+ " st.divider()\n"
385
+ ]
386
+ },
387
+ {
388
+ "cell_type": "markdown",
389
+ "id": "1599354f-fd00-4312-be42-0ae156540f9b",
390
+ "metadata": {},
391
+ "source": [
392
+ "# Trial 3"
393
+ ]
394
+ },
395
+ {
396
+ "cell_type": "code",
397
+ "execution_count": null,
398
+ "id": "4777b2e7-da34-4a68-83cd-984850734708",
399
+ "metadata": {},
400
+ "outputs": [],
401
+ "source": [
402
+ "import pandas as pd\n",
403
+ "import numpy as np\n",
404
+ "import yfinance as yf\n",
405
+ "import streamlit as st\n",
406
+ "import plotly.graph_objects as go\n",
407
+ "import time\n",
408
+ "import datetime\n",
409
+ "\n",
410
+ "with open(r\"../style/style.css\") as css:\n",
411
+ " st.markdown(f\"<style>{css.read()}</style>\", unsafe_allow_html=True)\n",
412
+ "\n",
413
+ "st.markdown(\n",
414
+ " \"<h1 style='text-align: center;'><u>CapiPort</u></h1>\", unsafe_allow_html=True\n",
415
+ ")\n",
416
+ "\n",
417
+ "st.markdown(\n",
418
+ " \"<h5 style='text-align: center; color: gray;'>Your Portfolio Optimisation Tool</h5>\",\n",
419
+ " unsafe_allow_html=True,\n",
420
+ ")\n",
421
+ "st.header(\n",
422
+ " \"\",\n",
423
+ " divider=\"rainbow\",\n",
424
+ ")\n",
425
+ "\n",
426
+ "color = \"Quest\"\n",
427
+ "st.markdown(\n",
428
+ " \"<h1 style='text-align: center;'>🔍 Quest for financial excellence begins with meticulous portfolio optimization</u></h1>\",\n",
429
+ " unsafe_allow_html=True,\n",
430
+ ")\n",
431
+ "\n",
432
+ "st.header(\n",
433
+ " \"\",\n",
434
+ " divider=\"rainbow\",\n",
435
+ ")\n",
436
+ "\n",
437
+ "list_df = pd.read_csv(\"../Data/Company List.csv\")\n",
438
+ "\n",
439
+ "company_name = list_df[\"Name\"].to_list()\n",
440
+ "company_symbol = (list_df[\"Ticker\"] + \".NS\").to_list()\n",
441
+ "\n",
442
+ "company_dict = dict()\n",
443
+ "company_symbol_dict = dict()\n",
444
+ "\n",
445
+ "for CSymbol, CName in zip(company_symbol, company_name):\n",
446
+ " company_dict[CName] = CSymbol\n",
447
+ "\n",
448
+ "for CSymbol, CName in zip(company_symbol, company_name):\n",
449
+ " company_symbol_dict[CSymbol] = CName\n",
450
+ "\n",
451
+ "st.markdown(\n",
452
+ " \"\"\" \n",
453
+ " <style>\n",
454
+ " .big-font {\n",
455
+ " font-size:20px;\n",
456
+ " }\n",
457
+ " </style>\"\"\",\n",
458
+ " unsafe_allow_html=True,\n",
459
+ ")\n",
460
+ "\n",
461
+ "st.markdown('<p class=\"big-font\">Select Multiple Companies</p>', unsafe_allow_html=True)\n",
462
+ "\n",
463
+ "com_sel_name = st.multiselect(\"\", company_name, default=None)\n",
464
+ "com_sel_date = []\n",
465
+ "\n",
466
+ "for i in com_sel_name:\n",
467
+ " d = st.date_input(\n",
468
+ " f\"On which date did you invested in - {i}\",\n",
469
+ " value= pd.Timestamp('2021-01-01'),\n",
470
+ " format=\"YYYY-MM-DD\",\n",
471
+ " )\n",
472
+ " d = d - datetime.timedelta(days=3)\n",
473
+ " com_sel_date.append(d)\n",
474
+ "\n",
475
+ "com_sel = [company_dict[i] for i in com_sel_name]\n",
476
+ "\n",
477
+ "num_tick = len(com_sel)\n",
478
+ "\n",
479
+ "if num_tick > 1:\n",
480
+ " com_data = pd.DataFrame()\n",
481
+ " for cname, cdate in zip(com_sel, com_sel_date):\n",
482
+ " stock_data_temp = yf.download(cname, start=cdate, end=pd.Timestamp.now().strftime('%Y-%m-%d'))['Low']\n",
483
+ " stock_data_temp.name = cname\n",
484
+ " com_data = pd.merge(com_data, stock_data_temp, how=\"outer\", right_index=True, left_index=True)\n",
485
+ " for i in com_data.columns:\n",
486
+ " com_data.dropna(axis=1, how='all', inplace=True)\n",
487
+ " # com_data.dropna(inplace=True)\n",
488
+ " num_tick = len(com_data.columns)\n",
489
+ "\n",
490
+ " # Dataframe of the selected companies\n",
491
+ " st.dataframe(com_data, use_container_width=True)\n",
492
+ "\n",
493
+ " # make a function to calculate moving averages from the dataframe com_data, store those moving averages in dictionary for respective company\n",
494
+ " def moving_average(data, window):\n",
495
+ " ma = {}\n",
496
+ " for i in data.columns:\n",
497
+ " ma[i] = data[i].rolling(window=window).mean().values[2]\n",
498
+ " return ma\n",
499
+ "\n",
500
+ " moving_avg = moving_average(com_data, 3)\n",
501
+ " MA_df = pd.DataFrame(moving_avg.items(), columns=['Company', 'Purchase Rate (MA)'])\n",
502
+ "\n",
503
+ " # calculate percentage return till present date from the moving average price of the stock\n",
504
+ " def percentage_return(data, moving_avg):\n",
505
+ " pr = {}\n",
506
+ " for i in data.columns:\n",
507
+ " pr[i] = f'{round(((data[i].values[-1] - moving_avg[i]) / moving_avg[i]) * 100,2) }%'\n",
508
+ " return pr\n",
509
+ " \n",
510
+ " # make percentage return a dataframe from dictionary\n",
511
+ " percentage_return = pd.DataFrame(percentage_return(com_data, moving_avg).items(), columns=['Company', 'Percentage Return'])\n",
512
+ "\n",
513
+ " #merge MA_df and percentage_return on \"Company\" columns\n",
514
+ " MA_df = pd.merge(MA_df, percentage_return, on='Company')\n",
515
+ "\n",
516
+ " st.markdown(\n",
517
+ " \"<h5 style='text-align: center;'>Percent Returns & MA price</h5>\",\n",
518
+ " unsafe_allow_html=True,\n",
519
+ " )\n",
520
+ "\n",
521
+ " st.write(\"<p style='text-align: center;'>**rate of purchase is moving average(MA) of 3 (t+2) days</p>\", unsafe_allow_html=True) \n",
522
+ " st.write(MA_df)\n",
523
+ "\n",
524
+ " if num_tick > 1:\n",
525
+ " com_sel_name_temp = []\n",
526
+ " for i in com_data.columns:\n",
527
+ " com_sel_name_temp.append(company_symbol_dict[i])\n",
528
+ " com_sel = com_data.columns.to_list()\n",
529
+ " \n",
530
+ "\n",
531
+ " ## Log-Return of Company Dataset\n",
532
+ " log_return = np.log(1 + com_data.pct_change())\n",
533
+ "\n",
534
+ " ## Generate Random Weights\n",
535
+ " rand_weig = np.array(np.random.random(num_tick))\n",
536
+ "\n",
537
+ " ## Rebalancing Random Weights\n",
538
+ " rebal_weig = rand_weig / np.sum(rand_weig)\n",
539
+ "\n",
540
+ " ## Calculate the Expected Returns, Annualize it by * 252.0\n",
541
+ " exp_ret = np.sum((log_return.mean() * rebal_weig) * 252)\n",
542
+ "\n",
543
+ " ## Calculate the Expected Volatility, Annualize it by * 252.0\n",
544
+ " exp_vol = np.sqrt(np.dot(rebal_weig.T, np.dot(log_return.cov() * 252, rebal_weig)))\n",
545
+ "\n",
546
+ " ## Calculate the Sharpe Ratio.\n",
547
+ " sharpe_ratio = exp_ret / exp_vol\n",
548
+ "\n",
549
+ " # Put the weights into a data frame to see them better.\n",
550
+ " weights_df = pd.DataFrame(\n",
551
+ " data={\n",
552
+ " \"company_name\": com_sel_name_temp,\n",
553
+ " \"random_weights\": rand_weig,\n",
554
+ " \"rebalance_weights\": rebal_weig,\n",
555
+ " }\n",
556
+ " )\n",
557
+ "\n",
558
+ " st.divider()\n",
559
+ "\n",
560
+ " st.markdown(\n",
561
+ " \"<h5 style='text-align: center;'>Random Portfolio Weights</h5>\",\n",
562
+ " unsafe_allow_html=True,\n",
563
+ " )\n",
564
+ " st.dataframe(weights_df, use_container_width=True)\n",
565
+ "\n",
566
+ " # Do the same with the other metrics.\n",
567
+ " metrics_df = pd.DataFrame(\n",
568
+ " data={\n",
569
+ " \"Expected Portfolio Returns\": exp_ret,\n",
570
+ " \"Expected Portfolio Volatility\": exp_vol,\n",
571
+ " \"Portfolio Sharpe Ratio\": sharpe_ratio,\n",
572
+ " },\n",
573
+ " index=[0],\n",
574
+ " )\n",
575
+ "\n",
576
+ " st.markdown(\n",
577
+ " \"<h5 style='text-align: center;'>Random Weights Metrics</h5>\",\n",
578
+ " unsafe_allow_html=True,\n",
579
+ " )\n",
580
+ " st.dataframe(metrics_df, use_container_width=True)\n",
581
+ "\n",
582
+ " st.divider()\n"
583
+ ]
584
+ }
585
+ ],
586
+ "metadata": {
587
+ "kernelspec": {
588
+ "display_name": "Python 3 (ipykernel)",
589
+ "language": "python",
590
+ "name": "python3"
591
+ },
592
+ "language_info": {
593
+ "codemirror_mode": {
594
+ "name": "ipython",
595
+ "version": 3
596
+ },
597
+ "file_extension": ".py",
598
+ "mimetype": "text/x-python",
599
+ "name": "python",
600
+ "nbconvert_exporter": "python",
601
+ "pygments_lexer": "ipython3",
602
+ "version": "3.10.12"
603
+ }
604
+ },
605
+ "nbformat": 4,
606
+ "nbformat_minor": 5
607
+ }
main.py CHANGED
@@ -86,6 +86,40 @@ if num_tick > 1:
86
  # com_data.dropna(inplace=True)
87
  num_tick = len(com_data.columns)
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  if num_tick > 1:
90
  com_sel_name_temp = []
91
  for i in com_data.columns:
@@ -93,8 +127,6 @@ if num_tick > 1:
93
 
94
  com_sel = com_data.columns.to_list()
95
 
96
- st.dataframe(com_data, use_container_width=True)
97
-
98
  ## Log-Return of Company Dataset
99
  log_return = np.log(1 + com_data.pct_change())
100
 
@@ -122,8 +154,6 @@ if num_tick > 1:
122
  }
123
  )
124
 
125
- st.divider()
126
-
127
  st.markdown(
128
  "<h5 style='text-align: center;'>Random Portfolio Weights</h5>",
129
  unsafe_allow_html=True,
@@ -146,7 +176,6 @@ if num_tick > 1:
146
  )
147
  st.dataframe(metrics_df, use_container_width=True)
148
 
149
- st.divider()
150
 
151
  ## Let's get started with Monte Carlo Simulations
152
 
 
86
  # com_data.dropna(inplace=True)
87
  num_tick = len(com_data.columns)
88
 
89
+ # Dataframe of the selected companies
90
+ st.dataframe(com_data, use_container_width=True)
91
+
92
+ # make a function to calculate moving averages from the dataframe com_data, store those moving averages in dictionary for respective company
93
+ def moving_average(data, window):
94
+ ma = {}
95
+ for i in data.columns:
96
+ ma[i] = data[i].rolling(window=window).mean().values[2]
97
+ return ma
98
+
99
+ moving_avg = moving_average(com_data, 3)
100
+ MA_df = pd.DataFrame(moving_avg.items(), columns=['Company', 'Purchase Rate (MA)'])
101
+
102
+ # calculate percentage return till present date from the moving average price of the stock
103
+ def percentage_return(data, moving_avg):
104
+ pr = {}
105
+ for i in data.columns:
106
+ pr[i] = f'{round(((data[i].values[-1] - moving_avg[i]) / moving_avg[i]) * 100,2) }%'
107
+ return pr
108
+
109
+ # make percentage return a dataframe from dictionary
110
+ percentage_return = pd.DataFrame(percentage_return(com_data, moving_avg).items(), columns=['Company', 'Percentage Return'])
111
+
112
+ #merge MA_df and percentage_return on "Company" columns
113
+ MA_df = pd.merge(MA_df, percentage_return, on='Company')
114
+
115
+ st.markdown(
116
+ "<h5 style='text-align: center;'>Percent Returns & MA price</h5>",
117
+ unsafe_allow_html=True,
118
+ )
119
+
120
+ st.write("<p style='text-align: center;'>**rate of purchase is moving average(MA) of 3 (t+2) days</p>", unsafe_allow_html=True)
121
+ st.dataframe(MA_df,use_container_width=True)
122
+
123
  if num_tick > 1:
124
  com_sel_name_temp = []
125
  for i in com_data.columns:
 
127
 
128
  com_sel = com_data.columns.to_list()
129
 
 
 
130
  ## Log-Return of Company Dataset
131
  log_return = np.log(1 + com_data.pct_change())
132
 
 
154
  }
155
  )
156
 
 
 
157
  st.markdown(
158
  "<h5 style='text-align: center;'>Random Portfolio Weights</h5>",
159
  unsafe_allow_html=True,
 
176
  )
177
  st.dataframe(metrics_df, use_container_width=True)
178
 
 
179
 
180
  ## Let's get started with Monte Carlo Simulations
181