Faham commited on
Commit
a88ab54
·
1 Parent(s): df534c5

FIX: filtered out the non-trading days

Browse files
Files changed (1) hide show
  1. Home.py +81 -277
Home.py CHANGED
@@ -12,6 +12,8 @@ import gnews
12
  from bs4 import BeautifulSoup
13
  import importlib.util
14
  import requests
 
 
15
 
16
  try:
17
  from prophet import Prophet
@@ -206,287 +208,15 @@ def get_available_tickers():
206
 
207
  # Comprehensive list of major stocks across sectors
208
  fallback_ticker_list = [
209
- # Technology
210
  "AAPL",
211
  "MSFT",
212
- "GOOGL",
213
  "AMZN",
214
  "META",
215
  "NVDA",
216
  "TSLA",
217
  "NFLX",
218
  "ADBE",
219
- "CRM",
220
- "ORCL",
221
- "INTC",
222
- "AMD",
223
- "QCOM",
224
- "AVGO",
225
- "TXN",
226
- "MU",
227
- "ADI",
228
- "KLAC",
229
- "LRCX",
230
- "ASML",
231
- "TSM",
232
- "NVDA",
233
- "AMD",
234
- "INTC",
235
- "QCOM",
236
- "AVGO",
237
- "TXN",
238
- "MU",
239
- "ADI",
240
- # Financial
241
- "JPM",
242
- "BAC",
243
- "WFC",
244
- "GS",
245
- "MS",
246
- "C",
247
- "USB",
248
- "PNC",
249
- "TFC",
250
- "COF",
251
- "AXP",
252
- "BLK",
253
- "SCHW",
254
- "CME",
255
- "ICE",
256
- "SPGI",
257
- "MCO",
258
- "V",
259
- "MA",
260
- "PYPL",
261
- # Healthcare
262
- "JNJ",
263
- "PFE",
264
- "UNH",
265
- "ABBV",
266
- "MRK",
267
- "TMO",
268
- "ABT",
269
- "DHR",
270
- "BMY",
271
- "AMGN",
272
- "GILD",
273
- "CVS",
274
- "CI",
275
- "ANTM",
276
- "HUM",
277
- "CNC",
278
- "WBA",
279
- "CAH",
280
- "MCK",
281
- "ABC",
282
- # Consumer
283
- "PG",
284
- "KO",
285
- "PEP",
286
- "WMT",
287
- "HD",
288
- "MCD",
289
- "SBUX",
290
- "NKE",
291
- "DIS",
292
- "CMCSA",
293
- "VZ",
294
- "T",
295
- "TMUS",
296
- "CHTR",
297
- "CMCSA",
298
- "FOXA",
299
- "NWSA",
300
- "PARA",
301
- "WBD",
302
- "NFLX",
303
- # Industrial
304
- "BA",
305
- "CAT",
306
- "GE",
307
- "MMM",
308
- "HON",
309
- "UPS",
310
- "FDX",
311
- "RTX",
312
- "LMT",
313
- "NOC",
314
- "GD",
315
- "LHX",
316
- "TDG",
317
- "TXT",
318
- "DE",
319
- "CNH",
320
- "AGCO",
321
- "KUB",
322
- "EMR",
323
- "ETN",
324
- # Energy
325
- "XOM",
326
- "CVX",
327
- "COP",
328
- "EOG",
329
- "SLB",
330
- "PSX",
331
- "VLO",
332
- "MPC",
333
- "OXY",
334
- "HAL",
335
- "BKR",
336
- "NOV",
337
- "FTI",
338
- "WMB",
339
- "KMI",
340
- "ENB",
341
- "EPD",
342
- "ET",
343
- "OKE",
344
- "PXD",
345
- # Real Estate
346
- "AMT",
347
- "PLD",
348
- "CCI",
349
- "EQIX",
350
- "DLR",
351
- "PSA",
352
- "O",
353
- "SPG",
354
- "WELL",
355
- "VICI",
356
- "EQR",
357
- "AVB",
358
- "MAA",
359
- "ESS",
360
- "UDR",
361
- "CPT",
362
- "BXP",
363
- "SLG",
364
- "VNO",
365
- "KIM",
366
- # Utilities
367
- "NEE",
368
- "DUK",
369
- "SO",
370
- "D",
371
- "AEP",
372
- "SRE",
373
- "XEL",
374
- "WEC",
375
- "DTE",
376
- "ED",
377
- "EIX",
378
- "AEE",
379
- "PEG",
380
- "CMS",
381
- "D",
382
- "AEP",
383
- "SRE",
384
- "XEL",
385
- "WEC",
386
- "DTE",
387
- # Materials
388
- "LIN",
389
- "APD",
390
- "FCX",
391
- "NEM",
392
- "DOW",
393
- "DD",
394
- "NUE",
395
- "STLD",
396
- "X",
397
- "AA",
398
- "BLL",
399
- "IP",
400
- "PKG",
401
- "WRK",
402
- "SEE",
403
- "BMS",
404
- "ALB",
405
- "LVS",
406
- "WY",
407
- "VMC",
408
- # Communication Services
409
- "GOOGL",
410
- "META",
411
- "NFLX",
412
- "DIS",
413
- "CMCSA",
414
- "VZ",
415
- "T",
416
- "TMUS",
417
- "CHTR",
418
- "FOXA",
419
- "NWSA",
420
- "PARA",
421
- "WBD",
422
- "LYV",
423
- "MTCH",
424
- "SNAP",
425
- "TWTR",
426
- "PINS",
427
- "SPOT",
428
- "ZM",
429
- # Additional Major Companies
430
- "BRK-B",
431
- "BRK-A",
432
- "V",
433
- "MA",
434
- "PYPL",
435
- "SQ",
436
- "COIN",
437
- "HOOD",
438
- "RBLX",
439
- "UBER",
440
- "LYFT",
441
- "DASH",
442
- "ABNB",
443
- "EXPE",
444
- "BKNG",
445
- "MAR",
446
- "HLT",
447
- "CCL",
448
- "RCL",
449
- "NCLH",
450
- "SBUX",
451
- "MCD",
452
- "YUM",
453
- "CMG",
454
- "DPZ",
455
- "PZZA",
456
- "SHAK",
457
- "WING",
458
- "CHWY",
459
- "PETM",
460
- "TSCO",
461
- "HD",
462
- "LOW",
463
- "TGT",
464
- "COST",
465
- "BJ",
466
- "KR",
467
- "WMT",
468
- "AMZN",
469
- "BABA",
470
- "JD",
471
- "PDD",
472
- "TCEHY",
473
- "BIDU",
474
- "NTES",
475
- "NIO",
476
- "XPEV",
477
- "LI",
478
- "XP",
479
- "DIDI",
480
- "UBER",
481
- "LYFT",
482
- "DASH",
483
- "ABNB",
484
- "EXPE",
485
- "BKNG",
486
- "MAR",
487
- "HLT",
488
- "CCL",
489
- "RCL",
490
  ]
