prasanth.thangavel commited on
Commit
a71b954
·
1 Parent(s): 04cf5a7

Made improvements

Browse files
Files changed (3) hide show
  1. app.py +32 -5
  2. notebooks/scratchpad.ipynb +182 -112
  3. utils/yfinance_utils.py +2 -0
app.py CHANGED
@@ -30,10 +30,10 @@ st.write("Note: Cryptocurrencies (BTC, ETH, SOL, DOGE) are highly volatile and s
30
  st.sidebar.header("Investment Parameters")
31
  currency = st.sidebar.selectbox("Display Currency", ["USD", "SGD"], index=0)
32
  initial_investment = st.sidebar.number_input(f"Initial Investment Amount ({currency})", min_value=1000, value=10000, step=1000)
33
- start_date = st.sidebar.date_input("Start Date", value=datetime.now() - timedelta(days=365*10))
34
  user_end_date = st.sidebar.date_input("End Date", value=datetime.now())
35
  fd_rate = st.sidebar.number_input("Fixed Deposit Rate (%)", min_value=0.0, value=2.9, step=0.1) / 100
36
- use_log_scale = st.sidebar.checkbox("Use Log Scale", value=False)
37
 
38
  # Asset selection
39
  selected_assets = st.sidebar.multiselect(
@@ -61,7 +61,14 @@ selected_assets = st.sidebar.multiselect(
61
  "Solana",
62
  "Dogecoin",
63
  ],
64
- default=["Fixed Deposit", "Microsoft", "Google", "Nvidia"]
 
 
 
 
 
 
 
65
  )
66
 
67
  # Today's date for reference
@@ -73,8 +80,8 @@ currency_symbol = "$" if currency == "USD" else "S$"
73
  # Create a dictionary of tickers for yfinance
74
  tickers = {
75
  "Gold": "GC=F",
76
- "SGS Bonds": "^TNX",
77
- "US Treasury Bonds": "^TNX",
78
  "NASDAQ Composite": "^IXIC",
79
  "NASDAQ Large Cap": "^NDX",
80
  "NASDAQ 100": "^NDX",
@@ -204,6 +211,26 @@ for asset in selected_assets:
204
  else:
205
  st.write(f"{asset}: N/A")
206
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  # Show warnings for data availability
208
  for asset in selected_assets:
209
  if asset in actual_start_dates and pd.Timestamp(actual_start_dates[asset]).date() > start_date:
 
30
  st.sidebar.header("Investment Parameters")
31
  currency = st.sidebar.selectbox("Display Currency", ["USD", "SGD"], index=0)
32
  initial_investment = st.sidebar.number_input(f"Initial Investment Amount ({currency})", min_value=1000, value=10000, step=1000)
33
+ start_date = st.sidebar.date_input("Start Date", value=datetime.now() - timedelta(days=365*25))
34
  user_end_date = st.sidebar.date_input("End Date", value=datetime.now())
35
  fd_rate = st.sidebar.number_input("Fixed Deposit Rate (%)", min_value=0.0, value=2.9, step=0.1) / 100
36
+ use_log_scale = st.sidebar.checkbox("Use Log Scale", value=True)
37
 
38
  # Asset selection
39
  selected_assets = st.sidebar.multiselect(
 
61
  "Solana",
62
  "Dogecoin",
63
  ],
64
+ default=[
65
+ "Fixed Deposit",
66
+ "Gold",
67
+ "US Treasury Bonds", "SGS Bonds",
68
+ "S&P 500", "Dow Jones", "NASDAQ Composite", #"NASDAQ Large Cap", "NASDAQ 100",
69
+ "Microsoft", "Google", "Nvidia",
70
+ "Bitcoin"
71
+ ]
72
  )
73
 
74
  # Today's date for reference
 
80
  # Create a dictionary of tickers for yfinance
81
  tickers = {
82
  "Gold": "GC=F",
83
+ "SGS Bonds": "A35.SI", # Nikko AM SGD Investment Grade Corporate Bond ETF
84
+ "US Treasury Bonds": "TLT", # iShares 20+ Year Treasury Bond ETF
85
  "NASDAQ Composite": "^IXIC",
86
  "NASDAQ Large Cap": "^NDX",
87
  "NASDAQ 100": "^NDX",
 
211
  else:
212
  st.write(f"{asset}: N/A")
213
 
214
+ # Calculate and display yearly return statistics
215
+ st.subheader("Yearly Return Statistics")
216
+ for asset in selected_assets:
217
+ valid_series = returns_data[asset].dropna()
218
+ if len(valid_series) > 1:
219
+ # Resample to yearly data
220
+ yearly_data = valid_series.resample('Y').first()
221
+
222
+ # Calculate yearly returns
223
+ yearly_returns = yearly_data.pct_change().dropna()
224
+
225
+ # Count positive and negative years
226
+ positive_years = (yearly_returns > 0).sum()
227
+ total_years = len(yearly_returns)
228
+ positive_percentage = (positive_years / total_years) * 100
229
+
230
+ st.write(f"{asset}: {positive_years} out of {total_years} years ({positive_percentage:.1f}%) had positive returns")
231
+ else:
232
+ st.write(f"{asset}: Insufficient data for yearly analysis")
233
+
234
  # Show warnings for data availability
235
  for asset in selected_assets:
236
  if asset in actual_start_dates and pd.Timestamp(actual_start_dates[asset]).date() > start_date:
notebooks/scratchpad.ipynb CHANGED
@@ -9,37 +9,128 @@
9
  "import yfinance as yf"
10
  ]
11
  },
 
 
 
 
 
 
 
