diff --git a/tradingagents/dashboards/momentum/__init__.py b/tradingagents/dashboards/momentum/__init__.py index 38018d46..b341c742 100644 --- a/tradingagents/dashboards/momentum/__init__.py +++ b/tradingagents/dashboards/momentum/__init__.py @@ -13,6 +13,7 @@ import pandas as pd import numpy as np from datetime import datetime, timedelta from typing import List, Dict, Optional, Tuple +from concurrent.futures import ThreadPoolExecutor, as_completed # Magnificent Seven stocks MAGNIFICENT_SEVEN = ["AAPL", "MSFT", "GOOGL", "AMZN", "NVDA", "META", "TSLA"] @@ -57,8 +58,12 @@ class MomentumIndicator: delta = data.diff() gain = (delta.where(delta > 0, 0)).rolling(window=period).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean() + # Handle division by zero and NaN values + loss = loss.replace(0, np.nan) rs = gain / loss - return 100 - (100 / (1 + rs)) + # When loss is 0 (no downtrends), RSI = 100 + rsi = 100 - (100 / (1 + rs)) + return rsi.fillna(100 if loss.isna().any() else 50) class MomentumScanner: @@ -156,11 +161,13 @@ class MomentumScanner: return "HOLD" def scan_all(self) -> List[Dict]: - """Scan all symbols and return results""" + """Scan all symbols and return results (parallelized)""" results = [] - for symbol in self.symbols: - result = self.analyze_symbol(symbol) - results.append(result) + with ThreadPoolExecutor(max_workers=min(len(self.symbols), 8)) as executor: + future_to_symbol = {executor.submit(self.analyze_symbol, symbol): symbol + for symbol in self.symbols} + for future in as_completed(future_to_symbol): + results.append(future.result()) return results diff --git a/tradingagents/dashboards/momentum/app.py b/tradingagents/dashboards/momentum/app.py index 733d50f6..6d05c850 100644 --- a/tradingagents/dashboards/momentum/app.py +++ b/tradingagents/dashboards/momentum/app.py @@ -11,11 +11,12 @@ from plotly.subplots import make_subplots from datetime import datetime, timedelta import sys import os +import yfinance as yf -# Add parent directory to path -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +# Add parent directory to path for proper module imports +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) -from __init__ import MomentumScanner, MomentumIndicator, MAGNIFICENT_SEVEN, get_top_momentum_stocks +from tradingagents.dashboards.momentum import MomentumScanner, MomentumIndicator, MAGNIFICENT_SEVEN, get_top_momentum_stocks # Page config @@ -151,7 +152,6 @@ def main(): if selected_symbol: with st.spinner(f"Loading {selected_symbol} chart..."): # Fetch data for chart - import yfinance as yf ticker = yf.Ticker(selected_symbol) hist = ticker.history(period="3mo", interval=timeframe)