491
 
492
  print(f"Loading {len(fallback_ticker_list)} fallback tickers...")
@@ -515,7 +245,7 @@ def get_available_tickers():
515
  "AAPL": "Apple Inc.",
516
  "TSLA": "Tesla Inc.",
517
  "MSFT": "Microsoft Corporation",
518
- "GOOGL": "Alphabet Inc. (Google)",
519
  "AMZN": "Amazon.com Inc.",
520
  "META": "Meta Platforms Inc.",
521
  "NVDA": "NVIDIA Corporation",
@@ -737,14 +467,42 @@ def create_stock_chart(ticker: str):
737
  # Get the forecast data for the next 30 days (future predictions only)
738
  # Find the last date in historical data
739
  last_historical_date = df["ds"].max()
740
-
741
- # Add one day to ensure we start from tomorrow
742
-
743
  tomorrow = last_historical_date + timedelta(days=1)
744
 
745
  # Filter for only future predictions (starting from tomorrow)
746
  forecast_future = forecast[forecast["ds"] >= tomorrow].copy()
747
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
  # Track Prophet training time
749
  training_time = time.time() - start_time
750
  if RESOURCE_MONITORING_AVAILABLE:
@@ -1168,6 +926,52 @@ def display_top_news(ticker: str):
1168
  st.error(f"Error fetching news for {ticker}: {e}")
1169
 
1170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1171
  def test_server_availability():
1172
  """Test if the MCP servers are available and can be executed."""
1173
 
 
12
  from bs4 import BeautifulSoup
13
  import importlib.util
14
  import requests
15
+ import holidays
16
+ from datetime import datetime, timedelta
17
 
18
  try:
19
  from prophet import Prophet
 
