fix: address Gemini review comments

- Fix RSI NaN handling for edge cases (flat prices, only gains/losses)
- Refactor imports to follow PEP 8 ordering (stdlib → third-party → local)
- Add explicit handling for all RSI edge cases with proper values

Co-authored-by: AI Assistant <assistant@openclaw.ai>
This commit is contained in:
阳虎 2026-03-18 20:08:16 +08:00
parent 78ad76876d
commit 0b7619b501
2 changed files with 37 additions and 20 deletions

View File

@ -58,18 +58,32 @@ class MomentumIndicator:
delta = data.diff() delta = data.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean() gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
loss = (-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) # Initialize RSI series
rsi = pd.Series(index=data.index, dtype=float)
# When both gain and loss are zero (no price change), return neutral RSI of 50
# Otherwise compute RS and RSI for i in range(len(data)):
rs = gain / loss g = gain.iloc[i]
rsi = 100 - (100 / (1 + rs)) l = loss.iloc[i]
# Fill NaN values: # Handle special cases
# - When loss was NaN (no downtrends), RSI should be 100 if pd.isna(g) or pd.isna(l):
# - When gain and loss were both 0 (no price change), RSI should be 50 rsi.iloc[i] = np.nan
return rsi.fillna(100 if loss.isna().any() else 50) 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: class MomentumScanner:

View File

@ -4,19 +4,22 @@ Momentum Dashboard - Streamlit Web UI
Run: streamlit run app.py 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 pandas as pd
import plotly.graph_objects as go import plotly.graph_objects as go
from plotly.subplots import make_subplots import streamlit as st
from datetime import datetime, timedelta
import sys
import os
import yfinance as yf 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__))))) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from tradingagents.dashboards.momentum import (MAGNIFICENT_SEVEN, MomentumIndicator,
from tradingagents.dashboards.momentum import MomentumScanner, MomentumIndicator, MAGNIFICENT_SEVEN, get_top_momentum_stocks MomentumScanner, get_top_momentum_stocks)
# Page config # Page config