12
  {
13
  "cell_type": "code",
14
- "execution_count": 2,
15
  "metadata": {},
16
  "outputs": [
17
  {
18
- "name": "stdout",
19
  "output_type": "stream",
20
  "text": [
21
- "YF.download() has changed argument auto_adjust default to True\n"
22
  ]
23
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  {
25
  "name": "stderr",
26
  "output_type": "stream",
27
  "text": [
28
  "[*********************100%***********************] 1 of 1 completed\n"
29
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  }
31
  ],
32
  "source": [
33
- "ticker = \"META\"\n",
34
- "start_date = \"2010-01-01\"\n",
35
- "end_date = \"2020-01-10\"\n",
36
- "\n",
37
- "data = yf.download(ticker, start=start_date, end=end_date) # [\"Close\"][ticker]"
38
  ]
39
  },
40
  {
41
  "cell_type": "code",
42
- "execution_count": 3,
43
  "metadata": {},
44
  "outputs": [
45
  {
@@ -55,31 +146,21 @@
55
  " vertical-align: top;\n",
56
  " }\n",
57
  "\n",
58
- " .dataframe thead tr th {\n",
59
- " text-align: left;\n",
60
- " }\n",
61
- "\n",
62
- " .dataframe thead tr:last-of-type th {\n",
63
  " text-align: right;\n",
64
  " }\n",
65
  "</style>\n",
66
  "<table border=\"1\" class=\"dataframe\">\n",
67
  " <thead>\n",
68
- " <tr>\n",
69
- " <th>Price</th>\n",
70
- " <th>Close</th>\n",
71
  " <th>High</th>\n",
72
  " <th>Low</th>\n",
73
- " <th>Open</th>\n",
74
  " <th>Volume</th>\n",
75
- " </tr>\n",
76
- " <tr>\n",
77
- " <th>Ticker</th>\n",
78
- " <th>META</th>\n",
79
- " <th>META</th>\n",
80
- " <th>META</th>\n",
81
- " <th>META</th>\n",
82
- " <th>META</th>\n",
83
  " </tr>\n",
84
  " <tr>\n",
85
  " <th>Date</th>\n",
@@ -88,136 +169,125 @@
88
  " <th></th>\n",
89
  " <th></th>\n",
90
  " <th></th>\n",
 
 
91
  " </tr>\n",
92
  " </thead>\n",
93
  " <tbody>\n",
94
  " <tr>\n",
95
- " <th>2012-05-18</th>\n",
96
- " <td>38.050663</td>\n",
97
- " <td>44.788905</td>\n",
98
- " <td>37.821742</td>\n",
99
- " <td>41.852743</td>\n",
100
  " <td>573576400</td>\n",
 
 
101
  " </tr>\n",
102
  " <tr>\n",
103
- " <th>2012-05-21</th>\n",
104
- " <td>33.870365</td>\n",
105
  " <td>36.488029</td>\n",
106
  " <td>32.845198</td>\n",
107
- " <td>36.358638</td>\n",
108
  " <td>168192700</td>\n",
 
 
109
  " </tr>\n",
110
  " <tr>\n",
111
- " <th>2012-05-22</th>\n",
112
- " <td>30.854582</td>\n",
113
  " <td>33.432433</td>\n",
114
  " <td>30.794864</td>\n",
115
- " <td>32.457030</td>\n",
116
  " <td>101786600</td>\n",
 
 
117
  " </tr>\n",
118
  " <tr>\n",
119
- " <th>2012-05-23</th>\n",
120
- " <td>31.849892</td>\n",
121
  " <td>32.347546</td>\n",
122
  " <td>31.212894</td>\n",
123
- " <td>31.222848</td>\n",
124
  " <td>73600000</td>\n",
 
 
125
  " </tr>\n",
126
  " <tr>\n",
127
- " <th>2012-05-24</th>\n",
128
- " <td>32.875057</td>\n",
129
  " <td>33.054213</td>\n",
130
  " <td>31.620969</td>\n",
131
- " <td>32.795434</td>\n",
132
  " <td>50237200</td>\n",
133
- " </tr>\n",
134
- " <tr>\n",
135
- " <th>...</th>\n",
136
- " <td>...</td>\n",
137
- " <td>...</td>\n",
138
- " <td>...</td>\n",
139
- " <td>...</td>\n",
140
- " <td>...</td>\n",
141
- " </tr>\n",
142
- " <tr>\n",
143
- " <th>2020-01-03</th>\n",
144
- " <td>207.691132</td>\n",
145
- " <td>209.413012</td>\n",
146
- " <td>205.979199</td>\n",
147
- " <td>206.237989</td>\n",
148
- " <td>11188400</td>\n",
149
- " </tr>\n",
150
- " <tr>\n",
151
- " <th>2020-01-06</th>\n",
152
- " <td>211.602707</td>\n",
153
- " <td>211.781855</td>\n",
154
- " <td>205.551226</td>\n",
155
- " <td>205.730374</td>\n",
156
- " <td>17058900</td>\n",
157
- " </tr>\n",
158
- " <tr>\n",
159
- " <th>2020-01-07</th>\n",
160
- " <td>212.060547</td>\n",
161
- " <td>213.573421</td>\n",
162
- " <td>210.756694</td>\n",
163
- " <td>211.821682</td>\n",
164
- " <td>14912400</td>\n",
165
- " </tr>\n",
166
- " <tr>\n",
167
- " <th>2020-01-08</th>\n",
168
- " <td>214.210419</td>\n",
169
- " <td>215.225638</td>\n",
170
- " <td>211.612661</td>\n",
171
- " <td>212.000831</td>\n",
172
- " <td>13475000</td>\n",
173
- " </tr>\n",
174
- " <tr>\n",
175
- " <th>2020-01-09</th>\n",
176
- " <td>217.275986</td>\n",
177
- " <td>217.355612</td>\n",
178
- " <td>215.265457</td>\n",
179
- " <td>216.519541</td>\n",
180
- " <td>12642800</td>\n",
181
  " </tr>\n",
182
  " </tbody>\n",
183
  "</table>\n",
184
- "<p>1923 rows × 5 columns</p>\n",
185
  "</div>"
186
  ],
187
  "text/plain": [
188
- "Price Close High Low Open Volume\n",
189
- "Ticker META META META META META\n",
190
- "Date \n",
191
- "2012-05-18 38.050663 44.788905 37.821742 41.852743 573576400\n",
192
- "2012-05-21 33.870365 36.488029 32.845198 36.358638 168192700\n",
193
- "2012-05-22 30.854582 33.432433 30.794864 32.457030 101786600\n",
194
- "2012-05-23 31.849892 32.347546 31.212894 31.222848 73600000\n",
195
- "2012-05-24 32.875057 33.054213 31.620969 32.795434 50237200\n",
196
- "... ... ... ... ... ...\n",
197
- "2020-01-03 207.691132 209.413012 205.979199 206.237989 11188400\n",
198
- "2020-01-06 211.602707 211.781855 205.551226 205.730374 17058900\n",
199
- "2020-01-07 212.060547 213.573421 210.756694 211.821682 14912400\n",
200
- "2020-01-08 214.210419 215.225638 211.612661 212.000831 13475000\n",
201
- "2020-01-09 217.275986 217.355612 215.265457 216.519541 12642800\n",
202
  "\n",
203
- "[1923 rows x 5 columns]"
 
 
 
 
 
 
204
  ]
205
  },
206
- "execution_count": 3,
207
  "metadata": {},
208
  "output_type": "execute_result"
209
  }
210
  ],
211
  "source": [
212
- "data"
 
 
 
 
 
 
 
213
  ]
214
  },
