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:
parent
78ad76876d
commit
0b7619b501
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue