shyam gupta commited on
Commit
663e2d1
2 Parent(s): 17c56fd d1094fd

Merge pull request #10 from bhanuprasanna527/shyam

Browse files
.devcontainer/devcontainer.json DELETED
@@ -1,33 +0,0 @@
1
- {
2
- "name": "Python 3",
3
- // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
4
- "image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
5
- "customizations": {
6
- "codespaces": {
7
- "openFiles": [
8
- "README.md",
9
- "main.py"
10
- ]
11
- },
12
- "vscode": {
13
- "settings": {},
14
- "extensions": [
15
- "ms-python.python",
16
- "ms-python.vscode-pylance"
17
- ]
18
- }
19
- },
20
- "updateContentCommand": "[ -f packages.txt ] && sudo apt update && sudo apt upgrade -y && sudo xargs apt install -y <packages.txt; [ -f requirements.txt ] && pip3 install --user -r requirements.txt; pip3 install --user streamlit; echo '✅ Packages installed and Requirements met'",
21
- "postAttachCommand": {
22
- "server": "streamlit run main.py --server.enableCORS false --server.enableXsrfProtection false"
23
- },
24
- "portsAttributes": {
25
- "8501": {
26
- "label": "Application",
27
- "onAutoForward": "openPreview"
28
- }
29
- },
30
- "forwardPorts": [
31
- 8501
32
- ]
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.gitignore CHANGED
@@ -1,5 +1,7 @@
1
- # Object file
2
  *.o
3
-
4
- # Ada Library Information
5
  *.ali
 
 
 
 
 
 
 
1
  *.o
 
 
2
  *.ali
3
+ .devcontainer
4
+ .idea
5
+ .ipynb_checkpoints
6
+ __pycache__
7
+ app.py
.idea/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- # Default ignored files
2
- /shelf/
3
- /workspace.xml
4
- # Editor-based HTTP Client requests
5
- /httpRequests/
6
- # Datasource local storage ignored files
7
- /dataSources/
8
- /dataSources.local.xml
 
 
 
 
 
 
 
 
 
.idea/CapiPort.iml DELETED
@@ -1,12 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="PYTHON_MODULE" version="4">
3
- <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$" />
5
- <orderEntry type="jdk" jdkName="data_science" jdkType="Python SDK" />
6
- <orderEntry type="sourceFolder" forTests="false" />
7
- </component>
8
- <component name="PyDocumentationSettings">
9
- <option name="format" value="GOOGLE" />
10
- <option name="myDocStringFormat" value="Google" />
11
- </component>
12
- </module>
 
 
 
 
 
 
 
 
 
 
 
 
 
.idea/inspectionProfiles/profiles_settings.xml DELETED
@@ -1,6 +0,0 @@
1
- <component name="InspectionProjectProfileManager">
2
- <settings>
3
- <option name="USE_PROJECT_PROFILE" value="false" />
4
- <version value="1.0" />
5
- </settings>
6
- </component>
 
 
 
 
 
 
 
.idea/misc.xml DELETED
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="Black">
4
- <option name="sdkName" value="data_science" />
5
- </component>
6
- <component name="ProjectRootManager" version="2" project-jdk-name="data_science" project-jdk-type="Python SDK" />
7
- </project>
 
 
 
 
 
 
 
 
.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/CapiPort.iml" filepath="$PROJECT_DIR$/.idea/CapiPort.iml" />
6
- </modules>
7
- </component>
8
- </project>
 
 
 
 
 
 
 
 
 
.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="" vcs="Git" />
5
- </component>
6
- </project>
 
 
 
 
 
 
 
.ipynb_checkpoints/CapiPort-checkpoint.ipynb DELETED
The diff for this file is too large to render. See raw diff
 
.ipynb_checkpoints/Untitled-checkpoint.ipynb DELETED
@@ -1,95 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 2,
6
- "id": "621c09fe",
7
- "metadata": {},
8
- "outputs": [],
9
- "source": [
10
- "from bs4 import BeautifulSoup\n",
11
- "import pandas as pd\n",
12
- "\n",
13
- "# Read HTML content from the file\n",
14
- "with open(\"index.html\", \"r\", encoding=\"utf-8\") as file:\n",
15
- " html_content = file.read()\n",
16
- "\n",
17
- "# Parse the HTML content\n",
18
- "soup = BeautifulSoup(html_content, \"html.parser\")\n",
19
- "\n",
20
- "# Find the table\n",
21
- "table = soup.find(\"table\")\n",
22
- "\n",
23
- "# Extract table data\n",
24
- "if table:\n",
25
- " rows = table.find_all(\"tr\")\n",
26
- " data = []\n",
27
- " for row in rows:\n",
28
- " columns = row.find_all(\"td\")\n",
29
- " if columns: # Ensure it's not a header row or empty row\n",
30
- " row_data = [column.text.strip() for column in columns]\n",
31
- " data.append(row_data)\n",
32
- " # Create DataFrame\n",
33
- " df = pd.DataFrame(data)\n",
34
- " \n",
35
- " # Extract first part and last word from the first column\n",
36
- " df['Name'] = df[0].str.split().str[:-1].str.join(\" \")\n",
37
- " df['Ticker'] = df[0].str.split().str[-1]\n",
38
- " df[['Name', 'Ticker']].to_csv(\"Company List.csv\")\n",
39
- "else:\n",
40
- " print(\"Table not found in the HTML content.\")\n"
41
- ]
42
- },
43
- {
44
- "cell_type": "code",
45
- "execution_count": 1,
46
- "id": "38efd2c9",
47
- "metadata": {},
48
- "outputs": [
49
- {
50
- "ename": "NameError",
51
- "evalue": "name 'c' is not defined",
52
- "output_type": "error",
53
- "traceback": [
54
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
55
- "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
56
- "Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mc\u001b[49m)\n",
57
- "\u001b[0;31mNameError\u001b[0m: name 'c' is not defined"
58
- ]
59
- }
60
- ],
61
- "source": [
62
- "print(c)"
63
- ]
64
- },
65
- {
66
- "cell_type": "code",
67
- "execution_count": null,
68
- "id": "6c185203",
69
- "metadata": {},
70
- "outputs": [],
71
- "source": []
72
- }
73
- ],
74
- "metadata": {
75
- "kernelspec": {
76
- "display_name": "Python 3 (ipykernel)",
77
- "language": "python",
78
- "name": "python3"
79
- },
80
- "language_info": {
81
- "codemirror_mode": {
82
- "name": "ipython",
83
- "version": 3
84
- },
85
- "file_extension": ".py",
86
- "mimetype": "text/x-python",
87
- "name": "python",
88
- "nbconvert_exporter": "python",
89
- "pygments_lexer": "ipython3",
90
- "version": "3.10.13"
91
- }
92
- },
93
- "nbformat": 4,
94
- "nbformat_minor": 5
95
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Notebooks/MAexp.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ from utilities import checker
8
+ import datetime
9
+
10
+ with open(r"../style/style.css") as css:
11
+ st.markdown(f"<style>{css.read()}</style>", unsafe_allow_html=True)
12
+
13
+ st.markdown(
14
+ "<h1 style='text-align: center;'><u>CapiPort</u></h1>", unsafe_allow_html=True
15
+ )
16
+
17
+ st.markdown(
18
+ "<h5 style='text-align: center; color: gray;'>Your Portfolio Optimisation Tool</h5>",
19
+ unsafe_allow_html=True,
20
+ )
21
+ st.header(
22
+ "",
23
+ divider="rainbow",
24
+ )
25
+
26
+ color = "Quest"
27
+ st.markdown(
28
+ "<h1 style='text-align: center;'>🔍 Quest for financial excellence begins with meticulous portfolio optimization</u></h1>",
29
+ unsafe_allow_html=True,
30
+ )
31
+
32
+ st.header(
33
+ "",
34
+ divider="rainbow",
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
+ company_symbol_dict = dict()
44
+
45
+ for CSymbol, CName in zip(company_symbol, company_name):
46
+ company_dict[CName] = CSymbol
47
+
48
+ for CSymbol, CName in zip(company_symbol, company_name):
49
+ company_symbol_dict[CSymbol] = CName
50
+
51
+ st.markdown(
52
+ """
53
+ <style>
54
+ .big-font {
55
+ font-size:20px;
56
+ }
57
+ </style>""",
58
+ unsafe_allow_html=True,
59
+ )
60
+
61
+ st.markdown('<p class="big-font">Select Multiple Companies</p>', unsafe_allow_html=True)
62
+
63
+ com_sel_name = st.multiselect("", company_name, default=None)
64
+ com_sel_date = []
65
+
66
+ for i in com_sel_name:
67
+ d = st.date_input(
68
+ f"On which date did you invested in - {i}",
69
+ value= pd.Timestamp('2021-01-01'),
70
+ format="YYYY-MM-DD",
71
+ )
72
+ d = d - datetime.timedelta(days=3)
73
+ com_sel_date.append(d)
74
+
75
+ com_sel = [company_dict[i] for i in com_sel_name]
76
+
77
+ num_tick = len(com_sel)
78
+
79
+
80
+ if num_tick > 1:
81
+ com_data = pd.DataFrame()
82
+ for cname, cdate in zip(com_sel, com_sel_date):
83
+ stock_data_temp = yf.download(cname, start=cdate, end=pd.Timestamp.now().strftime('%Y-%m-%d'))['Low']
84
+ stock_data_temp.name = cname
85
+ com_data = pd.merge(com_data, stock_data_temp, how="outer", right_index=True, left_index=True)
86
+ for i in com_data.columns:
87
+ com_data.dropna(axis=1, how='all', inplace=True)
88
+ # com_data.dropna(inplace=True)
89
+ num_tick = len(com_data.columns)
90
+
91
+ # Dataframe of the selected companies
92
+ st.dataframe(com_data, use_container_width=True)
93
+
94
+ # make a function to calculate moving averages from the dataframe com_data, store those moving averages in dictionary for respective company
95
+ def moving_average(data, window):
96
+ ma = {}
97
+ for i in data.columns:
98
+ ma[i] = data[i].rolling(window=window).mean().values[2]
99
+ return ma
100
+
101
+ moving_avg = moving_average(com_data, 3)
102
+ MA_df = pd.DataFrame(moving_avg.items(), columns=['Company', 'Purchase Rate (MA)'])
103
+
104
+ # calculate percentage return till present date from the moving average price of the stock
105
+ def percentage_return(data, moving_avg):
106
+ pr = {}
107
+ for i in data.columns:
108
+ pr[i] = f'{round(((data[i].values[-1] - moving_avg[i]) / moving_avg[i]) * 100,2) }%'
109
+ return pr
110
+
111
+ # make percentage return a dataframe from dictionary
112
+ percentage_return = pd.DataFrame(percentage_return(com_data, moving_avg).items(), columns=['Company', 'Percentage Return'])
113
+
114
+ #merge MA_df and percentage_return on "Company" columns
115
+ MA_df = pd.merge(MA_df, percentage_return, on='Company')
116
+
117
+ st.markdown(
118
+ "<h5 style='text-align: center;'>Percent Returns & MA price</h5>",
119
+ unsafe_allow_html=True,
120
+ )
121
+
122
+ st.write("<p style='text-align: center;'>**rate of purchase is moving average(MA) of 3 (t+2) days</p>", unsafe_allow_html=True)
123
+ st.dataframe(MA_df,use_container_width=True)
124
+
125
+ if num_tick > 1:
126
+ com_sel_name_temp = []
127
+ for i in com_data.columns:
128
+ com_sel_name_temp.append(company_symbol_dict[i])
129
+ com_sel = com_data.columns.to_list()
130
+
131
+
132
+ ## Log-Return of Company Dataset
133
+ log_return = np.log(1 + com_data.pct_change())
134
+
135
+ ## Generate Random Weights
136
+ rand_weig = np.array(np.random.random(num_tick))
137
+
138
+ ## Rebalancing Random Weights
139
+ rebal_weig = rand_weig / np.sum(rand_weig)
140
+
141
+ ## Calculate the Expected Returns, Annualize it by * 252.0
142
+ exp_ret = np.sum((log_return.mean() * rebal_weig) * 252)
143
+
144
+ ## Calculate the Expected Volatility, Annualize it by * 252.0
145
+ exp_vol = np.sqrt(np.dot(rebal_weig.T, np.dot(log_return.cov() * 252, rebal_weig)))
146
+
147
+ ## Calculate the Sharpe Ratio.
148
+ sharpe_ratio = exp_ret / exp_vol
149
+
150
+ # Put the weights into a data frame to see them better.
151
+ weights_df = pd.DataFrame(
152
+ data={
153
+ "company_name": com_sel_name_temp,
154
+ "random_weights": rand_weig,
155
+ "rebalance_weights": rebal_weig,
156
+ }
157
+ )
158
+
159
+ st.divider()
160
+
161
+ st.markdown(
162
+ "<h5 style='text-align: center;'>Random Portfolio Weights</h5>",
163
+ unsafe_allow_html=True,
164
+ )
165
+ st.dataframe(weights_df, use_container_width=True)
166
+
167
+ # Do the same with the other metrics.
168
+ metrics_df = pd.DataFrame(
169
+ data={
170
+ "Expected Portfolio Returns": exp_ret,
171
+ "Expected Portfolio Volatility": exp_vol,
172
+ "Portfolio Sharpe Ratio": sharpe_ratio,
173
+ },
174
+ index=[0],
175
+ )
176
+
177
+ st.markdown(
178
+ "<h5 style='text-align: center;'>Random Weights Metrics</h5>",
179
+ unsafe_allow_html=True,
180
+ )
181
+ st.dataframe(metrics_df, use_container_width=True)
182
+
183
+ st.divider()
Notebooks/Untitled.ipynb CHANGED
@@ -86,8 +86,92 @@
86
  "outputs": [
87
  {
88
  "data": {
89
- "text/plain": " 0 1 2 3 \\\ncount 2062 2062 2062 2062 \nunique 2062 2044 2060 2056 \ntop 20 Microns Ltd. 20MICRONS ₹1.14 -4.16% ₹8.8/₹3.79 ₹128.05 Crs \nfreq 1 4 2 2 \n\n 4 Name Ticker \ncount 2062 2062 2062 \nunique 125 2061 2062 \ntop Pharmaceuticals Gallantt Ispat Ltd. 20MICRONS \nfreq 105 2 1 ",
90
- "text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>0</th>\n <th>1</th>\n <th>2</th>\n <th>3</th>\n <th>4</th>\n <th>Name</th>\n <th>Ticker</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>count</th>\n <td>2062</td>\n <td>2062</td>\n <td>2062</td>\n <td>2062</td>\n <td>2062</td>\n <td>2062</td>\n <td>2062</td>\n </tr>\n <tr>\n <th>unique</th>\n <td>2062</td>\n <td>2044</td>\n <td>2060</td>\n <td>2056</td>\n <td>125</td>\n <td>2061</td>\n <td>2062</td>\n </tr>\n <tr>\n <th>top</th>\n <td>20 Microns Ltd. 20MICRONS</td>\n <td>₹1.14 -4.16%</td>\n <td>₹8.8/₹3.79</td>\n <td>₹128.05 Crs</td>\n <td>Pharmaceuticals</td>\n <td>Gallantt Ispat Ltd.</td>\n <td>20MICRONS</td>\n </tr>\n <tr>\n <th>freq</th>\n <td>1</td>\n <td>4</td>\n <td>2</td>\n <td>2</td>\n <td>105</td>\n <td>2</td>\n <td>1</td>\n </tr>\n </tbody>\n</table>\n</div>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  },
92
  "execution_count": 4,
93
  "metadata": {},
@@ -111,7 +195,9 @@
111
  "outputs": [
112
  {
113
  "data": {
114
- "text/plain": "2062"
 
 
115
  },
116
  "execution_count": 5,
117
  "metadata": {},
@@ -150,8 +236,68 @@
150
  "outputs": [
151
  {
152
  "data": {
153
- "text/plain": " 0 1 \\\n610 Gallantt Ispat Ltd.\\n ... ₹64.15 -0.77% \n611 Gallantt Ispat Ltd.\\n ... ₹216.94 +1.33% \n\n 2 3 4 Name Ticker \n610 ₹76/₹44.64 ₹1807.11 Crs Iron & Steel Gallantt Ispat Ltd. GALLISPAT \n611 ₹236.4/₹49.54 ₹5235.8 Crs Iron & Steel Gallantt Ispat Ltd. GALLANTT ",
154
- "text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>0</th>\n <th>1</th>\n <th>2</th>\n <th>3</th>\n <th>4</th>\n <th>Name</th>\n <th>Ticker</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>610</th>\n <td>Gallantt Ispat Ltd.\\n ...</td>\n <td>₹64.15 -0.77%</td>\n <td>₹76/₹44.64</td>\n <td>₹1807.11 Crs</td>\n <td>Iron &amp; Steel</td>\n <td>Gallantt Ispat Ltd.</td>\n <td>GALLISPAT</td>\n </tr>\n <tr>\n <th>611</th>\n <td>Gallantt Ispat Ltd.\\n ...</td>\n <td>₹216.94 +1.33%</td>\n <td>₹236.4/₹49.54</td>\n <td>₹5235.8 Crs</td>\n <td>Iron &amp; Steel</td>\n <td>Gallantt Ispat Ltd.</td>\n <td>GALLANTT</td>\n </tr>\n </tbody>\n</table>\n</div>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  },
156
  "execution_count": 7,
157
  "metadata": {},
@@ -179,12 +325,13 @@
179
  },
180
  {
181
  "cell_type": "code",
182
- "outputs": [],
183
- "source": [],
184
  "metadata": {
185
  "collapsed": false
186
  },
187
- "id": "e9274e3c3011e6fc"
 
188
  }
189
  ],
190
  "metadata": {
@@ -203,7 +350,7 @@
203
  "name": "python",
204
  "nbconvert_exporter": "python",
205
  "pygments_lexer": "ipython3",
206
- "version": "3.10.13"
207
  }
208
  },
209
  "nbformat": 4,
 
86
  "outputs": [
87
  {
88
  "data": {
89
+ "text/html": [
90
+ "<div>\n",
91
+ "<style scoped>\n",
92
+ " .dataframe tbody tr th:only-of-type {\n",
93
+ " vertical-align: middle;\n",
94
+ " }\n",
95
+ "\n",
96
+ " .dataframe tbody tr th {\n",
97
+ " vertical-align: top;\n",
98
+ " }\n",
99
+ "\n",
100
+ " .dataframe thead th {\n",
101
+ " text-align: right;\n",
102
+ " }\n",
103
+ "</style>\n",
104
+ "<table border=\"1\" class=\"dataframe\">\n",
105
+ " <thead>\n",
106
+ " <tr style=\"text-align: right;\">\n",
107
+ " <th></th>\n",
108
+ " <th>0</th>\n",
109
+ " <th>1</th>\n",
110
+ " <th>2</th>\n",
111
+ " <th>3</th>\n",
112
+ " <th>4</th>\n",
113
+ " <th>Name</th>\n",
114
+ " <th>Ticker</th>\n",
115
+ " </tr>\n",
116
+ " </thead>\n",
117
+ " <tbody>\n",
118
+ " <tr>\n",
119
+ " <th>count</th>\n",
120
+ " <td>2062</td>\n",
121
+ " <td>2062</td>\n",
122
+ " <td>2062</td>\n",
123
+ " <td>2062</td>\n",
124
+ " <td>2062</td>\n",
125
+ " <td>2062</td>\n",
126
+ " <td>2062</td>\n",
127
+ " </tr>\n",
128
+ " <tr>\n",
129
+ " <th>unique</th>\n",
130
+ " <td>2062</td>\n",
131
+ " <td>2044</td>\n",
132
+ " <td>2060</td>\n",
133
+ " <td>2056</td>\n",
134
+ " <td>125</td>\n",
135
+ " <td>2061</td>\n",
136
+ " <td>2062</td>\n",
137
+ " </tr>\n",
138
+ " <tr>\n",
139
+ " <th>top</th>\n",
140
+ " <td>20 Microns Ltd. 20MICRONS</td>\n",
141
+ " <td>₹1.14 -4.16%</td>\n",
142
+ " <td>₹8.8/₹3.79</td>\n",
143
+ " <td>₹128.05 Crs</td>\n",
144
+ " <td>Pharmaceuticals</td>\n",
145
+ " <td>Gallantt Ispat Ltd.</td>\n",
146
+ " <td>20MICRONS</td>\n",
147
+ " </tr>\n",
148
+ " <tr>\n",
149
+ " <th>freq</th>\n",
150
+ " <td>1</td>\n",
151
+ " <td>4</td>\n",
152
+ " <td>2</td>\n",
153
+ " <td>2</td>\n",
154
+ " <td>105</td>\n",
155
+ " <td>2</td>\n",
156
+ " <td>1</td>\n",
157
+ " </tr>\n",
158
+ " </tbody>\n",
159
+ "</table>\n",
160
+ "</div>"
161
+ ],
162
+ "text/plain": [
163
+ " 0 1 2 3 \\\n",
164
+ "count 2062 2062 2062 2062 \n",
165
+ "unique 2062 2044 2060 2056 \n",
166
+ "top 20 Microns Ltd. 20MICRONS ₹1.14 -4.16% ₹8.8/₹3.79 ₹128.05 Crs \n",
167
+ "freq 1 4 2 2 \n",
168
+ "\n",
169
+ " 4 Name Ticker \n",
170
+ "count 2062 2062 2062 \n",
171
+ "unique 125 2061 2062 \n",
172
+ "top Pharmaceuticals Gallantt Ispat Ltd. 20MICRONS \n",
173
+ "freq 105 2 1 "
174
+ ]
175
  },
176
  "execution_count": 4,
177
  "metadata": {},
 
195
  "outputs": [
196
  {
197
  "data": {
198
+ "text/plain": [
199
+ "2062"
200
+ ]
201
  },
202
  "execution_count": 5,
203
  "metadata": {},
 
236
  "outputs": [
237
  {
238
  "data": {
239
+ "text/html": [
240
+ "<div>\n",
241
+ "<style scoped>\n",
242
+ " .dataframe tbody tr th:only-of-type {\n",
243
+ " vertical-align: middle;\n",
244
+ " }\n",
245
+ "\n",
246
+ " .dataframe tbody tr th {\n",
247
+ " vertical-align: top;\n",
248
+ " }\n",
249
+ "\n",
250
+ " .dataframe thead th {\n",
251
+ " text-align: right;\n",
252
+ " }\n",
253
+ "</style>\n",
254
+ "<table border=\"1\" class=\"dataframe\">\n",
255
+ " <thead>\n",
256
+ " <tr style=\"text-align: right;\">\n",
257
+ " <th></th>\n",
258
+ " <th>0</th>\n",
259
+ " <th>1</th>\n",
260
+ " <th>2</th>\n",
261
+ " <th>3</th>\n",
262
+ " <th>4</th>\n",
263
+ " <th>Name</th>\n",
264
+ " <th>Ticker</th>\n",
265
+ " </tr>\n",
266
+ " </thead>\n",
267
+ " <tbody>\n",
268
+ " <tr>\n",
269
+ " <th>610</th>\n",
270
+ " <td>Gallantt Ispat Ltd.\\n ...</td>\n",
271
+ " <td>₹64.15 -0.77%</td>\n",
272
+ " <td>₹76/₹44.64</td>\n",
273
+ " <td>₹1807.11 Crs</td>\n",
274
+ " <td>Iron &amp; Steel</td>\n",
275
+ " <td>Gallantt Ispat Ltd.</td>\n",
276
+ " <td>GALLISPAT</td>\n",
277
+ " </tr>\n",
278
+ " <tr>\n",
279
+ " <th>611</th>\n",
280
+ " <td>Gallantt Ispat Ltd.\\n ...</td>\n",
281
+ " <td>₹216.94 +1.33%</td>\n",
282
+ " <td>₹236.4/₹49.54</td>\n",
283
+ " <td>₹5235.8 Crs</td>\n",
284
+ " <td>Iron &amp; Steel</td>\n",
285
+ " <td>Gallantt Ispat Ltd.</td>\n",
286
+ " <td>GALLANTT</td>\n",
287
+ " </tr>\n",
288
+ " </tbody>\n",
289
+ "</table>\n",
290
+ "</div>"
291
+ ],
292
+ "text/plain": [
293
+ " 0 1 \\\n",
294
+ "610 Gallantt Ispat Ltd.\\n ... ₹64.15 -0.77% \n",
295
+ "611 Gallantt Ispat Ltd.\\n ... ₹216.94 +1.33% \n",
296
+ "\n",
297
+ " 2 3 4 Name Ticker \n",
298
+ "610 ₹76/₹44.64 ₹1807.11 Crs Iron & Steel Gallantt Ispat Ltd. GALLISPAT \n",
299
+ "611 ₹236.4/₹49.54 ₹5235.8 Crs Iron & Steel Gallantt Ispat Ltd. GALLANTT "
300
+ ]
301
  },
302
  "execution_count": 7,
303
  "metadata": {},
 
325
  },
326
  {
327
  "cell_type": "code",
328
+ "execution_count": null,
329
+ "id": "e9274e3c3011e6fc",
330
  "metadata": {
331
  "collapsed": false
332
  },
333
+ "outputs": [],
334
+ "source": []
335
  }
336
  ],
337
  "metadata": {
 
350
  "name": "python",
351
  "nbconvert_exporter": "python",
352
  "pygments_lexer": "ipython3",
353
+ "version": "3.10.12"
354
  }
355
  },
356
  "nbformat": 4,
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
+ }
__pycache__/CapiPort.cpython-310.pyc DELETED
Binary file (1.75 kB)
 
main.py CHANGED
@@ -3,6 +3,8 @@ import numpy as np
3
  import yfinance as yf
4
  import streamlit as st
5
  import plotly.graph_objects as go
 
 
6
 
7
  with open(r"style/style.css") as css:
8
  st.markdown(f"<style>{css.read()}</style>", unsafe_allow_html=True)
@@ -31,7 +33,6 @@ st.header(
31
  divider="rainbow",
32
  )
33
 
34
-
35
  list_df = pd.read_csv("Data/Company List.csv")
36
 
37
  company_name = list_df["Name"].to_list()
@@ -59,43 +60,100 @@ st.markdown(
59
  st.markdown('<p class="big-font">Select Multiple Companies</p>', unsafe_allow_html=True)
60
 
61
  com_sel_name = st.multiselect("", company_name, default=None)
 
 
 
 
 
 
 
 
 
 
62
 
63
  com_sel = [company_dict[i] for i in com_sel_name]
64
 
65
  num_tick = len(com_sel)
66
 
67
  if num_tick > 1:
68
-
69
- com_data = yf.download(com_sel, start="1900-01-01", end="2024-03-08")["Adj Close"]
 
 
 
 
 
 
 
70
  for i in com_data.columns:
71
- com_data.dropna(axis=1, how='all', inplace=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
@@ -104,13 +162,10 @@ if num_tick > 1:
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,
@@ -133,8 +188,6 @@ if num_tick > 1:
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
@@ -152,9 +205,15 @@ if num_tick > 1:
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)
@@ -170,6 +229,10 @@ if num_tick > 1:
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]
@@ -213,8 +276,8 @@ if num_tick > 1:
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
 
@@ -227,47 +290,51 @@ if num_tick > 1:
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)
 
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)
 
33
  divider="rainbow",
34
  )
35
 
 
36
  list_df = pd.read_csv("Data/Company List.csv")
37
 
38
  company_name = list_df["Name"].to_list()
 
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(
82
+ cname, start=cdate, end=pd.Timestamp.now().strftime("%Y-%m-%d")
83
+ )["Low"]
84
+ stock_data_temp.name = cname
85
+ com_data = pd.merge(
86
+ com_data, stock_data_temp, how="outer", right_index=True, left_index=True
87
+ )
88
  for i in com_data.columns:
89
+ com_data.dropna(axis=1, how="all", inplace=True)
90
+ # com_data.dropna(inplace=True)
91
  num_tick = len(com_data.columns)
92
 
93
+ # Dataframe of the selected companies
94
+ st.dataframe(com_data, use_container_width=True)
95
+
96
+ # make a function to calculate moving averages from the dataframe com_data, store those moving averages in dictionary for respective company
97
+ def moving_average(data, window):
98
+ ma = {}
99
+ for i in data.columns:
100
+ ma[i] = data[i].rolling(window=window).mean().values[2]
101
+ return ma
102
+
103
+ moving_avg = moving_average(com_data, 3)
104
+ MA_df = pd.DataFrame(moving_avg.items(), columns=["Company", "Purchase Rate (MA)"])
105
+
106
+ # calculate percentage return till present date from the moving average price of the stock
107
+ def percentage_return(data, moving_avg):
108
+ pr = {}
109
+ for i in data.columns:
110
+ pr[i] = (
111
+ f"{round(((data[i].values[-1] - moving_avg[i]) / moving_avg[i]) * 100,2) }%"
112
+ )
113
+ return pr
114
+
115
+ # make percentage return a dataframe from dictionary
116
+ percentage_return = pd.DataFrame(
117
+ percentage_return(com_data, moving_avg).items(),
118
+ columns=["Company", "Percentage Return"],
119
+ )
120
+
121
+ # merge MA_df and percentage_return on "Company" columns
122
+ MA_df = pd.merge(MA_df, percentage_return, on="Company")
123
+
124
+ st.markdown(
125
+ "<h5 style='text-align: center;'>Percent Returns & MA price</h5>",
126
+ unsafe_allow_html=True,
127
+ )
128
+
129
+ st.write(
130
+ "<p style='text-align: center;'>**rate of purchase is moving average(MA) of 3 (t+2) days</p>",
131
+ unsafe_allow_html=True,
132
+ )
133
+ st.dataframe(MA_df, use_container_width=True)
134
+
135
  if num_tick > 1:
136
  com_sel_name_temp = []
137
  for i in com_data.columns:
138
  com_sel_name_temp.append(company_symbol_dict[i])
139
 
140
  com_sel = com_data.columns.to_list()
 
 
 
141
 
142
  ## Log-Return of Company Dataset
143
  log_return = np.log(1 + com_data.pct_change())
144
 
145
  ## Generate Random Weights
146
+ rand_weig = np.array([100 / len(com_sel)] * len(com_sel))
 
147
  ## Rebalancing Random Weights
148
  rebal_weig = rand_weig / np.sum(rand_weig)
149
 
150
+ ## Calculate the Expected Returns, Annualize it by * 252.0
151
+ exp_ret = np.sum((log_return.mean() * rebal_weig) * 252)
152
 
153
+ ## Calculate the Expected Volatility, Annualize it by * 252.0
154
+ exp_vol = np.sqrt(
155
+ np.dot(rebal_weig.T, np.dot(log_return.cov() * 252, rebal_weig))
156
+ )
157
 
158
  ## Calculate the Sharpe Ratio.
159
  sharpe_ratio = exp_ret / exp_vol
 
162
  weights_df = pd.DataFrame(
163
  data={
164
  "company_name": com_sel_name_temp,
 
165
  "rebalance_weights": rebal_weig,
166
  }
167
  )
168
 
 
 
169
  st.markdown(
170
  "<h5 style='text-align: center;'>Random Portfolio Weights</h5>",
171
  unsafe_allow_html=True,
 
188
  )
189
  st.dataframe(metrics_df, use_container_width=True)
190
 
 
 
191
  ## Let's get started with Monte Carlo Simulations
192
 
193
  ## How many times should we run Monte Carlo
 
205
  ## Create an Array to store the Sharpe Ratios as they are generated
206
  sharpe_arr = np.zeros(num_of_port)
207
 
208
+ ## Track Progress with a Bar
209
+ progress_text = "Simulations in progress. Please wait."
210
+ my_bar = st.progress(0, text=progress_text)
211
 
212
+ ## Let's start the Monte Carlo Simulation
213
+ for ind in range(
214
+ num_of_port
215
+ ): # Corrected the range to iterate from 0 to num_of_port
216
+ time.sleep(0.001)
217
  ## Let's first Calculate the Weights
218
  weig = np.array(np.random.random(num_tick))
219
  weig = weig / np.sum(weig)
 
229
 
230
  ## Calculate and Append the Sharpe Ratio to Sharpe Ratio Array
231
  sharpe_arr[ind] = ret_arr[ind] / vol_arr[ind]
232
+ if ind % 100 == 0:
233
+ my_bar.progress((ind + 1) / num_of_port, text=progress_text)
234
+ # clear progress bar
235
+ my_bar.empty()
236
 
237
  ## Let's create a Data Frame with Weights, Returns, Volatitlity, and the Sharpe Ratio
238
  sim_data = [ret_arr, vol_arr, sharpe_arr, all_weights]
 
276
 
277
  min_volatility_weights_df = pd.DataFrame(
278
  data={
279
+ "company name": com_sel_name_temp,
280
+ "optimized weights": min_volatility["Portfolio Weights"],
281
  }
282
  )
283
 
 
290
 
291
  st.divider()
292
 
293
+ st.markdown(
294
+ "<h1 style='text-align: center;'>Plotting</h1>", unsafe_allow_html=True
295
+ )
296
 
297
+ # plot a pie chart using plotly for max sharpe ratio
298
  fig = go.Figure(
299
+ data=go.Pie(
300
+ labels=com_sel_name_temp,
301
+ values=max_sharpe_ratio["Portfolio Weights"],
302
+ hole=0.3,
303
+ textinfo="percent+label", # Information to display on the pie slices
304
+ hoverinfo="label+percent", # Information to display on hover
305
+ marker=dict(line=dict(color="white", width=2)),
306
+ )
307
+ )
308
+
309
+ # update colors
310
+ fig.update_traces(
311
+ marker=dict(
312
+ colors=[
313
+ "lightseagreen",
314
+ "lightcoral",
315
+ "lightskyblue",
316
+ "lightgreen",
317
+ "lightpink",
318
+ "lightyellow",
319
+ "lightblue",
320
+ "lightgrey",
321
+ "lightgoldenrodyellow",
322
+ "lightcyan",
323
+ ]
324
  )
325
  )
326
 
327
+ # update layout of the pie chart
328
+
329
  # Add color bar
330
  fig.update_layout(coloraxis_colorbar=dict(title="Sharpe Ratio"))
331
 
332
  # Add title and axis labels
333
  fig.update_layout(
334
+ title="Portfolio Composition",
335
+ showlegend=False,
336
+ height=500,
337
+ width=700,
338
+ margin=dict(l=50, r=50, t=50, b=50),
 
 
 
 
 
 
 
 
 
339
  )
 
 
 
 
 
 
 
 
 
 
 
 
340
  st.plotly_chart(fig, use_container_width=True)
utilities/__init__.py ADDED
File without changes
utilities/checker.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import yfinance as yf
2
+
3
+ # 1. Check if the company is listed on Yahoo Finance
4
+ def check_company(company_dict):
5
+ com_sel = []
6
+ for i in company_dict.keys():
7
+ if yf.Ticker(company_dict[i]).info:
8
+ com_sel.append(i)
9
+
10
+ return com_sel
11
+
12
+ #2. make a function to calculate moving averages from the dataframe com_data, store those moving averages in dictionary for respective company
13
+ def moving_average(data, window):
14
+ ma = {}
15
+ for i in data.columns:
16
+ ma[i] = data[i].rolling(window=window).mean().values[2]
17
+ return ma
18
+
19
+
20
+ # calculate percentage return till present date from the moving average price of the stock
21
+ def percentage_return(data, moving_avg):
22
+ pr = {}
23
+ for i in data.columns:
24
+ pr[i] = f'{round(((data[i].values[-1] - moving_avg[i]) / moving_avg[i]) * 100,2) }%'
25
+ return pr
26
+