208
 
209
  # Comprehensive list of major stocks across sectors
210
  fallback_ticker_list = [
 
211
  "AAPL",
212
  "MSFT",
213
+ "GOOG",
214
  "AMZN",
215
  "META",
216
  "NVDA",
217
  "TSLA",
218
  "NFLX",
219
  "ADBE",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  ]
221
 
222
  print(f"Loading {len(fallback_ticker_list)} fallback tickers...")
 
245
  "AAPL": "Apple Inc.",
246
  "TSLA": "Tesla Inc.",
247
  "MSFT": "Microsoft Corporation",
248
+ "GOOG": "Alphabet Inc. (Google)",
249
  "AMZN": "Amazon.com Inc.",
250
  "META": "Meta Platforms Inc.",
251
  "NVDA": "NVIDIA Corporation",
 
467
  # Get the forecast data for the next 30 days (future predictions only)
468
  # Find the last date in historical data
469
  last_historical_date = df["ds"].max()
 
 
 
470
  tomorrow = last_historical_date + timedelta(days=1)
471
 
472
  # Filter for only future predictions (starting from tomorrow)
473
  forecast_future = forecast[forecast["ds"] >= tomorrow].copy()
474
 
475
+ # Filter out non-trading days
476
+ forecast_future["is_trading_day"] = forecast_future["ds"].apply(
477
+ is_trading_day
478
+ )
479
+ forecast_future = forecast_future[
480
+ forecast_future["is_trading_day"] == True
481
+ ].copy()
482
+
483
+ # If we don't have enough trading days, get more predictions
484
+ if len(forecast_future) < 20: # Aim for at least 20 trading days
485
+ # Calculate how many more days we need
486
+ additional_days_needed = 30 - len(forecast_future)
487
+ future_extended = model.make_future_dataframe(
488
+ periods=30 + additional_days_needed
489
+ )
490
+ forecast_extended = model.predict(future_extended)
491
+
492
+ # Filter extended forecast for trading days
493
+ forecast_extended_future = forecast_extended[
494
+ forecast_extended["ds"] >= tomorrow
495
+ ].copy()
496
+ forecast_extended_future["is_trading_day"] = forecast_extended_future[
497
+ "ds"
498
+ ].apply(is_trading_day)
499
+ forecast_future = forecast_extended_future[
500
+ forecast_extended_future["is_trading_day"] == True
501
+ ].copy()
502
+
503
+ # Take only the first 30 trading days
504
+ forecast_future = forecast_future.head(30)
505
+
506
  # Track Prophet training time
507
  training_time = time.time() - start_time
508
  if RESOURCE_MONITORING_AVAILABLE:
 
926
  st.error(f"Error fetching news for {ticker}: {e}")
927
 
928
 
929
+ def is_trading_day(date):
930
+ """Check if a date is a trading day (not weekend or holiday)."""
931
+ # Check if it's a weekend
932
+ if date.weekday() >= 5: # Saturday = 5, Sunday = 6
933
+ return False
934
+
935
+ # Check if it's a US market holiday
936
+ us_holidays = holidays.US()
937
+ if date in us_holidays:
938
+ return False
939
+
940
+ return True
941
+
942
+
943
+ def get_next_trading_days(start_date, num_days):
944
+ """Get the next N trading days starting from start_date."""
945
+ trading_days = []
946
+ current_date = start_date
947
+
948
+ while len(trading_days) < num_days:
949
+ if is_trading_day(current_date):
950
+ trading_days.append(current_date)
951
+ current_date += timedelta(days=1)
952
+
953
+ return trading_days
954
+
955
+
956
+ def create_trading_day_future_dataframe(model, periods=30, freq="D"):
957
+ """Create a future dataframe with only trading days."""
958
+ # Get the last date from the training data
959
+ last_date = model.history["ds"].max()
960
+
961
+ # Generate trading days
962
+ trading_days = []
963
+ current_date = last_date + timedelta(days=1)
964
+
965
+ while len(trading_days) < periods:
966
+ if is_trading_day(current_date):
967
+ trading_days.append(current_date)
968
+ current_date += timedelta(days=1)
969
+
970
+ # Create future dataframe with only trading days
971
+ future_df = pd.DataFrame({"ds": trading_days})
972
+ return future_df
973
+
974
+
975
  def test_server_availability():
976
  """Test if the MCP servers are available and can be executed."""
977