diff --git a/tradingagents/dashboards/momentum/__init__.py b/tradingagents/dashboards/momentum/__init__.py index ce4acfbb..de4d015e 100644 --- a/tradingagents/dashboards/momentum/__init__.py +++ b/tradingagents/dashboards/momentum/__init__.py @@ -58,18 +58,32 @@ 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) - - # When both gain and loss are zero (no price change), return neutral RSI of 50 - # Otherwise compute RS and RSI - rs = gain / loss - rsi = 100 - (100 / (1 + rs)) - - # Fill NaN values: - # - When loss was NaN (no downtrends), RSI should be 100 - # - When gain and loss were both 0 (no price change), RSI should be 50 - return rsi.fillna(100 if loss.isna().any() else 50) + + # Initialize RSI series + rsi = pd.Series(index=data.index, dtype=float) + + for i in range(len(data)): + g = gain.iloc[i] + l = loss.iloc[i] + + # Handle special cases + if pd.isna(g) or pd.isna(l): + rsi.iloc[i] = np.nan + elif l == 0 and g == 0: + # No price movement - neutral RSI + rsi.iloc[i] = 50.0 + elif l == 0: + # Only gains - maximum strength + rsi.iloc[i] = 100.0 + elif g == 0: + # Only losses - minimum strength + rsi.iloc[i] = 0.0 + else: + # Normal RSI calculation + rs = g / l + rsi.iloc[i] = 100 - (100 / (1 + rs)) + + return rsi class MomentumScanner: diff --git a/tradingagents/dashboards/momentum/app.py b/tradingagents/dashboards/momentum/app.py index 6d05c850..1807cdc7 100644 --- a/tradingagents/dashboards/momentum/app.py +++ b/tradingagents/dashboards/momentum/app.py @@ -4,19 +4,22 @@ Momentum Dashboard - Streamlit Web UI Run: streamlit run app.py """ -import streamlit as st +# Standard library imports +import os +import sys +from datetime import datetime, timedelta + +# Third-party imports import pandas as pd import plotly.graph_objects as go -from plotly.subplots import make_subplots -from datetime import datetime, timedelta -import sys -import os +import streamlit as st import yfinance as yf +from plotly.subplots import make_subplots -# Add parent directory to path for proper module imports +# Local imports (add path first for module resolution) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) - -from tradingagents.dashboards.momentum import MomentumScanner, MomentumIndicator, MAGNIFICENT_SEVEN, get_top_momentum_stocks +from tradingagents.dashboards.momentum import (MAGNIFICENT_SEVEN, MomentumIndicator, + MomentumScanner, get_top_momentum_stocks) # Page config