215
  {
216
  "cell_type": "code",
217
- "execution_count": null,
218
  "metadata": {},
219
- "outputs": [],
220
- "source": []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  }
222
  ],
223
  "metadata": {
 
9
  "import yfinance as yf"
10
  ]
11
  },
12
+ {
13
+ "cell_type": "markdown",
14
+ "metadata": {},
15
+ "source": [
16
+ "## Stocks"
17
+ ]
18
+ },
19
  {
20
  "cell_type": "code",
21
+ "execution_count": 22,
22
  "metadata": {},
23
  "outputs": [
24
  {
25
+ "name": "stderr",
26
  "output_type": "stream",
27
  "text": [
28
+ "[*********************100%***********************] 1 of 1 completed\n"
29
  ]
30
  },
31
+ {
32
+ "data": {
33
+ "text/plain": [
34
+ "Date\n",
35
+ "2012-05-18 38.050667\n",
36
+ "2012-05-21 33.870369\n",
37
+ "2012-05-22 30.854580\n",
38
+ "2012-05-23 31.849892\n",
39
+ "2012-05-24 32.875061\n",
40
+ " ... \n",
41
+ "2020-01-03 207.691162\n",
42
+ "2020-01-06 211.602722\n",
43
+ "2020-01-07 212.060562\n",
44
+ "2020-01-08 214.210419\n",
45
+ "2020-01-09 217.275986\n",
46
+ "Name: META, Length: 1923, dtype: float64"
47
+ ]
48
+ },
49
+ "execution_count": 22,
50
+ "metadata": {},
51
+ "output_type": "execute_result"
52
+ }
53
+ ],
54
+ "source": [
55
+ "ticker = \"META\"\n",
56
+ "start_date = \"2010-01-01\"\n",
57
+ "end_date = \"2020-01-10\"\n",
58
+ "\n",
59
+ "data = yf.download(ticker, start=start_date, end=end_date) # [\"Close\"][ticker]\n",
60
+ "data[\"Close\"][ticker]"
61
+ ]
62
+ },
63
+ {
64
+ "cell_type": "code",
65
+ "execution_count": 9,
66
+ "metadata": {},
67
+ "outputs": [
68
+ {
69
+ "data": {
70
+ "text/plain": [
71
+ "(1923,)"
72
+ ]
73
+ },
74
+ "execution_count": 9,
75
+ "metadata": {},
76
+ "output_type": "execute_result"
77
+ }
78
+ ],
79
+ "source": [
80
+ "data[\"Close\"][ticker].shape"
81
+ ]
82
+ },
83
+ {
84
+ "cell_type": "markdown",
85
+ "metadata": {},
86
+ "source": [
87
+ "## Gold"
88
+ ]
89
+ },
90
+ {
91
+ "cell_type": "code",
92
+ "execution_count": 23,
93
+ "metadata": {},
94
+ "outputs": [
95
  {
96
  "name": "stderr",
97
  "output_type": "stream",
98
  "text": [
99
  "[*********************100%***********************] 1 of 1 completed\n"
100
  ]
101
+ },
102
+ {
103
+ "data": {
104
+ "text/plain": [
105
+ "Date\n",
106
+ "2010-01-04 1117.699951\n",
107
+ "2010-01-05 1118.099976\n",
108
+ "2010-01-06 1135.900024\n",
109
+ "2010-01-07 1133.099976\n",
110
+ "2010-01-08 1138.199951\n",
111
+ " ... \n",
112
+ "2020-01-03 1549.199951\n",
113
+ "2020-01-06 1566.199951\n",
114
+ "2020-01-07 1571.800049\n",
115
+ "2020-01-08 1557.400024\n",
116
+ "2020-01-09 1551.699951\n",
117
+ "Name: GC=F, Length: 2519, dtype: float64"
118
+ ]
119
+ },
120
+ "execution_count": 23,
121
+ "metadata": {},
122
+ "output_type": "execute_result"
123
  }
124
  ],
125
  "source": [
126
+ "ticker = \"GC=F\"\n",
127
+ "data = yf.download(ticker, start=start_date, end=end_date)\n",
128
+ "data[\"Close\"][ticker]"
 
 
129
  ]
130
  },
