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()
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:

View File

@ -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