131
  {
132
  "cell_type": "code",
133
+ "execution_count": null,
134
  "metadata": {},
135
  "outputs": [
136
  {
 
146
  " vertical-align: top;\n",
147
  " }\n",
148
  "\n",
149
+ " .dataframe thead th {\n",
 
 
 
 
150
  " text-align: right;\n",
151
  " }\n",
152
  "</style>\n",
153
  "<table border=\"1\" class=\"dataframe\">\n",
154
  " <thead>\n",
155
+ " <tr style=\"text-align: right;\">\n",
156
+ " <th></th>\n",
157
+ " <th>Open</th>\n",
158
  " <th>High</th>\n",
159
  " <th>Low</th>\n",
160
+ " <th>Close</th>\n",
161
  " <th>Volume</th>\n",
162
+ " <th>Dividends</th>\n",
163
+ " <th>Stock Splits</th>\n",
 
 
 
 
 
 
164
  " </tr>\n",
165
  " <tr>\n",
166
  " <th>Date</th>\n",
 
169
  " <th></th>\n",
170
  " <th></th>\n",
171
  " <th></th>\n",
172
+ " <th></th>\n",
173
+ " <th></th>\n",
174
  " </tr>\n",
175
  " </thead>\n",
176
  " <tbody>\n",
177
  " <tr>\n",
178
+ " <th>2012-05-18 00:00:00-04:00</th>\n",
179
+ " <td>41.852747</td>\n",
180
+ " <td>44.788910</td>\n",
181
+ " <td>37.821746</td>\n",
182
+ " <td>38.050667</td>\n",
183
  " <td>573576400</td>\n",
184
+ " <td>0.0</td>\n",
185
+ " <td>0.0</td>\n",
186
  " </tr>\n",
187
  " <tr>\n",
188
+ " <th>2012-05-21 00:00:00-04:00</th>\n",
189
+ " <td>36.358638</td>\n",
190
  " <td>36.488029</td>\n",
191
  " <td>32.845198</td>\n",
192
+ " <td>33.870365</td>\n",
193
  " <td>168192700</td>\n",
194
+ " <td>0.0</td>\n",
195
+ " <td>0.0</td>\n",
196
  " </tr>\n",
197
  " <tr>\n",
198
+ " <th>2012-05-22 00:00:00-04:00</th>\n",
199
+ " <td>32.457030</td>\n",
200
  " <td>33.432433</td>\n",
201
  " <td>30.794864</td>\n",
202
+ " <td>30.854582</td>\n",
203
  " <td>101786600</td>\n",
204
+ " <td>0.0</td>\n",
205
+ " <td>0.0</td>\n",
206
  " </tr>\n",
207
  " <tr>\n",
208
+ " <th>2012-05-23 00:00:00-04:00</th>\n",
209
+ " <td>31.222848</td>\n",
210
  " <td>32.347546</td>\n",
211
  " <td>31.212894</td>\n",
212
+ " <td>31.849892</td>\n",
213
  " <td>73600000</td>\n",
214
+ " <td>0.0</td>\n",
215
+ " <td>0.0</td>\n",
216
  " </tr>\n",
217
  " <tr>\n",
218
+ " <th>2012-05-24 00:00:00-04:00</th>\n",
219
+ " <td>32.795434</td>\n",
220
  " <td>33.054213</td>\n",
221
  " <td>31.620969</td>\n",
222
+ " <td>32.875057</td>\n",
223
  " <td>50237200</td>\n",
224
+ " <td>0.0</td>\n",
225
+ " <td>0.0</td>\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  " </tr>\n",
227
  " </tbody>\n",
228
  "</table>\n",
 
229
  "</div>"
230
  ],
231
  "text/plain": [
232
+ " Open High Low Close \\\n",
233
+ "Date \n",
234
+ "2012-05-18 00:00:00-04:00 41.852747 44.788910 37.821746 38.050667 \n",
235
+ "2012-05-21 00:00:00-04:00 36.358638 36.488029 32.845198 33.870365 \n",
236
+ "2012-05-22 00:00:00-04:00 32.457030 33.432433 30.794864 30.854582 \n",
237
+ "2012-05-23 00:00:00-04:00 31.222848 32.347546 31.212894 31.849892 \n",
238
+ "2012-05-24 00:00:00-04:00 32.795434 33.054213 31.620969 32.875057 \n",
 
 
 
 
 
 
 
239
  "\n",
240
+ " Volume Dividends Stock Splits \n",
241
+ "Date \n",
242
+ "2012-05-18 00:00:00-04:00 573576400 0.0 0.0 \n",
243
+ "2012-05-21 00:00:00-04:00 168192700 0.0 0.0 \n",
244
+ "2012-05-22 00:00:00-04:00 101786600 0.0 0.0 \n",
245
+ "2012-05-23 00:00:00-04:00 73600000 0.0 0.0 \n",
246
+ "2012-05-24 00:00:00-04:00 50237200 0.0 0.0 "
247
  ]
248
  },
249
+ "execution_count": 16,
250
  "metadata": {},
251
  "output_type": "execute_result"
252
  }
253
  ],
254
  "source": [
255
+ "# Get data for Gold futures\n",
256
+ "gold = yf.Ticker(\"GC=F\")\n",
257
+ "\n",
258
+ "# Get historical data (e.g., for the last month)\n",
259
+ "gold_data = gold.history(period=\"1000mo\")\n",
260
+ "\n",
261
+ "# Print the data\n",
262
+ "(gold_data.head())"
263
  ]
264
  },
265
  {
266
  "cell_type": "code",
267
+ "execution_count": 15,
268
  "metadata": {},
269
+ "outputs": [
270
+ {
271
+ "data": {
272
+ "text/plain": [
273
+ "(6185,)"
274
+ ]
275
+ },
276
+ "execution_count": 15,
277
+ "metadata": {},
278
+ "output_type": "execute_result"
279
+ }
280
+ ],
281
+ "source": [
282
+ "gold_data[\"Close\"].shape"
283
+ ]
284
+ },
285
+ {
286
+ "cell_type": "markdown",
287
+ "metadata": {},
288
+ "source": [
289
+ "## "
290
+ ]
291
  }
292
  ],
293
  "metadata": {
utils/yfinance_utils.py CHANGED
@@ -1,6 +1,8 @@
1
  import yfinance as yf
2
  import pandas as pd
 
3
 
 
4
  def fetch_yfinance_daily(ticker, start_date, end_date):
5
  try:
6
  data = yf.download(ticker, start=start_date, end=end_date)
 
1
  import yfinance as yf
2
  import pandas as pd
3
+ from functools import lru_cache
4
 
5
+ @lru_cache(maxsize=64) # Cache up to 64 different ticker/date combinations
6
  def fetch_yfinance_daily(ticker, start_date, end_date):
7
  try:
8
  data = yf.download(ticker, start=start_date, end=end_date)